diff options
-rw-r--r-- | src/mm-device.c | 146 | ||||
-rw-r--r-- | src/mm-device.h | 11 |
2 files changed, 136 insertions, 21 deletions
diff --git a/src/mm-device.c b/src/mm-device.c index a1b351ca..d2ca4de4 100644 --- a/src/mm-device.c +++ b/src/mm-device.c @@ -31,10 +31,12 @@ G_DEFINE_TYPE (MMDevice, mm_device, G_TYPE_OBJECT); enum { PROP_0, + PROP_PATH, PROP_UDEV_DEVICE, PROP_PLUGIN, PROP_MODEM, PROP_HOTPLUGGED, + PROP_VIRTUAL, PROP_LAST }; @@ -48,9 +50,14 @@ static GParamSpec *properties[PROP_LAST]; static guint signals[SIGNAL_LAST]; struct _MMDevicePrivate { + /* Whether the device is real or virtual */ + gboolean virtual; + + /* Device path */ + gchar *path; + /* Parent UDev device */ GUdevDevice *udev_device; - gchar *udev_device_path; guint16 vendor; guint16 product; @@ -72,6 +79,9 @@ struct _MMDevicePrivate { /* Whether the device was hot-plugged. */ gboolean hotplugged; + + /* Virtual ports */ + gchar **virtual_ports; }; /*****************************************************************************/ @@ -296,7 +306,7 @@ mm_device_grab_port (MMDevice *self, &self->priv->vendor, &self->priv->product)) { mm_dbg ("(%s) could not get vendor/product ID", - self->priv->udev_device_path); + self->priv->path); } } @@ -413,7 +423,9 @@ export_modem (MMDevice *self) G_DBUS_OBJECT_SKELETON (self->priv->modem)); mm_dbg ("Exported modem '%s' at path '%s'", - g_udev_device_get_sysfs_path (self->priv->udev_device), + (self->priv->virtual ? + self->priv->path : + g_udev_device_get_sysfs_path (self->priv->udev_device)), path); /* Once connected, dump additional debug info about the modem */ @@ -422,7 +434,9 @@ export_modem (MMDevice *self) mm_base_modem_get_plugin (self->priv->modem), (mm_base_modem_get_vendor_id (self->priv->modem) & 0xFFFF), (mm_base_modem_get_product_id (self->priv->modem) & 0xFFFF), - g_udev_device_get_subsystem (self->priv->udev_device)); + (self->priv->virtual ? + "virtual" : + g_udev_device_get_subsystem (self->priv->udev_device))); g_free (path); } @@ -474,17 +488,31 @@ mm_device_create_modem (MMDevice *self, g_assert (self->priv->modem == NULL); g_assert (self->priv->object_manager == NULL); - if (!self->priv->port_probes) { - g_set_error (error, - MM_CORE_ERROR, - MM_CORE_ERROR_FAILED, - "Not creating a device without ports"); - return FALSE; - } + if (!self->priv->virtual) { + if (!self->priv->port_probes) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Not creating a device without ports"); + return FALSE; + } - mm_info ("Creating modem with plugin '%s' and '%u' ports", - mm_plugin_get_name (self->priv->plugin), - g_list_length (self->priv->port_probes)); + mm_info ("Creating modem with plugin '%s' and '%u' ports", + mm_plugin_get_name (self->priv->plugin), + g_list_length (self->priv->port_probes)); + } else { + if (!self->priv->virtual_ports) { + g_set_error (error, + MM_CORE_ERROR, + MM_CORE_ERROR_FAILED, + "Not creating a virtual device without ports"); + return FALSE; + } + + mm_info ("Creating virtual modem with plugin '%s' and '%u' ports", + mm_plugin_get_name (self->priv->plugin), + g_strv_length (self->priv->virtual_ports)); + } self->priv->modem = mm_plugin_create_modem (self->priv->plugin, self, error); if (self->priv->modem) { @@ -506,7 +534,7 @@ mm_device_create_modem (MMDevice *self, const gchar * mm_device_get_path (MMDevice *self) { - return self->priv->udev_device_path; + return self->priv->path; } const gchar ** @@ -530,12 +558,14 @@ mm_device_get_product (MMDevice *self) GUdevDevice * mm_device_peek_udev_device (MMDevice *self) { + g_return_val_if_fail (self->priv->udev_device != NULL, NULL); return self->priv->udev_device; } GUdevDevice * mm_device_get_udev_device (MMDevice *self) { + g_return_val_if_fail (self->priv->udev_device != NULL, NULL); return G_UDEV_DEVICE (g_object_ref (self->priv->udev_device)); } @@ -624,14 +654,62 @@ mm_device_get_hotplugged (MMDevice *self) /*****************************************************************************/ +void +mm_device_virtual_grab_ports (MMDevice *self, + const gchar **ports) +{ + g_return_if_fail (ports != NULL); + g_return_if_fail (self->priv->virtual); + + /* Setup drivers array */ + self->priv->drivers = g_malloc (2 * sizeof (gchar *)); + self->priv->drivers[0] = g_strdup ("virtual"); + self->priv->drivers[1] = NULL; + + /* Keep virtual port names */ + self->priv->virtual_ports = g_strdupv ((gchar **)ports); +} + +const gchar ** +mm_device_virtual_peek_ports (MMDevice *self) +{ + g_return_val_if_fail (self->priv->virtual, NULL); + + return (const gchar **)self->priv->virtual_ports; +} + +gboolean +mm_device_is_virtual (MMDevice *self) +{ + return self->priv->virtual; +} + +/*****************************************************************************/ + MMDevice * mm_device_new (GUdevDevice *udev_device, gboolean hotplugged) { - return MM_DEVICE (g_object_new (MM_TYPE_DEVICE, - MM_DEVICE_UDEV_DEVICE, udev_device, - MM_DEVICE_HOTPLUGGED, hotplugged, - NULL)); + g_return_val_if_fail (udev_device != NULL, NULL); + + return MM_DEVICE (g_object_new (MM_TYPE_DEVICE, + MM_DEVICE_UDEV_DEVICE, udev_device, + MM_DEVICE_PATH, g_udev_device_get_sysfs_path (udev_device), + MM_DEVICE_HOTPLUGGED, hotplugged, + NULL)); +} + +MMDevice * +mm_device_virtual_new (const gchar *path, + gboolean hotplugged) +{ + g_return_val_if_fail (path != NULL, NULL); + + return MM_DEVICE (g_object_new (MM_TYPE_DEVICE, + MM_DEVICE_PATH, path, + MM_DEVICE_HOTPLUGGED, hotplugged, + MM_DEVICE_VIRTUAL, TRUE, + NULL)); } static void @@ -652,10 +730,13 @@ set_property (GObject *object, MMDevice *self = MM_DEVICE (object); switch (prop_id) { + case PROP_PATH: + /* construct only */ + self->priv->path = g_value_dup_string (value); + break; case PROP_UDEV_DEVICE: /* construct only */ self->priv->udev_device = g_value_dup_object (value); - self->priv->udev_device_path = g_strdup (g_udev_device_get_sysfs_path (self->priv->udev_device)); break; case PROP_PLUGIN: g_clear_object (&(self->priv->plugin)); @@ -668,6 +749,9 @@ set_property (GObject *object, case PROP_HOTPLUGGED: self->priv->hotplugged = g_value_get_boolean (value); break; + case PROP_VIRTUAL: + self->priv->virtual = g_value_get_boolean (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -695,6 +779,9 @@ get_property (GObject *object, case PROP_HOTPLUGGED: g_value_set_boolean (value, self->priv->hotplugged); break; + case PROP_VIRTUAL: + g_value_set_boolean (value, self->priv->virtual); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -720,8 +807,9 @@ finalize (GObject *object) { MMDevice *self = MM_DEVICE (object); - g_free (self->priv->udev_device_path); + g_free (self->priv->path); g_strfreev (self->priv->drivers); + g_strfreev (self->priv->virtual_ports); G_OBJECT_CLASS (mm_device_parent_class)->finalize (object); } @@ -739,6 +827,14 @@ mm_device_class_init (MMDeviceClass *klass) object_class->finalize = finalize; object_class->dispose = dispose; + properties[PROP_PATH] = + g_param_spec_string (MM_DEVICE_PATH, + "Path", + "Device path", + NULL, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_PATH, properties[PROP_PATH]); + properties[PROP_UDEV_DEVICE] = g_param_spec_object (MM_DEVICE_UDEV_DEVICE, "UDev Device", @@ -771,6 +867,14 @@ mm_device_class_init (MMDeviceClass *klass) G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); g_object_class_install_property (object_class, PROP_HOTPLUGGED, properties[PROP_HOTPLUGGED]); + properties[PROP_VIRTUAL] = + g_param_spec_boolean (MM_DEVICE_VIRTUAL, + "Virtual", + "Whether the device is virtual or real", + FALSE, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY); + g_object_class_install_property (object_class, PROP_VIRTUAL, properties[PROP_VIRTUAL]); + signals[SIGNAL_PORT_GRABBED] = g_signal_new (MM_DEVICE_PORT_GRABBED, G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/mm-device.h b/src/mm-device.h index fa70d862..2da82223 100644 --- a/src/mm-device.h +++ b/src/mm-device.h @@ -34,10 +34,12 @@ typedef struct _MMDevice MMDevice; typedef struct _MMDeviceClass MMDeviceClass; typedef struct _MMDevicePrivate MMDevicePrivate; +#define MM_DEVICE_PATH "path" #define MM_DEVICE_UDEV_DEVICE "udev-device" #define MM_DEVICE_PLUGIN "plugin" #define MM_DEVICE_MODEM "modem" #define MM_DEVICE_HOTPLUGGED "hotplugged" +#define MM_DEVICE_VIRTUAL "virtual" #define MM_DEVICE_PORT_GRABBED "port-grabbed" #define MM_DEVICE_PORT_RELEASED "port-released" @@ -100,4 +102,13 @@ const gchar *mm_device_utils_get_port_driver (GUdevDevice *udev_port); gboolean mm_device_get_hotplugged (MMDevice *self); + +/* For testing purposes */ +MMDevice *mm_device_virtual_new (const gchar *path, + gboolean hotplugged); +void mm_device_virtual_grab_ports (MMDevice *self, + const gchar **ports); +const gchar **mm_device_virtual_peek_ports (MMDevice *self); +gboolean mm_device_is_virtual (MMDevice *self); + #endif /* MM_DEVICE_H */ |