diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/kerneldevice/mm-kernel-device-generic.c | 309 | ||||
-rw-r--r-- | src/kerneldevice/mm-kernel-device-generic.h | 51 | ||||
-rw-r--r-- | src/mm-base-modem.c | 36 | ||||
-rw-r--r-- | src/mm-base-modem.h | 13 | ||||
-rw-r--r-- | src/mm-plugin.c | 48 | ||||
-rw-r--r-- | src/mm-port.c | 44 | ||||
-rw-r--r-- | src/mm-port.h | 24 | ||||
-rw-r--r-- | src/tests/Makefile.am | 1 |
9 files changed, 458 insertions, 73 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 48c7d26d..b1f1a401 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -105,6 +105,8 @@ noinst_LTLIBRARIES += libkerneldevice.la libkerneldevice_la_SOURCES = \ kerneldevice/mm-kernel-device.h \ kerneldevice/mm-kernel-device.c \ + kerneldevice/mm-kernel-device-generic.h \ + kerneldevice/mm-kernel-device-generic.c \ kerneldevice/mm-kernel-device-udev.h \ kerneldevice/mm-kernel-device-udev.c \ $(NULL) @@ -173,6 +175,7 @@ libport_la_LIBADD = \ $(top_builddir)/libqcdm/src/libqcdm.la \ $(top_builddir)/libmm-glib/libmm-glib.la \ $(builddir)/libhelpers.la \ + $(builddir)/libkerneldevice.la \ $(NULL) # Request to build enum types before anything else @@ -220,9 +223,7 @@ ModemManager_LDADD = \ $(top_builddir)/libqcdm/src/libqcdm.la \ $(top_builddir)/libmm-glib/libmm-glib.la \ $(top_builddir)/libmm-glib/generated/tests/libmm-test-generated.la \ - $(builddir)/libhelpers.la \ $(builddir)/libport.la \ - $(builddir)/libkerneldevice.la \ $(NULL) ModemManager_SOURCES = \ diff --git a/src/kerneldevice/mm-kernel-device-generic.c b/src/kerneldevice/mm-kernel-device-generic.c new file mode 100644 index 00000000..a6dbc2d7 --- /dev/null +++ b/src/kerneldevice/mm-kernel-device-generic.c @@ -0,0 +1,309 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2016 Velocloud, Inc. + */ + +#define _GNU_SOURCE +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-kernel-device-generic.h" +#include "mm-log.h" + +static void initable_iface_init (GInitableIface *iface); + +G_DEFINE_TYPE_EXTENDED (MMKernelDeviceGeneric, mm_kernel_device_generic, MM_TYPE_KERNEL_DEVICE, 0, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, initable_iface_init)) + +enum { + PROP_0, + PROP_PROPERTIES, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +struct _MMKernelDeviceGenericPrivate { + /* Input properties */ + MMKernelEventProperties *properties; +}; + +/*****************************************************************************/ + +static const gchar * +kernel_device_get_subsystem (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return mm_kernel_event_properties_get_subsystem (MM_KERNEL_DEVICE_GENERIC (self)->priv->properties); +} + +static const gchar * +kernel_device_get_name (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return mm_kernel_event_properties_get_name (MM_KERNEL_DEVICE_GENERIC (self)->priv->properties); +} + +static const gchar * +kernel_device_get_sysfs_path (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return NULL; +} + +static const gchar * +kernel_device_get_parent_sysfs_path (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return NULL; +} + +static const gchar * +kernel_device_get_physdev_uid (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + /* Prefer the one coming in the properties, if any */ + return mm_kernel_event_properties_get_uid (MM_KERNEL_DEVICE_GENERIC (self)->priv->properties); +} + +static const gchar * +kernel_device_get_driver (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return NULL; +} + +static guint16 +kernel_device_get_physdev_vid (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), 0); + + return 0; +} + +static guint16 +kernel_device_get_physdev_pid (MMKernelDevice *self) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), 0); + + return 0; +} + +static gboolean +kernel_device_is_candidate (MMKernelDevice *_self, + gboolean manual_scan) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (_self), FALSE); + + return TRUE; +} + +static gboolean +kernel_device_cmp (MMKernelDevice *a, + MMKernelDevice *b) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (a), FALSE); + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (b), FALSE); + + return (!g_strcmp0 (mm_kernel_device_get_subsystem (a), mm_kernel_device_get_subsystem (b)) && + !g_strcmp0 (mm_kernel_device_get_name (a), mm_kernel_device_get_name (b))); +} + +static gboolean +kernel_device_has_property (MMKernelDevice *self, + const gchar *property) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), FALSE); + + return FALSE; +} + +static const gchar * +kernel_device_get_property (MMKernelDevice *self, + const gchar *property) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), NULL); + + return NULL; +} + +static gboolean +kernel_device_get_property_as_boolean (MMKernelDevice *self, + const gchar *property) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), FALSE); + + return FALSE; +} + +static gint +kernel_device_get_property_as_int (MMKernelDevice *self, + const gchar *property) +{ + g_return_val_if_fail (MM_IS_KERNEL_DEVICE_GENERIC (self), -1); + + return 0; +} + +/*****************************************************************************/ + +MMKernelDevice * +mm_kernel_device_generic_new (MMKernelEventProperties *properties, + GError **error) +{ + g_return_val_if_fail (MM_IS_KERNEL_EVENT_PROPERTIES (properties), NULL); + + return MM_KERNEL_DEVICE (g_initable_new (MM_TYPE_KERNEL_DEVICE_GENERIC, + NULL, + error, + "properties", properties, + NULL)); +} + +/*****************************************************************************/ + +static void +mm_kernel_device_generic_init (MMKernelDeviceGeneric *self) +{ + /* Initialize private data */ + self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, MM_TYPE_KERNEL_DEVICE_GENERIC, MMKernelDeviceGenericPrivate); +} + +static void +set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + MMKernelDeviceGeneric *self = MM_KERNEL_DEVICE_GENERIC (object); + + switch (prop_id) { + case PROP_PROPERTIES: + g_assert (!self->priv->properties); + self->priv->properties = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + MMKernelDeviceGeneric *self = MM_KERNEL_DEVICE_GENERIC (object); + + switch (prop_id) { + case PROP_PROPERTIES: + g_value_set_object (value, self->priv->properties); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static gboolean +initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MMKernelDeviceGeneric *self = MM_KERNEL_DEVICE_GENERIC (initable); + const gchar *subsystem; + + subsystem = mm_kernel_device_get_subsystem (MM_KERNEL_DEVICE (self)); + if (!subsystem) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "subsystem is mandatory in kernel device"); + return FALSE; + } + + if (!g_str_equal (subsystem, "virtual")) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "only virtual subsystem supported"); + return FALSE; + } + + if (!mm_kernel_device_get_name (MM_KERNEL_DEVICE (self))) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_INVALID_ARGS, + "name is mandatory in kernel device"); + return FALSE; + } + + return TRUE; +} + +static void +dispose (GObject *object) +{ + MMKernelDeviceGeneric *self = MM_KERNEL_DEVICE_GENERIC (object); + + g_clear_object (&self->priv->properties); + + G_OBJECT_CLASS (mm_kernel_device_generic_parent_class)->dispose (object); +} + +static void +initable_iface_init (GInitableIface *iface) +{ + iface->init = initable_init; +} + +static void +mm_kernel_device_generic_class_init (MMKernelDeviceGenericClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + MMKernelDeviceClass *kernel_device_class = MM_KERNEL_DEVICE_CLASS (klass); + + g_type_class_add_private (object_class, sizeof (MMKernelDeviceGenericPrivate)); + + object_class->dispose = dispose; + object_class->get_property = get_property; + object_class->set_property = set_property; + + kernel_device_class->get_subsystem = kernel_device_get_subsystem; + kernel_device_class->get_name = kernel_device_get_name; + kernel_device_class->get_driver = kernel_device_get_driver; + kernel_device_class->get_sysfs_path = kernel_device_get_sysfs_path; + kernel_device_class->get_physdev_uid = kernel_device_get_physdev_uid; + kernel_device_class->get_physdev_vid = kernel_device_get_physdev_vid; + kernel_device_class->get_physdev_pid = kernel_device_get_physdev_pid; + kernel_device_class->get_parent_sysfs_path = kernel_device_get_parent_sysfs_path; + kernel_device_class->is_candidate = kernel_device_is_candidate; + kernel_device_class->cmp = kernel_device_cmp; + kernel_device_class->has_property = kernel_device_has_property; + kernel_device_class->get_property = kernel_device_get_property; + kernel_device_class->get_property_as_boolean = kernel_device_get_property_as_boolean; + kernel_device_class->get_property_as_int = kernel_device_get_property_as_int; + + properties[PROP_PROPERTIES] = + g_param_spec_object ("properties", + "Properties", + "Generic kernel event properties", + MM_TYPE_KERNEL_EVENT_PROPERTIES, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_PROPERTIES, properties[PROP_PROPERTIES]); +} diff --git a/src/kerneldevice/mm-kernel-device-generic.h b/src/kerneldevice/mm-kernel-device-generic.h new file mode 100644 index 00000000..87f99941 --- /dev/null +++ b/src/kerneldevice/mm-kernel-device-generic.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details: + * + * Copyright (C) 2016 Velocloud, Inc. + */ + +#ifndef MM_KERNEL_DEVICE_GENERIC_H +#define MM_KERNEL_DEVICE_GENERIC_H + +#include <glib.h> +#include <glib-object.h> + +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-kernel-device.h" + +#define MM_TYPE_KERNEL_DEVICE_GENERIC (mm_kernel_device_generic_get_type ()) +#define MM_KERNEL_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), MM_TYPE_KERNEL_DEVICE_GENERIC, MMKernelDeviceGeneric)) +#define MM_KERNEL_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MM_TYPE_KERNEL_DEVICE_GENERIC, MMKernelDeviceGenericClass)) +#define MM_IS_KERNEL_DEVICE_GENERIC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MM_TYPE_KERNEL_DEVICE_GENERIC)) +#define MM_IS_KERNEL_DEVICE_GENERIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_KERNEL_DEVICE_GENERIC)) +#define MM_KERNEL_DEVICE_GENERIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_KERNEL_DEVICE_GENERIC, MMKernelDeviceGenericClass)) + +typedef struct _MMKernelDeviceGeneric MMKernelDeviceGeneric; +typedef struct _MMKernelDeviceGenericClass MMKernelDeviceGenericClass; +typedef struct _MMKernelDeviceGenericPrivate MMKernelDeviceGenericPrivate; + +struct _MMKernelDeviceGeneric { + MMKernelDevice parent; + MMKernelDeviceGenericPrivate *priv; +}; + +struct _MMKernelDeviceGenericClass { + MMKernelDeviceClass parent; +}; + +GType mm_kernel_device_generic_get_type (void); +MMKernelDevice *mm_kernel_device_generic_new (MMKernelEventProperties *properties, + GError **error); + +#endif /* MM_KERNEL_DEVICE_GENERIC_H */ diff --git a/src/mm-base-modem.c b/src/mm-base-modem.c index 2dc00ce7..50717471 100644 --- a/src/mm-base-modem.c +++ b/src/mm-base-modem.c @@ -21,7 +21,6 @@ #include <stdlib.h> #include <unistd.h> #include <string.h> -#include <gudev/gudev.h> #include <ModemManager.h> #include <mm-errors-types.h> @@ -129,18 +128,23 @@ serial_port_timed_out_cb (MMPortSerial *port, } gboolean -mm_base_modem_grab_port (MMBaseModem *self, - const gchar *subsys, - const gchar *name, - const gchar *parent_path, - MMPortType ptype, - MMPortSerialAtFlag at_pflags, - GError **error) +mm_base_modem_grab_port (MMBaseModem *self, + MMKernelDevice *kernel_device, + MMPortType ptype, + MMPortSerialAtFlag at_pflags, + GError **error) { - MMPort *port; - gchar *key; + MMPort *port; + gchar *key; + const gchar *subsys; + const gchar *name; g_return_val_if_fail (MM_IS_BASE_MODEM (self), FALSE); + g_return_val_if_fail (MM_IS_KERNEL_DEVICE (kernel_device), FALSE); + + subsys = mm_kernel_device_get_subsystem (kernel_device); + name = mm_kernel_device_get_name (kernel_device); + g_return_val_if_fail (subsys != NULL, FALSE); g_return_val_if_fail (name != NULL, FALSE); @@ -285,9 +289,9 @@ mm_base_modem_grab_port (MMBaseModem *self, * Note: 'key' and 'port' now owned by the HT. */ g_hash_table_insert (self->priv->ports, key, port); - /* Store parent path */ + /* Store kernel device */ g_object_set (port, - MM_PORT_PARENT_PATH, parent_path, + MM_PORT_KERNEL_DEVICE, kernel_device, NULL); return TRUE; @@ -555,7 +559,7 @@ mm_base_modem_peek_port_qmi_for_data (MMBaseModem *self, const gchar *net_port_parent_path; g_warn_if_fail (mm_port_get_subsys (data) == MM_PORT_SUBSYS_NET); - net_port_parent_path = mm_port_get_parent_path (data); + net_port_parent_path = mm_kernel_device_get_parent_sysfs_path (mm_port_peek_kernel_device (data)); if (!net_port_parent_path) { g_set_error (error, MM_CORE_ERROR, @@ -574,7 +578,7 @@ mm_base_modem_peek_port_qmi_for_data (MMBaseModem *self, const gchar *wdm_port_parent_path; g_assert (MM_IS_PORT_QMI (l->data)); - wdm_port_parent_path = mm_port_get_parent_path (MM_PORT (l->data)); + wdm_port_parent_path = mm_kernel_device_get_parent_sysfs_path (mm_port_peek_kernel_device (MM_PORT (l->data))); if (wdm_port_parent_path && g_str_equal (wdm_port_parent_path, net_port_parent_path)) return MM_PORT_QMI (l->data); } @@ -629,7 +633,7 @@ mm_base_modem_peek_port_mbim_for_data (MMBaseModem *self, const gchar *net_port_parent_path; g_warn_if_fail (mm_port_get_subsys (data) == MM_PORT_SUBSYS_NET); - net_port_parent_path = mm_port_get_parent_path (data); + net_port_parent_path = mm_kernel_device_get_parent_sysfs_path (mm_port_peek_kernel_device (data)); if (!net_port_parent_path) { g_set_error (error, MM_CORE_ERROR, @@ -648,7 +652,7 @@ mm_base_modem_peek_port_mbim_for_data (MMBaseModem *self, const gchar *wdm_port_parent_path; g_assert (MM_IS_PORT_MBIM (l->data)); - wdm_port_parent_path = mm_port_get_parent_path (MM_PORT (l->data)); + wdm_port_parent_path = mm_kernel_device_get_parent_sysfs_path (mm_port_peek_kernel_device (MM_PORT (l->data))); if (wdm_port_parent_path && g_str_equal (wdm_port_parent_path, net_port_parent_path)) return MM_PORT_MBIM (l->data); } diff --git a/src/mm-base-modem.h b/src/mm-base-modem.h index 71445ede..db3d54d3 100644 --- a/src/mm-base-modem.h +++ b/src/mm-base-modem.h @@ -30,6 +30,7 @@ #include "mm-auth.h" #include "mm-port.h" +#include "mm-kernel-device.h" #include "mm-port-serial-at.h" #include "mm-port-serial-qcdm.h" #include "mm-port-serial-gps.h" @@ -104,13 +105,11 @@ struct _MMBaseModemClass { GType mm_base_modem_get_type (void); -gboolean mm_base_modem_grab_port (MMBaseModem *self, - const gchar *subsys, - const gchar *name, - const gchar *parent_path, - MMPortType ptype, - MMPortSerialAtFlag at_pflags, - GError **error); +gboolean mm_base_modem_grab_port (MMBaseModem *self, + MMKernelDevice *kernel_device, + MMPortType ptype, + MMPortSerialAtFlag at_pflags, + GError **error); gboolean mm_base_modem_has_at_port (MMBaseModem *self); diff --git a/src/mm-plugin.c b/src/mm-plugin.c index bd5d313b..8ebdbd17 100644 --- a/src/mm-plugin.c +++ b/src/mm-plugin.c @@ -29,6 +29,7 @@ #include "mm-plugin.h" #include "mm-device.h" #include "mm-kernel-device.h" +#include "mm-kernel-device-generic.h" #include "mm-port-serial-at.h" #include "mm-port-serial-qcdm.h" #include "mm-serial-parsers.h" @@ -902,9 +903,7 @@ mm_plugin_create_modem (MMPlugin *self, mm_port_probe_get_port_subsys (probe), mm_port_probe_get_port_name (probe)); grabbed = mm_base_modem_grab_port (modem, - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe), - mm_port_probe_get_parent_path (probe), + mm_port_probe_peek_port (probe), MM_PORT_TYPE_IGNORED, MM_PORT_SERIAL_AT_FLAG_NONE, &inner_error); @@ -914,9 +913,7 @@ mm_plugin_create_modem (MMPlugin *self, !g_strcmp0 (mm_kernel_device_get_driver (mm_port_probe_peek_port (probe)), "qmi_wwan")) { /* Try to generically grab the port, but flagged as ignored */ grabbed = mm_base_modem_grab_port (modem, - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe), - mm_port_probe_get_parent_path (probe), + mm_port_probe_peek_port (probe), MM_PORT_TYPE_IGNORED, MM_PORT_SERIAL_AT_FLAG_NONE, &inner_error); @@ -927,9 +924,7 @@ mm_plugin_create_modem (MMPlugin *self, !g_strcmp0 (mm_kernel_device_get_driver (mm_port_probe_peek_port (probe)), "cdc_mbim")) { /* Try to generically grab the port, but flagged as ignored */ grabbed = mm_base_modem_grab_port (modem, - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe), - mm_port_probe_get_parent_path (probe), + mm_port_probe_peek_port (probe), MM_PORT_TYPE_IGNORED, MM_PORT_SERIAL_AT_FLAG_NONE, &inner_error); @@ -942,9 +937,7 @@ mm_plugin_create_modem (MMPlugin *self, &inner_error); else grabbed = mm_base_modem_grab_port (modem, - mm_port_probe_get_port_subsys (probe), - mm_port_probe_get_port_name (probe), - mm_port_probe_get_parent_path (probe), + mm_port_probe_peek_port (probe), mm_port_probe_get_port_type (probe), MM_PORT_SERIAL_AT_FLAG_NONE, &inner_error); @@ -960,20 +953,35 @@ mm_plugin_create_modem (MMPlugin *self, guint i; for (i = 0; virtual_ports[i]; i++) { - GError *inner_error = NULL; + GError *inner_error = NULL; + MMKernelDevice *kernel_device; + MMKernelEventProperties *properties; + + properties = mm_kernel_event_properties_new (); + mm_kernel_event_properties_set_action (properties, "add"); + mm_kernel_event_properties_set_subsystem (properties, "virtual"); + mm_kernel_event_properties_set_name (properties, virtual_ports[i]); - if (!mm_base_modem_grab_port (modem, - "virtual", - virtual_ports[i], - NULL, - MM_PORT_TYPE_AT, - MM_PORT_SERIAL_AT_FLAG_NONE, - &inner_error)) { + kernel_device = mm_kernel_device_generic_new (properties, &inner_error); + if (!kernel_device) { + mm_warn ("Could not grab port (virtual/%s): '%s'", + virtual_ports[i], + inner_error ? inner_error->message : "unknown error"); + g_clear_error (&inner_error); + } else if (!mm_base_modem_grab_port (modem, + kernel_device, + MM_PORT_TYPE_AT, + MM_PORT_SERIAL_AT_FLAG_NONE, + &inner_error)) { mm_warn ("Could not grab port (virtual/%s): '%s'", virtual_ports[i], inner_error ? inner_error->message : "unknown error"); g_clear_error (&inner_error); } + + if (kernel_device) + g_object_unref (kernel_device); + g_object_unref (properties); } } diff --git a/src/mm-port.c b/src/mm-port.c index 0ee9a199..0156f6e7 100644 --- a/src/mm-port.c +++ b/src/mm-port.c @@ -29,8 +29,7 @@ enum { PROP_SUBSYS, PROP_TYPE, PROP_CONNECTED, - PROP_PARENT_PATH, - + PROP_KERNEL_DEVICE, LAST_PROP }; @@ -39,7 +38,7 @@ struct _MMPortPrivate { MMPortSubsys subsys; MMPortType ptype; gboolean connected; - gchar *parent_path; + MMKernelDevice *kernel_device; }; /*****************************************************************************/ @@ -96,12 +95,12 @@ mm_port_set_connected (MMPort *self, gboolean connected) } } -const gchar * -mm_port_get_parent_path (MMPort *self) +MMKernelDevice * +mm_port_peek_kernel_device (MMPort *self) { g_return_val_if_fail (MM_IS_PORT (self), NULL); - return self->priv->parent_path; + return self->priv->kernel_device; } /*****************************************************************************/ @@ -136,9 +135,10 @@ set_property (GObject *object, case PROP_CONNECTED: self->priv->connected = g_value_get_boolean (value); break; - case PROP_PARENT_PATH: - g_free (self->priv->parent_path); - self->priv->parent_path = g_value_dup_string (value); + case PROP_KERNEL_DEVICE: + /* Not construct only, but only set once */ + g_assert (!self->priv->kernel_device); + self->priv->kernel_device = g_value_dup_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -165,8 +165,8 @@ get_property (GObject *object, guint prop_id, case PROP_CONNECTED: g_value_set_boolean (value, self->priv->connected); break; - case PROP_PARENT_PATH: - g_value_set_string (value, self->priv->parent_path); + case PROP_KERNEL_DEVICE: + g_value_set_object (value, self->priv->kernel_device); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -180,12 +180,21 @@ finalize (GObject *object) MMPort *self = MM_PORT (object); g_free (self->priv->device); - g_free (self->priv->parent_path); G_OBJECT_CLASS (mm_port_parent_class)->finalize (object); } static void +dispose (GObject *object) +{ + MMPort *self = MM_PORT (object); + + g_clear_object (&self->priv->kernel_device); + + G_OBJECT_CLASS (mm_port_parent_class)->dispose (object); +} + +static void mm_port_class_init (MMPortClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); @@ -196,6 +205,7 @@ mm_port_class_init (MMPortClass *klass) object_class->set_property = set_property; object_class->get_property = get_property; object_class->finalize = finalize; + object_class->dispose = dispose; g_object_class_install_property (object_class, PROP_DEVICE, @@ -234,10 +244,10 @@ mm_port_class_init (MMPortClass *klass) G_PARAM_READWRITE)); g_object_class_install_property - (object_class, PROP_PARENT_PATH, - g_param_spec_string (MM_PORT_PARENT_PATH, - "Parent path", - "sysfs path of the parent device", - NULL, + (object_class, PROP_KERNEL_DEVICE, + g_param_spec_object (MM_PORT_KERNEL_DEVICE, + "Kernel device", + "kernel device object", + MM_TYPE_KERNEL_DEVICE, G_PARAM_READWRITE)); } diff --git a/src/mm-port.h b/src/mm-port.h index 8ac6829a..80463294 100644 --- a/src/mm-port.h +++ b/src/mm-port.h @@ -20,6 +20,8 @@ #include <glib.h> #include <glib-object.h> +#include "mm-kernel-device.h" + typedef enum { /*< underscore_name=mm_port_subsys >*/ MM_PORT_SUBSYS_UNKNOWN = 0x0, MM_PORT_SUBSYS_TTY, @@ -49,11 +51,11 @@ typedef enum { /*< underscore_name=mm_port_type >*/ #define MM_IS_PORT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MM_TYPE_PORT)) #define MM_PORT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), MM_TYPE_PORT, MMPortClass)) -#define MM_PORT_DEVICE "device" -#define MM_PORT_SUBSYS "subsys" -#define MM_PORT_TYPE "type" -#define MM_PORT_CONNECTED "connected" -#define MM_PORT_PARENT_PATH "parent-path" +#define MM_PORT_DEVICE "device" +#define MM_PORT_SUBSYS "subsys" +#define MM_PORT_TYPE "type" +#define MM_PORT_CONNECTED "connected" +#define MM_PORT_KERNEL_DEVICE "kernel-device" typedef struct _MMPort MMPort; typedef struct _MMPortClass MMPortClass; @@ -70,11 +72,11 @@ struct _MMPortClass { GType mm_port_get_type (void); -const gchar *mm_port_get_device (MMPort *self); -MMPortSubsys mm_port_get_subsys (MMPort *self); -MMPortType mm_port_get_port_type (MMPort *self); -const gchar *mm_port_get_parent_path (MMPort *self); -gboolean mm_port_get_connected (MMPort *self); -void mm_port_set_connected (MMPort *self, gboolean connected); +const gchar *mm_port_get_device (MMPort *self); +MMPortSubsys mm_port_get_subsys (MMPort *self); +MMPortType mm_port_get_port_type (MMPort *self); +gboolean mm_port_get_connected (MMPort *self); +void mm_port_set_connected (MMPort *self, gboolean connected); +MMKernelDevice *mm_port_peek_kernel_device (MMPort *self); #endif /* MM_PORT_H */ diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 53b17456..97adac6a 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -16,6 +16,7 @@ AM_CFLAGS = \ -I${top_builddir}/libmm-glib/generated \ -I${top_srcdir}/src/ \ -I${top_builddir}/src/ \ + -I${top_srcdir}/src/kerneldevice \ $(NULL) AM_LDFLAGS = \ |