aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2016-03-27 14:41:35 +0200
committerAleksander Morgado <aleksander@aleksander.es>2016-09-29 15:41:21 +0200
commit1f813c4e9691f22017802278ab6f5b1475185113 (patch)
tree8c354cd3053d7837bc575e6f1c793fda0c2ba3e1 /src
parente5fa0233bb73a8374cf35e9170c66c580255815a (diff)
core: allow identifying devices by a user-provided 'uid'
All ports of the same modem reported by the kernel will all be associated with a common 'uid' (unique id), which uniquely identifies the physical device. This logic was already in place, what we do now is avoid calling it the 'sysfs path' of the physical device, because we may not want to use that to identify a device. This logic now also enables the possibility of "naming" the modems in a unique way by setting the "ID_MM_PHYSDEV_UID" property in the "usb_device" that owns all the ports. E.g. a custom device has 4 modems in 4 different USB ports. The device path of each USB device will always be the same, so the naming rules could go like this: $ vim /usr/lib/udev/rules.d/78-mm-naming.rules ACTION!="add|change|move", GOTO="mm_naming_rules_end" DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.1", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-1" DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.2", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-2" DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.3", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-3" DEVPATH=="/devices/pci0000:00/0000:00:1d.0/usb4/4-1/4-1.5/4-1.5.4", ENV{ID_MM_PHYSDEV_UID}="USB-MODEM-4" LABEL="mm_naming_rules_end" Each of the modems found will have a unique UID retrieved from the previous list of rules. Then, "mmcli" has also been updated to allow using the UID instead of the modem DBus path or index, e.g.: $ sudo mmcli -m USB-MODEM-1 /org/freedesktop/ModemManager1/Modem/0 (device id '988d83252c0598f670c2d69d5f41e077204a92fd') ------------------------- Hardware | manufacturer: 'ZTE CORPORATION' | model: 'MF637' | revision: 'BD_W7P673A3F3V1.0.0B04' | supported: 'gsm-umts' | current: 'gsm-umts' | equipment id: '356516027657837' ------------------------- System | device: 'USB-MODEM-1' | drivers: 'option' | plugin: 'ZTE' | primary port: 'ttyUSB5' | ports: 'ttyUSB5 (at)' ... $ sudo mmcli -m USB-MODEM-1 --enable ...
Diffstat (limited to 'src')
-rw-r--r--src/mm-base-manager.c66
-rw-r--r--src/mm-device.c55
-rw-r--r--src/mm-device.h6
-rw-r--r--src/mm-plugin-manager.c6
-rw-r--r--src/mm-plugin.c2
-rw-r--r--src/mm-plugin.h2
6 files changed, 71 insertions, 66 deletions
diff --git a/src/mm-base-manager.c b/src/mm-base-manager.c
index 275a855f..cdc5d54a 100644
--- a/src/mm-base-manager.c
+++ b/src/mm-base-manager.c
@@ -111,18 +111,17 @@ find_device_by_port (MMBaseManager *manager,
}
static MMDevice *
-find_device_by_sysfs_path (MMBaseManager *self,
- const gchar *sysfs_path)
+find_device_by_physdev_uid (MMBaseManager *self,
+ const gchar *physdev_uid)
{
- return g_hash_table_lookup (self->priv->devices,
- sysfs_path);
+ return g_hash_table_lookup (self->priv->devices, physdev_uid);
}
static MMDevice *
find_device_by_udev_device (MMBaseManager *manager,
GUdevDevice *udev_device)
{
- return find_device_by_sysfs_path (manager, g_udev_device_get_sysfs_path (udev_device));
+ return find_device_by_physdev_uid (manager, g_udev_device_get_sysfs_path (udev_device));
}
/*****************************************************************************/
@@ -151,8 +150,8 @@ device_support_check_ready (MMPluginManager *plugin_manager,
/* Receive plugin result from the plugin manager */
plugin = mm_plugin_manager_device_support_check_finish (plugin_manager, res, &error);
if (!plugin) {
- mm_info ("Couldn't check support for device at '%s': %s",
- mm_device_get_path (ctx->device), error->message);
+ mm_info ("Couldn't check support for device '%s': %s",
+ mm_device_get_uid (ctx->device), error->message);
g_error_free (error);
find_device_support_context_free (ctx);
return;
@@ -163,16 +162,16 @@ device_support_check_ready (MMPluginManager *plugin_manager,
g_object_unref (plugin);
if (!mm_device_create_modem (ctx->device, ctx->self->priv->object_manager, &error)) {
- mm_warn ("Couldn't create modem for device at '%s': %s",
- mm_device_get_path (ctx->device), error->message);
+ mm_warn ("Couldn't create modem for device '%s': %s",
+ mm_device_get_uid (ctx->device), error->message);
g_error_free (error);
find_device_support_context_free (ctx);
return;
}
/* Modem now created */
- mm_info ("Modem for device at '%s' successfully created",
- mm_device_get_path (ctx->device));
+ mm_info ("Modem for device '%s' successfully created",
+ mm_device_get_uid (ctx->device));
find_device_support_context_free (ctx);
}
@@ -268,19 +267,16 @@ device_removed (MMBaseManager *self,
/* Handle tty/net/wdm port removal */
device = find_device_by_port (self, udev_device);
if (device) {
- mm_info ("(%s/%s): released by modem %s",
- subsys,
- name,
- g_udev_device_get_sysfs_path (mm_device_peek_udev_device (device)));
+ mm_info ("(%s/%s): released by device '%s'", subsys, name, mm_device_get_uid (device));
mm_device_release_port (device, udev_device);
/* If port probe list gets empty, remove the device object iself */
if (!mm_device_peek_port_probe_list (device)) {
- mm_dbg ("Removing empty device '%s'", mm_device_get_path (device));
+ mm_dbg ("Removing empty device '%s'", mm_device_get_uid (device));
if (mm_plugin_manager_device_support_check_cancel (self->priv->plugin_manager, device))
mm_dbg ("Device support check has been cancelled");
mm_device_remove_modem (device);
- g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
+ g_hash_table_remove (self->priv->devices, mm_device_get_uid (device));
}
}
@@ -297,9 +293,9 @@ device_removed (MMBaseManager *self,
*/
device = find_device_by_udev_device (self, udev_device);
if (device) {
- mm_dbg ("Removing device '%s'", mm_device_get_path (device));
+ mm_dbg ("Removing device '%s'", mm_device_get_uid (device));
mm_device_remove_modem (device);
- g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
+ g_hash_table_remove (self->priv->devices, mm_device_get_uid (device));
return;
}
@@ -314,7 +310,7 @@ device_added (MMBaseManager *manager,
gboolean manual_scan)
{
MMDevice *device;
- const char *subsys, *name, *physdev_path, *physdev_subsys;
+ const char *subsys, *name, *physdev_uid, *physdev_subsys;
gboolean is_candidate;
GUdevDevice *physdev = NULL;
@@ -389,21 +385,21 @@ device_added (MMBaseManager *manager,
goto out;
}
- physdev_path = g_udev_device_get_sysfs_path (physdev);
- if (!physdev_path) {
+ physdev_uid = g_udev_device_get_sysfs_path (physdev);
+ if (!physdev_uid) {
mm_dbg ("(%s/%s): could not get port's parent device sysfs path", subsys, name);
goto out;
}
/* See if we already created an object to handle ports in this device */
- device = find_device_by_sysfs_path (manager, physdev_path);
+ device = find_device_by_physdev_uid (manager, physdev_uid);
if (!device) {
FindDeviceSupportContext *ctx;
/* Keep the device listed in the Manager */
device = mm_device_new (physdev, hotplugged);
g_hash_table_insert (manager->priv->devices,
- g_strdup (physdev_path),
+ g_strdup (physdev_uid),
device);
/* Launch device support check */
@@ -754,15 +750,15 @@ handle_set_profile (MmGdbusTest *skeleton,
{
MMPlugin *plugin;
MMDevice *device;
- gchar *physdev;
+ gchar *physdev_uid;
GError *error = NULL;
mm_info ("Test profile set to: '%s'", id);
/* Create device and keep it listed in the Manager */
- physdev = g_strdup_printf ("/virtual/%s", id);
- device = mm_device_virtual_new (physdev, TRUE);
- g_hash_table_insert (self->priv->devices, physdev, device);
+ physdev_uid = g_strdup_printf ("/virtual/%s", id);
+ device = mm_device_virtual_new (physdev_uid, TRUE);
+ g_hash_table_insert (self->priv->devices, physdev_uid, device);
/* Grab virtual ports */
mm_device_virtual_grab_ports (device, (const gchar **)ports);
@@ -774,8 +770,8 @@ handle_set_profile (MmGdbusTest *skeleton,
MM_CORE_ERROR_NOT_FOUND,
"Requested plugin '%s' not found",
plugin_name);
- mm_warn ("Couldn't set plugin for virtual device at '%s': %s",
- mm_device_get_path (device),
+ mm_warn ("Couldn't set plugin for virtual device '%s': %s",
+ mm_device_get_uid (device),
error->message);
goto out;
}
@@ -783,20 +779,20 @@ handle_set_profile (MmGdbusTest *skeleton,
/* Create modem */
if (!mm_device_create_modem (device, self->priv->object_manager, &error)) {
- mm_warn ("Couldn't create modem for virtual device at '%s': %s",
- mm_device_get_path (device),
+ mm_warn ("Couldn't create modem for virtual device '%s': %s",
+ mm_device_get_uid (device),
error->message);
goto out;
}
- mm_info ("Modem for virtual device at '%s' successfully created",
- mm_device_get_path (device));
+ mm_info ("Modem for virtual device '%s' successfully created",
+ mm_device_get_uid (device));
out:
if (error) {
mm_device_remove_modem (device);
- g_hash_table_remove (self->priv->devices, mm_device_get_path (device));
+ g_hash_table_remove (self->priv->devices, mm_device_get_uid (device));
g_dbus_method_invocation_return_gerror (invocation, error);
g_error_free (error);
} else
diff --git a/src/mm-device.c b/src/mm-device.c
index b9ffdf83..a293149f 100644
--- a/src/mm-device.c
+++ b/src/mm-device.c
@@ -31,7 +31,7 @@ G_DEFINE_TYPE (MMDevice, mm_device, G_TYPE_OBJECT);
enum {
PROP_0,
- PROP_PATH,
+ PROP_UID,
PROP_UDEV_DEVICE,
PROP_PLUGIN,
PROP_MODEM,
@@ -53,8 +53,8 @@ struct _MMDevicePrivate {
/* Whether the device is real or virtual */
gboolean virtual;
- /* Device path */
- gchar *path;
+ /* Unique id */
+ gchar *uid;
/* Parent UDev device */
GUdevDevice *udev_device;
@@ -324,7 +324,7 @@ mm_device_grab_port (MMDevice *self,
&self->priv->vendor,
&self->priv->product)) {
mm_dbg ("(%s) could not get vendor/product ID",
- self->priv->path);
+ self->priv->uid);
}
}
@@ -447,7 +447,7 @@ export_modem (MMDevice *self)
mm_dbg ("Exported modem '%s' at path '%s'",
(self->priv->virtual ?
- self->priv->path :
+ self->priv->uid :
g_udev_device_get_sysfs_path (self->priv->udev_device)),
path);
@@ -496,12 +496,12 @@ modem_valid (MMBaseModem *modem,
GError *error = NULL;
if (!mm_device_create_modem (self, self->priv->object_manager, &error)) {
- mm_warn ("Could not recreate modem for device at '%s': %s",
- mm_device_get_path (self),
- error ? error->message : "unknown");
+ mm_warn ("Could not recreate modem for device '%s': %s",
+ self->priv->uid,
+ error ? error->message : "unknown");
g_error_free (error);
} else {
- mm_dbg ("Modem recreated for device '%s'", mm_device_get_path (self));
+ mm_dbg ("Modem recreated for device '%s'", self->priv->uid);
}
}
} else {
@@ -568,9 +568,9 @@ mm_device_create_modem (MMDevice *self,
/*****************************************************************************/
const gchar *
-mm_device_get_path (MMDevice *self)
+mm_device_get_uid (MMDevice *self)
{
- return self->priv->path;
+ return self->priv->uid;
}
const gchar **
@@ -726,23 +726,29 @@ MMDevice *
mm_device_new (GUdevDevice *udev_device,
gboolean hotplugged)
{
+ const gchar *uid;
+
g_return_val_if_fail (udev_device != NULL, NULL);
+ uid = g_udev_device_get_property (udev_device, "ID_MM_PHYSDEV_UID");
+ if (uid)
+ mm_dbg ("device with an explicit physdev UID: %s", uid);
+
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_UID, uid ? uid : g_udev_device_get_sysfs_path (udev_device),
MM_DEVICE_HOTPLUGGED, hotplugged,
NULL));
}
MMDevice *
-mm_device_virtual_new (const gchar *path,
+mm_device_virtual_new (const gchar *uid,
gboolean hotplugged)
{
- g_return_val_if_fail (path != NULL, NULL);
+ g_return_val_if_fail (uid != NULL, NULL);
return MM_DEVICE (g_object_new (MM_TYPE_DEVICE,
- MM_DEVICE_PATH, path,
+ MM_DEVICE_UID, uid,
MM_DEVICE_HOTPLUGGED, hotplugged,
MM_DEVICE_VIRTUAL, TRUE,
NULL));
@@ -766,9 +772,9 @@ set_property (GObject *object,
MMDevice *self = MM_DEVICE (object);
switch (prop_id) {
- case PROP_PATH:
+ case PROP_UID:
/* construct only */
- self->priv->path = g_value_dup_string (value);
+ self->priv->uid = g_value_dup_string (value);
break;
case PROP_UDEV_DEVICE:
/* construct only */
@@ -803,6 +809,9 @@ get_property (GObject *object,
MMDevice *self = MM_DEVICE (object);
switch (prop_id) {
+ case PROP_UID:
+ g_value_set_string (value, self->priv->uid);
+ break;
case PROP_UDEV_DEVICE:
g_value_set_object (value, self->priv->udev_device);
break;
@@ -843,7 +852,7 @@ finalize (GObject *object)
{
MMDevice *self = MM_DEVICE (object);
- g_free (self->priv->path);
+ g_free (self->priv->uid);
g_strfreev (self->priv->drivers);
g_strfreev (self->priv->virtual_ports);
@@ -863,13 +872,13 @@ 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",
+ properties[PROP_UID] =
+ g_param_spec_string (MM_DEVICE_UID,
+ "Unique ID",
+ "Unique device id, e.g. the physical device sysfs path",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
- g_object_class_install_property (object_class, PROP_PATH, properties[PROP_PATH]);
+ g_object_class_install_property (object_class, PROP_UID, properties[PROP_UID]);
properties[PROP_UDEV_DEVICE] =
g_param_spec_object (MM_DEVICE_UDEV_DEVICE,
diff --git a/src/mm-device.h b/src/mm-device.h
index 2da82223..57726e6c 100644
--- a/src/mm-device.h
+++ b/src/mm-device.h
@@ -34,7 +34,7 @@ typedef struct _MMDevice MMDevice;
typedef struct _MMDeviceClass MMDeviceClass;
typedef struct _MMDevicePrivate MMDevicePrivate;
-#define MM_DEVICE_PATH "path"
+#define MM_DEVICE_UID "uid"
#define MM_DEVICE_UDEV_DEVICE "udev-device"
#define MM_DEVICE_PLUGIN "plugin"
#define MM_DEVICE_MODEM "modem"
@@ -78,7 +78,7 @@ gboolean mm_device_create_modem (MMDevice *self,
GError **error);
void mm_device_remove_modem (MMDevice *self);
-const gchar *mm_device_get_path (MMDevice *self);
+const gchar *mm_device_get_uid (MMDevice *self);
const gchar **mm_device_get_drivers (MMDevice *self);
guint16 mm_device_get_vendor (MMDevice *self);
guint16 mm_device_get_product (MMDevice *self);
@@ -104,7 +104,7 @@ gboolean mm_device_get_hotplugged (MMDevice *self);
/* For testing purposes */
-MMDevice *mm_device_virtual_new (const gchar *path,
+MMDevice *mm_device_virtual_new (const gchar *uid,
gboolean hotplugged);
void mm_device_virtual_grab_ports (MMDevice *self,
const gchar **ports);
diff --git a/src/mm-plugin-manager.c b/src/mm-plugin-manager.c
index 22965fdb..8408dc33 100644
--- a/src/mm-plugin-manager.c
+++ b/src/mm-plugin-manager.c
@@ -1355,7 +1355,7 @@ plugin_manager_peek_device_context (MMPluginManager *self,
device_context = (DeviceContext *)(l->data);
if ((device == device_context->device) ||
- (! g_strcmp0 (mm_device_get_path (device_context->device), mm_device_get_path (device))))
+ (!g_strcmp0 (mm_device_get_uid (device_context->device), mm_device_get_uid (device))))
return device_context;
}
return NULL;
@@ -1427,7 +1427,7 @@ mm_plugin_manager_device_support_check (MMPluginManager *self,
if (device_context) {
g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_IN_PROGRESS,
"Device support check task already available for device '%s'",
- mm_device_get_path (device));
+ mm_device_get_uid (device));
g_object_unref (task);
return;
}
@@ -1439,7 +1439,7 @@ mm_plugin_manager_device_support_check (MMPluginManager *self,
self->priv->device_contexts = g_list_prepend (self->priv->device_contexts, device_context);
mm_dbg ("[plugin manager] task %s: new support task for device: %s",
- device_context->name, mm_device_get_path (device_context->device));
+ device_context->name, mm_device_get_uid (device_context->device));
/* Run device context */
device_context_run (self,
diff --git a/src/mm-plugin.c b/src/mm-plugin.c
index 78b767d8..0d9b4087 100644
--- a/src/mm-plugin.c
+++ b/src/mm-plugin.c
@@ -865,7 +865,7 @@ mm_plugin_create_modem (MMPlugin *self,
/* Let the plugin create the modem from the port probe results */
modem = MM_PLUGIN_GET_CLASS (self)->create_modem (MM_PLUGIN (self),
- mm_device_get_path (device),
+ mm_device_get_uid (device),
mm_device_get_drivers (device),
mm_device_get_vendor (device),
mm_device_get_product (device),
diff --git a/src/mm-plugin.h b/src/mm-plugin.h
index 04916794..afe300ad 100644
--- a/src/mm-plugin.h
+++ b/src/mm-plugin.h
@@ -104,7 +104,7 @@ struct _MMPluginClass {
/* Plugins need to provide a method to create a modem object given
* a list of port probes (Mandatory) */
MMBaseModem *(*create_modem) (MMPlugin *plugin,
- const gchar *sysfs_path,
+ const gchar *uid,
const gchar **drivers,
guint16 vendor,
guint16 product,