diff options
author | iain <iain@linux.intel.com> | 2011-10-19 13:06:50 +0100 |
---|---|---|
committer | iain <iain@linux.intel.com> | 2011-10-19 13:06:50 +0100 |
commit | 90101ef52786acfb0a14096f847b12403b15bec2 (patch) | |
tree | 750003eaa2b607a64231a2b1e51f9a64c1103664 | |
parent | faf3fd10171cf7cf432f7dca7f442ec475ee0002 (diff) |
Improve GypsyDiscovery for removed devices
Fallback to checking the product ID components on the tty device if the
usb_device fails. Also don't assume that the correct usb device will be the
grandparent of the tty.
-rw-r--r-- | src/gypsy-discovery.c | 95 |
1 files changed, 68 insertions, 27 deletions
diff --git a/src/gypsy-discovery.c b/src/gypsy-discovery.c index 20de6a9..047f15e 100644 --- a/src/gypsy-discovery.c +++ b/src/gypsy-discovery.c @@ -347,7 +347,9 @@ struct ProductMap { static struct ProductMap known_ids[] = { { "e8d/3329/100", "MTK GPS Receiver" }, + { "0e8d/3329/0100", "MTK GPS Receiver" }, { "1546/1a4/100", "u-blox AG ANTARIS r4 GPS Receiver" }, + { "1546/01a4/0100", "u-blox AG ANTARIS r4 GPS Receiver" }, { NULL, NULL } }; @@ -365,20 +367,18 @@ maybe_add_device (GypsyDiscovery *discovery, return NULL; } - /* Get USB interface */ + /* Find the usb device that owns this TTY */ parent = g_udev_device_get_parent (device); - if (parent == NULL) - return NULL; + while (parent) { + property_type = g_udev_device_get_property (parent, "DEVTYPE"); - /* Get USB device */ - parent = g_udev_device_get_parent (parent); - if (parent == NULL) - return NULL; + GYPSY_NOTE (DISCOVERY, "Found UDev type: %s", property_type); + if (property_type && + g_str_equal (property_type, "usb_device")) { + break; + } - property_type = g_udev_device_get_property (parent, "DEVTYPE"); - if (property_type == NULL || - g_str_equal (property_type, "usb_device") == FALSE) { - return NULL; + parent = g_udev_device_get_parent (parent); } property_id = g_udev_device_get_property (parent, "PRODUCT"); @@ -420,12 +420,31 @@ remove_string_from_array (GPtrArray *array, } } +static char * +build_product_id_from_tty (GUdevDevice *tty) +{ + const char *vendor_id, *model_id, *revision_id; + + vendor_id = g_udev_device_get_property (tty, "ID_VENDOR_ID"); + model_id = g_udev_device_get_property (tty, "ID_MODEL_ID"); + revision_id = g_udev_device_get_property (tty, "ID_REVISION"); + + if (vendor_id == NULL || model_id == NULL || revision_id == NULL) { + GYPSY_NOTE (DISCOVERY, "Missing property %s %s %s", + vendor_id, model_id, revision_id); + return NULL; + } + + return g_strdup_printf ("%s/%s/%s", vendor_id, model_id, revision_id); +} + static const char * maybe_remove_device (GypsyDiscovery *discovery, GUdevDevice *device) { GypsyDiscoveryPrivate *priv = discovery->priv; const char *property_id, *property_type, *name; + char *tty_id; GUdevDevice *parent; int i; @@ -434,32 +453,27 @@ maybe_remove_device (GypsyDiscovery *discovery, return NULL; } - /* Get tty device */ + /* Find the usb device that owns this TTY */ parent = g_udev_device_get_parent (device); - if (parent == NULL) - return NULL; - - /* Get USB interface */ - parent = g_udev_device_get_parent (parent); - if (parent == NULL) - return NULL; + while (parent) { + property_type = g_udev_device_get_property (parent, "DEVTYPE"); - /* Get USB device */ - parent = g_udev_device_get_parent (parent); - if (parent == NULL) - return NULL; + GYPSY_NOTE (DISCOVERY, "Found UDev type: %s", property_type); + if (property_type && + g_str_equal (property_type, "usb_device")) { + break; + } - property_type = g_udev_device_get_property (parent, "DEVTYPE"); - if (property_type == NULL || - g_str_equal (property_type, "usb_device") == FALSE) { - return NULL; + parent = g_udev_device_get_parent (parent); } property_id = g_udev_device_get_property (parent, "PRODUCT"); if (property_id == NULL) { + GYPSY_NOTE (DISCOVERY, "Product ID was NULL"); return NULL; } + GYPSY_NOTE (DISCOVERY, "Found Product ID %s", property_id); for (i = 0; known_ids[i].product_id; i++) { if (g_str_equal (property_id, known_ids[i].product_id)) { @@ -473,6 +487,33 @@ maybe_remove_device (GypsyDiscovery *discovery, } } + /* When removing a USB device, UDev seems to often (only?) give the + parent of the tty as the USB port or hub rather than the device + that was removed. But there may be the various components of the + product ID on the tty device. Check that against the known + database */ + tty_id = build_product_id_from_tty (device); + if (tty_id == NULL) { + GYPSY_NOTE (DISCOVERY, "%s is an unknown device.", name); + return NULL; + } + + GYPSY_NOTE (DISCOVERY, "Found usb_device with unknown product ID. Falling back to tty IDs: %s", tty_id); + for (i = 0; known_ids[i].product_id; i++) { + if (g_str_equal (tty_id, + known_ids[i].product_id)) { + GYPSY_NOTE (DISCOVERY, "Found %s - %s", + known_ids[i].product_name, name); + remove_string_from_array (priv->known_devices, name); + g_free (tty_id); + + return name; + } + } + + GYPSY_NOTE (DISCOVERY, "%s (%s)is an unknown device.", name, tty_id); + g_free (tty_id); + return NULL; } |