device: allow creating 'virtual' devices
This commit is contained in:
146
src/mm-device.c
146
src/mm-device.c
@@ -31,10 +31,12 @@ G_DEFINE_TYPE (MMDevice, mm_device, G_TYPE_OBJECT);
|
|||||||
|
|
||||||
enum {
|
enum {
|
||||||
PROP_0,
|
PROP_0,
|
||||||
|
PROP_PATH,
|
||||||
PROP_UDEV_DEVICE,
|
PROP_UDEV_DEVICE,
|
||||||
PROP_PLUGIN,
|
PROP_PLUGIN,
|
||||||
PROP_MODEM,
|
PROP_MODEM,
|
||||||
PROP_HOTPLUGGED,
|
PROP_HOTPLUGGED,
|
||||||
|
PROP_VIRTUAL,
|
||||||
PROP_LAST
|
PROP_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,9 +50,14 @@ static GParamSpec *properties[PROP_LAST];
|
|||||||
static guint signals[SIGNAL_LAST];
|
static guint signals[SIGNAL_LAST];
|
||||||
|
|
||||||
struct _MMDevicePrivate {
|
struct _MMDevicePrivate {
|
||||||
|
/* Whether the device is real or virtual */
|
||||||
|
gboolean virtual;
|
||||||
|
|
||||||
|
/* Device path */
|
||||||
|
gchar *path;
|
||||||
|
|
||||||
/* Parent UDev device */
|
/* Parent UDev device */
|
||||||
GUdevDevice *udev_device;
|
GUdevDevice *udev_device;
|
||||||
gchar *udev_device_path;
|
|
||||||
guint16 vendor;
|
guint16 vendor;
|
||||||
guint16 product;
|
guint16 product;
|
||||||
|
|
||||||
@@ -72,6 +79,9 @@ struct _MMDevicePrivate {
|
|||||||
|
|
||||||
/* Whether the device was hot-plugged. */
|
/* Whether the device was hot-plugged. */
|
||||||
gboolean hotplugged;
|
gboolean hotplugged;
|
||||||
|
|
||||||
|
/* Virtual ports */
|
||||||
|
gchar **virtual_ports;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -296,7 +306,7 @@ mm_device_grab_port (MMDevice *self,
|
|||||||
&self->priv->vendor,
|
&self->priv->vendor,
|
||||||
&self->priv->product)) {
|
&self->priv->product)) {
|
||||||
mm_dbg ("(%s) could not get vendor/product ID",
|
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));
|
G_DBUS_OBJECT_SKELETON (self->priv->modem));
|
||||||
|
|
||||||
mm_dbg ("Exported modem '%s' at path '%s'",
|
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);
|
path);
|
||||||
|
|
||||||
/* Once connected, dump additional debug info about the modem */
|
/* 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_plugin (self->priv->modem),
|
||||||
(mm_base_modem_get_vendor_id (self->priv->modem) & 0xFFFF),
|
(mm_base_modem_get_vendor_id (self->priv->modem) & 0xFFFF),
|
||||||
(mm_base_modem_get_product_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);
|
g_free (path);
|
||||||
}
|
}
|
||||||
@@ -474,17 +488,31 @@ mm_device_create_modem (MMDevice *self,
|
|||||||
g_assert (self->priv->modem == NULL);
|
g_assert (self->priv->modem == NULL);
|
||||||
g_assert (self->priv->object_manager == NULL);
|
g_assert (self->priv->object_manager == NULL);
|
||||||
|
|
||||||
if (!self->priv->port_probes) {
|
if (!self->priv->virtual) {
|
||||||
g_set_error (error,
|
if (!self->priv->port_probes) {
|
||||||
MM_CORE_ERROR,
|
g_set_error (error,
|
||||||
MM_CORE_ERROR_FAILED,
|
MM_CORE_ERROR,
|
||||||
"Not creating a device without ports");
|
MM_CORE_ERROR_FAILED,
|
||||||
return FALSE;
|
"Not creating a device without ports");
|
||||||
}
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
mm_info ("Creating modem with plugin '%s' and '%u' ports",
|
mm_info ("Creating modem with plugin '%s' and '%u' ports",
|
||||||
mm_plugin_get_name (self->priv->plugin),
|
mm_plugin_get_name (self->priv->plugin),
|
||||||
g_list_length (self->priv->port_probes));
|
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);
|
self->priv->modem = mm_plugin_create_modem (self->priv->plugin, self, error);
|
||||||
if (self->priv->modem) {
|
if (self->priv->modem) {
|
||||||
@@ -506,7 +534,7 @@ mm_device_create_modem (MMDevice *self,
|
|||||||
const gchar *
|
const gchar *
|
||||||
mm_device_get_path (MMDevice *self)
|
mm_device_get_path (MMDevice *self)
|
||||||
{
|
{
|
||||||
return self->priv->udev_device_path;
|
return self->priv->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
const gchar **
|
const gchar **
|
||||||
@@ -530,12 +558,14 @@ mm_device_get_product (MMDevice *self)
|
|||||||
GUdevDevice *
|
GUdevDevice *
|
||||||
mm_device_peek_udev_device (MMDevice *self)
|
mm_device_peek_udev_device (MMDevice *self)
|
||||||
{
|
{
|
||||||
|
g_return_val_if_fail (self->priv->udev_device != NULL, NULL);
|
||||||
return self->priv->udev_device;
|
return self->priv->udev_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
GUdevDevice *
|
GUdevDevice *
|
||||||
mm_device_get_udev_device (MMDevice *self)
|
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));
|
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 *
|
MMDevice *
|
||||||
mm_device_new (GUdevDevice *udev_device,
|
mm_device_new (GUdevDevice *udev_device,
|
||||||
gboolean hotplugged)
|
gboolean hotplugged)
|
||||||
{
|
{
|
||||||
return MM_DEVICE (g_object_new (MM_TYPE_DEVICE,
|
g_return_val_if_fail (udev_device != NULL, NULL);
|
||||||
MM_DEVICE_UDEV_DEVICE, udev_device,
|
|
||||||
MM_DEVICE_HOTPLUGGED, hotplugged,
|
return MM_DEVICE (g_object_new (MM_TYPE_DEVICE,
|
||||||
NULL));
|
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
|
static void
|
||||||
@@ -652,10 +730,13 @@ set_property (GObject *object,
|
|||||||
MMDevice *self = MM_DEVICE (object);
|
MMDevice *self = MM_DEVICE (object);
|
||||||
|
|
||||||
switch (prop_id) {
|
switch (prop_id) {
|
||||||
|
case PROP_PATH:
|
||||||
|
/* construct only */
|
||||||
|
self->priv->path = g_value_dup_string (value);
|
||||||
|
break;
|
||||||
case PROP_UDEV_DEVICE:
|
case PROP_UDEV_DEVICE:
|
||||||
/* construct only */
|
/* construct only */
|
||||||
self->priv->udev_device = g_value_dup_object (value);
|
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;
|
break;
|
||||||
case PROP_PLUGIN:
|
case PROP_PLUGIN:
|
||||||
g_clear_object (&(self->priv->plugin));
|
g_clear_object (&(self->priv->plugin));
|
||||||
@@ -668,6 +749,9 @@ set_property (GObject *object,
|
|||||||
case PROP_HOTPLUGGED:
|
case PROP_HOTPLUGGED:
|
||||||
self->priv->hotplugged = g_value_get_boolean (value);
|
self->priv->hotplugged = g_value_get_boolean (value);
|
||||||
break;
|
break;
|
||||||
|
case PROP_VIRTUAL:
|
||||||
|
self->priv->virtual = g_value_get_boolean (value);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -695,6 +779,9 @@ get_property (GObject *object,
|
|||||||
case PROP_HOTPLUGGED:
|
case PROP_HOTPLUGGED:
|
||||||
g_value_set_boolean (value, self->priv->hotplugged);
|
g_value_set_boolean (value, self->priv->hotplugged);
|
||||||
break;
|
break;
|
||||||
|
case PROP_VIRTUAL:
|
||||||
|
g_value_set_boolean (value, self->priv->virtual);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||||
break;
|
break;
|
||||||
@@ -720,8 +807,9 @@ finalize (GObject *object)
|
|||||||
{
|
{
|
||||||
MMDevice *self = MM_DEVICE (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->drivers);
|
||||||
|
g_strfreev (self->priv->virtual_ports);
|
||||||
|
|
||||||
G_OBJECT_CLASS (mm_device_parent_class)->finalize (object);
|
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->finalize = finalize;
|
||||||
object_class->dispose = dispose;
|
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] =
|
properties[PROP_UDEV_DEVICE] =
|
||||||
g_param_spec_object (MM_DEVICE_UDEV_DEVICE,
|
g_param_spec_object (MM_DEVICE_UDEV_DEVICE,
|
||||||
"UDev Device",
|
"UDev Device",
|
||||||
@@ -771,6 +867,14 @@ mm_device_class_init (MMDeviceClass *klass)
|
|||||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
|
||||||
g_object_class_install_property (object_class, PROP_HOTPLUGGED, properties[PROP_HOTPLUGGED]);
|
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] =
|
signals[SIGNAL_PORT_GRABBED] =
|
||||||
g_signal_new (MM_DEVICE_PORT_GRABBED,
|
g_signal_new (MM_DEVICE_PORT_GRABBED,
|
||||||
G_OBJECT_CLASS_TYPE (object_class),
|
G_OBJECT_CLASS_TYPE (object_class),
|
||||||
|
@@ -34,10 +34,12 @@ typedef struct _MMDevice MMDevice;
|
|||||||
typedef struct _MMDeviceClass MMDeviceClass;
|
typedef struct _MMDeviceClass MMDeviceClass;
|
||||||
typedef struct _MMDevicePrivate MMDevicePrivate;
|
typedef struct _MMDevicePrivate MMDevicePrivate;
|
||||||
|
|
||||||
|
#define MM_DEVICE_PATH "path"
|
||||||
#define MM_DEVICE_UDEV_DEVICE "udev-device"
|
#define MM_DEVICE_UDEV_DEVICE "udev-device"
|
||||||
#define MM_DEVICE_PLUGIN "plugin"
|
#define MM_DEVICE_PLUGIN "plugin"
|
||||||
#define MM_DEVICE_MODEM "modem"
|
#define MM_DEVICE_MODEM "modem"
|
||||||
#define MM_DEVICE_HOTPLUGGED "hotplugged"
|
#define MM_DEVICE_HOTPLUGGED "hotplugged"
|
||||||
|
#define MM_DEVICE_VIRTUAL "virtual"
|
||||||
|
|
||||||
#define MM_DEVICE_PORT_GRABBED "port-grabbed"
|
#define MM_DEVICE_PORT_GRABBED "port-grabbed"
|
||||||
#define MM_DEVICE_PORT_RELEASED "port-released"
|
#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);
|
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 */
|
#endif /* MM_DEVICE_H */
|
||||||
|
Reference in New Issue
Block a user