On Mon, Aug 29, 2016 at 11:25 AM, Aleksander Morgado <aleksan...@aleksander.es> wrote: >> In the API docs it talks about USB vid/pid, but MM does support at >> least one PCI-native device; the Option Nozomi. SDIO also uses 16-bit >> vid/pid, though I'm not sure why anyone would use SDIO to hook up a >> WWAN modem :) Maybe just say it's a USB or PCI vid/pid for now, but >> could be used for more in the future? >> >> Which means I'm not sure it should be a 'q'. Maybe just an 's' with >> guint16 validation for now? >> > > Yes, that is a good idea, will try to update the patch to reflect that. >
I started to do this change the other day and ended up not very happy with it... Given that the physdev-vid and physdev-pid are not mandatory in the call (it's totally fine to leave them out), I don't think we should complicate what they mean or what they could mean. I have a patch to explicitly avoid saying they're USB-only, though, see attached 0001 patch. What do you think? >> Also, would be nice to have some unit tests for the udev rules file >> parsing code... >> > > Oh, yes, indeed, should add that. Aaand... this is getting too complex! :) See attached patch 0002 for an ongoing attempt to have something unit-testable. The original parser relies on being able to "jump" to the LABELs specified in GOTOs when rules match, just by reading forward looking for the GOTO. This means that not every rule is parsed for every device; the GOTOs make sure only the ones applicable end up being applied. Now, if we want to make the reading of the rules unit-testable we would need to load all rules (e.g. just once) and keep them in memory for example, and then apply the rules to the devices as they appear. What do you think of this new approach? Does it make sense to do this? -- Aleksander https://aleksander.es
From 95777578634cafeab5d9e064743e0d7294282f65 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado <aleksan...@aleksander.es> Date: Thu, 15 Sep 2016 07:47:45 +0200 Subject: [PATCH 2/2] wip: unit tests for udev rules parser --- configure.ac | 2 +- src/Makefile.am | 2 + .../mm-kernel-device-generic-helpers.c | 328 +++++++++++++++++++++ .../mm-kernel-device-generic-helpers.h | 44 +++ src/tests/Makefile.am | 7 +- .../test-udev-rules-data/77-mm-blacklist.rules | 11 + src/tests/test-udev-rules.c | 178 +++++++++++ 7 files changed, 570 insertions(+), 2 deletions(-) create mode 100644 src/kerneldevice/mm-kernel-device-generic-helpers.c create mode 100644 src/kerneldevice/mm-kernel-device-generic-helpers.h create mode 100644 src/tests/test-udev-rules-data/77-mm-blacklist.rules create mode 100644 src/tests/test-udev-rules.c diff --git a/configure.ac b/configure.ac index e691b06..cf6ec1b 100644 --- a/configure.ac +++ b/configure.ac @@ -88,7 +88,7 @@ dnl----------------------------------------------------------------------------- dnl Build dependencies dnl -GLIB_MIN_VERSION=2.36.0 +GLIB_MIN_VERSION=2.38.0 PKG_CHECK_MODULES(MM, glib-2.0 >= $GLIB_MIN_VERSION diff --git a/src/Makefile.am b/src/Makefile.am index 6b3506f..ead652e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -111,6 +111,8 @@ libkerneldevice_la_SOURCES = \ kerneldevice/mm-kernel-device.c \ kerneldevice/mm-kernel-device-generic.h \ kerneldevice/mm-kernel-device-generic.c \ + kerneldevice/mm-kernel-device-generic-helpers.h \ + kerneldevice/mm-kernel-device-generic-helpers.c \ $(NULL) if WITH_UDEV diff --git a/src/kerneldevice/mm-kernel-device-generic-helpers.c b/src/kerneldevice/mm-kernel-device-generic-helpers.c new file mode 100644 index 0000000..9549087 --- /dev/null +++ b/src/kerneldevice/mm-kernel-device-generic-helpers.c @@ -0,0 +1,328 @@ +/* -*- 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 Aleksander Morgado <aleksan...@aleksander.es> + */ + +#include <config.h> +#include <string.h> +#include <gio/gio.h> + +#include <ModemManager.h> +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#include "mm-log.h" +#include "mm-kernel-device-generic-helpers.h" + +/* Define the following symbol to enable verbose rule parsing traces */ +#define TRACE_UDEV_RULES + +#if defined TRACE_UDEV_RULES +# define trace(...) mm_dbg (__VA_ARGS__) +static void +trace_print_rule (MMUdevRule *rule) +{ + GString *rule_str; + + rule_str = g_string_new (""); + + /* Process conditions */ + if (rule->conditions) { + guint i; + + for (i = 0; i < rule->conditions->len; i++) { + MMUdevRuleItem *item; + + item = &g_array_index (rule->conditions, MMUdevRuleItem, i); + g_string_append_printf (rule_str, "[condition %u] %s %s %s, ", + i, + item->parameter, + (item->type == MM_UDEV_RULE_ITEM_TYPE_EQUAL ? "equals to" : + (item->type == MM_UDEV_RULE_ITEM_TYPE_DIFFERENT ? "different than" : "?")), + item->value); + } + } + + /* Process result */ + g_string_append_printf (rule_str, "[result] %s %s %s", + rule->result.parameter, + (g_str_equal (rule->result.parameter, "LABEL") ? "is" : + (g_str_equal (rule->result.parameter, "GOTO") ? "jump to" : + (g_str_has_prefix (rule->result.parameter, "ENV") ? "set to" : + "?"))), + rule->result.value); + + g_debug ("rule: %s", rule_str->str); + g_string_free (rule_str, TRUE); +} +#else +# define trace(...) +# define trace_print_rule_item(...) +#endif + +static const gchar *expected_rules_prefix[] = { "77-mm-", "80-mm-" }; + +/* This is the global list of rules, loaded only once */ +static GList *rules; + +static gboolean +preload_item (MMUdevRuleItem *item, + const gchar *item_str, + GError **error) +{ + const gchar *aux; + const gchar *value; + + if ((aux = strstr (item_str, "==")) != NULL) { + item->type = MM_UDEV_RULE_ITEM_TYPE_EQUAL; + value = aux + 2; + } else if ((aux = strstr (item_str, "!=")) != NULL) { + item->type = MM_UDEV_RULE_ITEM_TYPE_DIFFERENT; + value = aux + 2; + } else if ((aux = strstr (item_str, "=")) != NULL) { + item->type = MM_UDEV_RULE_ITEM_TYPE_ASSIGN; + value = aux + 1; + } else { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Invalid rule item, missing action type: '%s'", item_str); + return FALSE; + } + + item->parameter = g_strndup (item_str, (aux - item_str)); + g_strstrip (item->parameter); + if (!item->parameter[0]) { + g_free (item->parameter); + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Invalid rule item, parameter is empty: '%s'", item_str); + return FALSE; + } + + item->value = g_strdup (value); + g_strdelimit (item->value, "\"", ' '); + g_strstrip (item->value); + if (!item->value[0]) { + g_free (item->parameter); + g_free (item->value); + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "Invalid rule item, value is empty: '%s'", item_str); + return FALSE; + } + + return TRUE; +} + +static gboolean +preload_rule_from_line (const gchar *line, + GError **error) +{ + gchar **split; + guint n_items, i; + MMUdevRule *rule; + GError *inner_error = NULL; + + rule = g_slice_new0 (MMUdevRule); + + split = g_strsplit (line, ",", -1); + n_items = g_strv_length (split); + + /* preload space for conditions */ + if (n_items > 1) + rule->conditions = g_array_sized_new (FALSE, FALSE, sizeof (MMUdevRuleItem), n_items - 1); + + for (i = 0; !inner_error && i < n_items; i++) { + /* All items except for the last one are conditions */ + if (i < (n_items - 1)) { + MMUdevRuleItem item = { 0 }; + + /* If condition correctly preloaded, add it to the rule */ + if (!preload_item (&item, split[i], &inner_error)) + break; + g_assert (item.type != MM_UDEV_RULE_ITEM_TYPE_ASSIGN); + g_assert (item.parameter); + g_assert (item.value); + g_array_append_val (rule->conditions, item); + continue; + } + + /* Last item, the result */ + g_assert_cmpuint (i, ==, (n_items -1)); + if (!preload_item (&rule->result, split[i], &inner_error)) + break; + g_assert (rule->result.type == MM_UDEV_RULE_ITEM_TYPE_ASSIGN); + g_assert (rule->result.parameter); + g_assert (rule->result.value); + } + g_strfreev (split); + + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + + trace_print_rule (rule); + rules = g_list_prepend (rules, rule); + return TRUE; +} + +static gboolean +preload_rules_from_file (const gchar *path, + GError **error) +{ + GFile *file; + GFileInputStream *fistream; + GDataInputStream *distream = NULL; + GError *inner_error = NULL; + gchar *line; + + file = g_file_new_for_path (path); + fistream = g_file_read (file, NULL, &inner_error); + if (!fistream) + goto out; + + distream = g_data_input_stream_new (G_INPUT_STREAM (fistream)); + + while ((line = g_data_input_stream_read_line_utf8 (distream, NULL, NULL, &inner_error)) != NULL) { + const gchar *aux; + + aux = line; + while (*aux == ' ') + aux++; + if (*aux != '#' && *aux != '\0') + preload_rule_from_line (aux, &inner_error); + g_free (line); + } + +out: + + if (distream) + g_object_unref (distream); + if (fistream) + g_object_unref (fistream); + g_object_unref (file); + + if (inner_error) { + g_propagate_error (error, inner_error); + return FALSE; + } + return TRUE; +} + +static GList * +list_rule_files (const gchar *rules_dir_path) +{ + GFile *udevrulesdir; + GFileEnumerator *enumerator; + GList *children = NULL; + + udevrulesdir = g_file_new_for_path (rules_dir_path); + enumerator = g_file_enumerate_children (udevrulesdir, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, + NULL); + if (enumerator) { + GFileInfo *info; + + /* If we get any kind of error, assume we need to stop enumerating */ + while ((info = g_file_enumerator_next_file (enumerator, NULL, NULL)) != NULL) { + guint i; + + for (i = 0; i < G_N_ELEMENTS (expected_rules_prefix); i++) { + if (g_str_has_prefix (g_file_info_get_name (info), expected_rules_prefix[i])) { + children = g_list_prepend (children, g_build_path (G_DIR_SEPARATOR_S, rules_dir_path, g_file_info_get_name (info), NULL)); + break; + } + } + g_object_unref (info); + } + g_object_unref (enumerator); + } + g_object_unref (udevrulesdir); + + return g_list_sort (children, (GCompareFunc) g_strcmp0); +} + +gboolean +mm_kernel_device_generic_helpers_preload_rules (const gchar *rules_dir_path, + GError **error) +{ + GList *rule_files, *l; + GError *inner_error = NULL; + + mm_dbg ("preloading udev rules..."); + + /* Preload only once */ + if (G_LIKELY (rules)) + return TRUE; + + rule_files = list_rule_files (rules_dir_path); + if (!rule_files) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, + "No rule files found in '%s'", rules_dir_path); + return FALSE; + } + + for (l = rule_files; l; l = g_list_next (l)) { + trace ("loading rules from: %s", (const gchar *)(l->data)); + if (!preload_rules_from_file ((const gchar *)(l->data), &inner_error)) { + g_critical ("error: couldn't load rules from file '%s': %s", (const gchar *)(l->data), inner_error->message); + g_clear_error (&inner_error); + } + } + g_list_free_full (rule_files, (GDestroyNotify) g_free); + + if (!rules) { + g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No rules preloaded"); + return FALSE; + } + + /* Note: rules are pre-pended and then list reversed only once */ + rules = g_list_reverse (rules); + + mm_dbg ("udev rules preloaded"); + + return TRUE; +} + +static void +rule_free (MMUdevRule *rule) +{ + if (rule->conditions) { + guint i; + + for (i = 0; i < rule->conditions->len; i++) { + MMUdevRuleItem *condition; + + condition = &g_array_index (rule->conditions, MMUdevRuleItem, i); + g_free (condition->parameter); + g_free (condition->value); + } + g_array_free (rule->conditions, TRUE); + } + g_free (rule->result.parameter); + g_free (rule->result.value); + g_slice_free (MMUdevRule, rule); +} + +void +mm_kernel_device_generic_helpers_cleanup_rules (void) +{ + g_list_free_full (rules, (GDestroyNotify) rule_free); + rules = NULL; +} + +GList * +mm_kernel_device_generic_peek_rules (void) +{ + return rules; +} diff --git a/src/kerneldevice/mm-kernel-device-generic-helpers.h b/src/kerneldevice/mm-kernel-device-generic-helpers.h new file mode 100644 index 0000000..bbd13a4 --- /dev/null +++ b/src/kerneldevice/mm-kernel-device-generic-helpers.h @@ -0,0 +1,44 @@ +/* -*- 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 Aleksander Morgado <aleksan...@aleksander.es> + */ + +#ifndef MM_KERNEL_DEVICE_GENERIC_HELPERS_H +#define MM_KERNEL_DEVICE_GENERIC_HELPERS_H + +#include <glib.h> +#include <glib-object.h> + +typedef enum { + MM_UDEV_RULE_ITEM_TYPE_EQUAL, + MM_UDEV_RULE_ITEM_TYPE_DIFFERENT, + MM_UDEV_RULE_ITEM_TYPE_ASSIGN, +} MMUdevRuleItemType; + +typedef struct { + MMUdevRuleItemType type; + gchar *parameter; + gchar *value; +} MMUdevRuleItem; + +typedef struct { + GArray *conditions; + MMUdevRuleItem result; +} MMUdevRule; + +gboolean mm_kernel_device_generic_helpers_preload_rules (const gchar *rules_dir, + GError **error); +void mm_kernel_device_generic_helpers_cleanup_rules (void); +GList *mm_kernel_device_generic_peek_rules (void); + +#endif /* MM_KERNEL_DEVICE_GENERIC_HELPERS_H */ diff --git a/src/tests/Makefile.am b/src/tests/Makefile.am index 97adac6..44b40a6 100644 --- a/src/tests/Makefile.am +++ b/src/tests/Makefile.am @@ -17,6 +17,7 @@ AM_CFLAGS = \ -I${top_srcdir}/src/ \ -I${top_builddir}/src/ \ -I${top_srcdir}/src/kerneldevice \ + -DTESTUDEVRULESDIR=\"${top_srcdir}/src/test/test-udev-rules-data\" \ $(NULL) AM_LDFLAGS = \ @@ -24,6 +25,7 @@ AM_LDFLAGS = \ $(CODE_COVERAGE_LDFLAGS) \ $(top_builddir)/src/libhelpers.la \ $(top_builddir)/src/libport.la \ + $(top_builddir)/src/libkerneldevice.la \ -lutil \ $(NULL) @@ -39,7 +41,7 @@ endif ################################################################################ # tests -# note: we abuse AM_LDFLAGS to include libhelpers and libport. +# note: we abuse AM_LDFLAGS to include the libraries being tested ################################################################################ noinst_PROGRAMS = \ @@ -49,6 +51,7 @@ noinst_PROGRAMS = \ test-at-serial-port \ test-sms-part-3gpp \ test-sms-part-cdma \ + test-udev-rules \ $(NULL) if WITH_QMI @@ -56,3 +59,5 @@ noinst_PROGRAMS += test-modem-helpers-qmi endif TEST_PROGS += $(noinst_PROGRAMS) + +EXTRA_DIST = test-udev-rules-data diff --git a/src/tests/test-udev-rules-data/77-mm-blacklist.rules b/src/tests/test-udev-rules-data/77-mm-blacklist.rules new file mode 100644 index 0000000..bdbcf47 --- /dev/null +++ b/src/tests/test-udev-rules-data/77-mm-blacklist.rules @@ -0,0 +1,11 @@ + +ACTION!="add|change|move", GOTO="mm_blacklist_end" +SUBSYSTEM!="usb", GOTO="mm_blacklist_end" + +# Test vendor check only +ATTRS{idVendor}=="aaaa", ENV{ID_MM_DEVICE_IGNORE}="1" + +# Test vendor & product +ATTRS{idVendor}=="bbbb", ATTRS{idProduct}=="1111", ENV{ID_MM_DEVICE_IGNORE}="1" + +LABEL="mm_blacklist_end" diff --git a/src/tests/test-udev-rules.c b/src/tests/test-udev-rules.c new file mode 100644 index 0000000..82ae274 --- /dev/null +++ b/src/tests/test-udev-rules.c @@ -0,0 +1,178 @@ +/* -*- 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 Aleksander Morgado <aleksan...@aleksander.es> + */ + +#include <glib.h> +#include <glib-object.h> +#include <string.h> +#include <stdio.h> +#include <locale.h> + +#define _LIBMM_INSIDE_MM +#include <libmm-glib.h> + +#define ENABLE_TEST_MESSAGE_TRACES + +#include "mm-kernel-device-generic-helpers.h" +#include "mm-log.h" + +/************************************************************/ + +static void +common_setup (void) +{ + gboolean result; + GError *error = NULL; + + result = mm_kernel_device_generic_helpers_preload_rules (g_test_get_filename (G_TEST_DIST, "test-udev-rules-data", NULL), &error); + g_assert_no_error (error); + g_assert (result); +} + +static void +common_teardown (void) +{ + mm_kernel_device_generic_helpers_cleanup_rules (); +} + +/************************************************************/ + +static void +test_preload_cleanup (void) +{ + common_setup (); + common_teardown (); +} + +/************************************************************/ + +static guint16 +parse_vid_pid (const gchar *str) +{ + guint64 id; + gchar *endptr = NULL; + + id = g_ascii_strtoull (str, &endptr, 16); + g_assert (id <= G_MAXUINT16); + g_assert (endptr != str); + + return (guint16) id; +} + +static void +common_test_blacklist_rules (guint16 vid, + guint16 pid, + gboolean expect_blacklisted) +{ + GList *list, *l; + gboolean blacklisted = FALSE; + + common_setup (); + + g_debug ("Checking 0x%04X:0x%04X...", vid, pid); + + list = mm_kernel_device_generic_peek_rules (); + for (l = list; l && !blacklisted; l = g_list_next (l)) { + MMUdevRule *rule; + + rule = (MMUdevRule *)(l->data); + if (g_str_equal (rule->result.parameter, "ENV{ID_MM_DEVICE_IGNORE}")) { + guint i; + gboolean vendor_matched = FALSE; + gboolean vendor_found = FALSE; + gboolean product_matched = FALSE; + gboolean product_found = FALSE; + + for (i = 0; i < rule->conditions->len; i++) { + MMUdevRuleItem *item; + + item = (MMUdevRuleItem *) &g_array_index (rule->conditions, MMUdevRuleItem, i); + + if (g_str_equal (item->parameter, "ATTRS{idVendor}")) { + vendor_found = TRUE; + if (parse_vid_pid (item->value) == vid) + vendor_matched = TRUE; + } else if (g_str_equal (item->parameter, "ATTRS{idProduct}")) { + product_found = TRUE; + if (parse_vid_pid (item->value) == pid) + product_found = TRUE; + } + } + + g_debug (" vendor %s (%s), product %s (%s)", + vendor_found ? "found" : "not found", + vendor_matched ? "matched" : "not matched", + product_found ? "found" : "not found", + product_matched ? "matched" : "not matched"); + + if (product_matched) + g_assert (vendor_found); + + if (vendor_matched && (!product_found || product_matched)) + blacklisted = TRUE; + } + } + + g_assert (blacklisted == expect_blacklisted); + + common_teardown (); +} + +static void +test_blacklist (void) +{ + common_test_blacklist_rules (0xAAAA, 0x0000, TRUE); + common_test_blacklist_rules (0xAAAA, 0x1111, TRUE); + + common_test_blacklist_rules (0xBBBB, 0x0000, FALSE); + common_test_blacklist_rules (0xBBBB, 0x1111, TRUE); + + common_test_blacklist_rules (0xCCCC, 0x0000, FALSE); + common_test_blacklist_rules (0xCCCC, 0x1111, FALSE); +} + +/************************************************************/ + +void +_mm_log (const char *loc, + const char *func, + guint32 level, + const char *fmt, + ...) +{ +#if defined ENABLE_TEST_MESSAGE_TRACES + /* Dummy log function */ + va_list args; + gchar *msg; + + va_start (args, fmt); + msg = g_strdup_vprintf (fmt, args); + va_end (args); + g_print ("%s\n", msg); + g_free (msg); +#endif +} + +int main (int argc, char **argv) +{ + setlocale (LC_ALL, ""); + + g_type_init (); + g_test_init (&argc, &argv, NULL); + + g_test_add_func ("/MM/test-udev-rules/preload-cleanup", test_preload_cleanup); + g_test_add_func ("/MM/test-udev-rules/blacklist", test_blacklist); + + return g_test_run (); +} -- 2.9.3
From d4fa6b507fcdb2e44caec3a40821e76d318c9b0f Mon Sep 17 00:00:00 2001 From: Aleksander Morgado <aleksan...@aleksander.es> Date: Thu, 1 Sep 2016 17:56:25 +0200 Subject: [PATCH 1/2] core: don't assume VID/PID are USB only We do assume, though, that both VID and PID are 16-bits long, which is what we already handle in the internal setup for USB, PCMCIA and PCI subsystems. --- introspection/org.freedesktop.ModemManager1.xml | 10 ++++++---- libmm-glib/mm-kernel-event-properties.c | 8 ++++---- src/mm-device.c | 2 +- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/introspection/org.freedesktop.ModemManager1.xml b/introspection/org.freedesktop.ModemManager1.xml index 32c896b..fb9adec 100644 --- a/introspection/org.freedesktop.ModemManager1.xml +++ b/introspection/org.freedesktop.ModemManager1.xml @@ -119,11 +119,12 @@ <varlistentry><term><literal>physdev-vid</literal></term> <listitem> <para> - The USB vendor ID of the physical device, given as a 16 bit + The vendor ID of the physical device, given as a 16 bit unsigned integer (signature <literal>"q"</literal>. This parameter is OPTIONAL, if not given it will be retrieved from sysfs. This parameter may be used to override the real one - exposed by the device. + exposed by the device. For devices in the USB subsystem, this + will be the USB VID of the device. </para> </listitem> </varlistentry> @@ -131,11 +132,12 @@ <varlistentry><term><literal>physdev-pid</literal></term> <listitem> <para> - The USB product ID of the physical device, given as a 16 bit + The product ID of the physical device, given as a 16 bit unsigned integer (signature <literal>"q"</literal>. This parameter is OPTIONAL, if not given it will be retrieved from sysfs. This parameter may be used to override the real one - exposed by the device. + exposed by the device. For devices in the USB subsystem, this + will be the USB PID of the device. </para> </listitem> </varlistentry> diff --git a/libmm-glib/mm-kernel-event-properties.c b/libmm-glib/mm-kernel-event-properties.c index 5ff52f9..fa6ffef 100644 --- a/libmm-glib/mm-kernel-event-properties.c +++ b/libmm-glib/mm-kernel-event-properties.c @@ -238,7 +238,7 @@ mm_kernel_event_properties_get_physdev_uid (MMKernelEventProperties *self) * @self: A #MMKernelEventProperties. * @physdev_vid: The vendor id to set. * - * Sets the USB vendor id of the physical device. + * Sets the vendor id of the physical device. */ void mm_kernel_event_properties_set_physdev_vid (MMKernelEventProperties *self, @@ -253,7 +253,7 @@ mm_kernel_event_properties_set_physdev_vid (MMKernelEventProperties *self, * mm_kernel_event_properties_get_physdev_vid: * @self: A #MMKernelEventProperties. * - * Gets the USB vendor id of the physical device. + * Gets the vendor id of the physical device. * * Returns: The vendor id. */ @@ -272,7 +272,7 @@ mm_kernel_event_properties_get_physdev_vid (MMKernelEventProperties *self) * @self: A #MMKernelEventProperties. * @physdev_pid: The product id to set. * - * Sets the USB product id of the physical device. + * Sets the product id of the physical device. */ void mm_kernel_event_properties_set_physdev_pid (MMKernelEventProperties *self, @@ -287,7 +287,7 @@ mm_kernel_event_properties_set_physdev_pid (MMKernelEventProperties *self, * mm_kernel_event_properties_get_physdev_pid: * @self: A #MMKernelEventProperties. * - * Gets the USB product id of the physical device. + * Gets the product id of the physical device. * * Returns: The product id. */ diff --git a/src/mm-device.c b/src/mm-device.c index ffa4fd2..83fe5aa 100644 --- a/src/mm-device.c +++ b/src/mm-device.c @@ -55,7 +55,7 @@ struct _MMDevicePrivate { /* Unique id */ gchar *uid; - /* If USB, device vid/pid */ + /* Device vid/pid */ guint16 vendor; guint16 product; -- 2.9.3
_______________________________________________ ModemManager-devel mailing list ModemManager-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/modemmanager-devel