static void fu_provider_chug_get_firmware_version (FuProviderChugItem *item) { FuProviderChugPrivate *priv = GET_PRIVATE (item->provider_chug); guint16 major; guint16 micro; guint16 minor; guint8 idx; g_autoptr(GError) error = NULL; g_autofree gchar *version = NULL; /* try to get the version without claiming interface */ if (!g_usb_device_open (item->usb_device, &error)) { g_debug ("Failed to open, polling: %s", error->message); return; } idx = g_usb_device_get_custom_index (item->usb_device, G_USB_DEVICE_CLASS_VENDOR_SPECIFIC, 'F', 'W', NULL); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (item->usb_device, idx, NULL); if (tmp != NULL) { item->got_version = TRUE; g_debug ("obtained fwver using extension '%s'", tmp); fu_device_set_version (item->device, tmp); goto out; } } g_usb_device_close (item->usb_device, NULL); /* attempt to open the device and get the serial number */ if (!ch_device_open (item->usb_device, &error)) { g_debug ("Failed to claim interface, polling: %s", error->message); return; } ch_device_queue_get_firmware_ver (priv->device_queue, item->usb_device, &major, &minor, µ); if (!ch_device_queue_process (priv->device_queue, CH_DEVICE_QUEUE_PROCESS_FLAGS_NONE, NULL, &error)) { g_warning ("Failed to get serial: %s", error->message); goto out; } /* got things the old fashioned way */ item->got_version = TRUE; version = g_strdup_printf ("%i.%i.%i", major, minor, micro); g_debug ("obtained fwver using API '%s'", version); fu_device_set_version (item->device, version); out: /* we're done here */ g_clear_error (&error); if (!g_usb_device_close (item->usb_device, &error)) g_debug ("Failed to close: %s", error->message); }
static gboolean fu_usb_device_open (FuDevice *device, GError **error) { FuUsbDevice *self = FU_USB_DEVICE (device); FuUsbDevicePrivate *priv = GET_PRIVATE (self); FuUsbDeviceClass *klass = FU_USB_DEVICE_GET_CLASS (device); guint idx; g_autoptr(FuDeviceLocker) locker = NULL; g_return_val_if_fail (FU_IS_USB_DEVICE (self), FALSE); g_return_val_if_fail (error == NULL || *error == NULL, FALSE); /* already open */ if (priv->usb_device_locker != NULL) return TRUE; /* open */ locker = fu_device_locker_new (priv->usb_device, error); if (locker == NULL) return FALSE; /* get vendor */ if (fu_device_get_vendor (device) == NULL) { idx = g_usb_device_get_manufacturer_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_vendor (device, tmp); } } /* get product */ if (fu_device_get_name (device) == NULL) { idx = g_usb_device_get_product_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_name (device, tmp); } } /* get serial number */ if (fu_device_get_serial (device) == NULL) { idx = g_usb_device_get_serial_number_index (priv->usb_device); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, error); if (tmp == NULL) return FALSE; fu_device_set_serial (device, tmp); } } /* get version number, falling back to the USB device release */ idx = g_usb_device_get_custom_index (priv->usb_device, G_USB_DEVICE_CLASS_VENDOR_SPECIFIC, 'F', 'W', NULL); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, NULL); fu_device_set_version (device, tmp); } /* get GUID from the descriptor if set */ idx = g_usb_device_get_custom_index (priv->usb_device, G_USB_DEVICE_CLASS_VENDOR_SPECIFIC, 'G', 'U', NULL); if (idx != 0x00) { g_autofree gchar *tmp = NULL; tmp = g_usb_device_get_string_descriptor (priv->usb_device, idx, NULL); fu_device_add_guid (device, tmp); } /* subclassed */ if (klass->open != NULL) { if (!klass->open (self, error)) return FALSE; } /* success */ priv->usb_device_locker = g_steal_pointer (&locker); return TRUE; }