Do not misdetect different ColorHug devices

Allow devices to have a specific device ID, which also matches other equivalent
IDs from other providers

This allows the user to plug in one type of device, and not match a different
cached device that also matches the same provider.
This commit is contained in:
Richard Hughes 2016-01-06 13:20:53 +00:00
parent 9a6a9c8b20
commit b1b59d83cb
4 changed files with 52 additions and 10 deletions

View File

@ -35,6 +35,7 @@ static void fu_device_finalize (GObject *object);
**/ **/
typedef struct { typedef struct {
gchar *id; gchar *id;
gchar *equivalent_id;
guint64 flags; guint64 flags;
GHashTable *metadata; GHashTable *metadata;
} FuDevicePrivate; } FuDevicePrivate;
@ -75,6 +76,29 @@ fu_device_set_id (FuDevice *device, const gchar *id)
priv->id = g_strdup (id); priv->id = g_strdup (id);
} }
/**
* fu_device_get_equivalent_id:
**/
const gchar *
fu_device_get_equivalent_id (FuDevice *device)
{
FuDevicePrivate *priv = GET_PRIVATE (device);
g_return_val_if_fail (FU_IS_DEVICE (device), NULL);
return priv->equivalent_id;
}
/**
* fu_device_set_equivalent_id:
**/
void
fu_device_set_equivalent_id (FuDevice *device, const gchar *equivalent_id)
{
FuDevicePrivate *priv = GET_PRIVATE (device);
g_return_if_fail (FU_IS_DEVICE (device));
g_free (priv->equivalent_id);
priv->equivalent_id = g_strdup (equivalent_id);
}
/** /**
* fu_device_get_flags: * fu_device_get_flags:
**/ **/

View File

@ -66,6 +66,9 @@ GVariant *fu_device_to_variant (FuDevice *device);
const gchar *fu_device_get_id (FuDevice *device); const gchar *fu_device_get_id (FuDevice *device);
void fu_device_set_id (FuDevice *device, void fu_device_set_id (FuDevice *device,
const gchar *id); const gchar *id);
const gchar *fu_device_get_equivalent_id (FuDevice *device);
void fu_device_set_equivalent_id (FuDevice *device,
const gchar *equivalent_id);
guint64 fu_device_get_flags (FuDevice *device); guint64 fu_device_get_flags (FuDevice *device);
void fu_device_set_flags (FuDevice *device, void fu_device_set_flags (FuDevice *device,
guint64 flags); guint64 flags);

View File

@ -200,6 +200,8 @@ fu_main_get_item_by_id (FuMainPrivate *priv, const gchar *id)
item = g_ptr_array_index (priv->devices, i); item = g_ptr_array_index (priv->devices, i);
if (g_strcmp0 (fu_device_get_id (item->device), id) == 0) if (g_strcmp0 (fu_device_get_id (item->device), id) == 0)
return item; return item;
if (g_strcmp0 (fu_device_get_equivalent_id (item->device), id) == 0)
return item;
} }
return NULL; return NULL;
} }

View File

@ -41,7 +41,7 @@ static void fu_provider_chug_finalize (GObject *object);
* FuProviderChugPrivate: * FuProviderChugPrivate:
**/ **/
typedef struct { typedef struct {
GHashTable *devices; GHashTable *devices; /* DeviceKey:FuProviderChugItem */
GUsbContext *usb_ctx; GUsbContext *usb_ctx;
ChDeviceQueue *device_queue; ChDeviceQueue *device_queue;
} FuProviderChugPrivate; } FuProviderChugPrivate;
@ -70,6 +70,17 @@ fu_provider_chug_get_name (FuProvider *provider)
return "ColorHug"; return "ColorHug";
} }
/**
* fu_provider_chug_get_device_key:
**/
static gchar *
fu_provider_chug_get_device_key (GUsbDevice *device)
{
return g_strdup_printf ("%s_%s",
g_usb_device_get_platform_id (device),
ch_device_get_guid (device));
}
/** /**
* fu_provider_chug_device_free: * fu_provider_chug_device_free:
**/ **/
@ -330,6 +341,7 @@ fu_provider_chug_update (FuProvider *provider,
g_usb_device_close (item->usb_device, NULL); g_usb_device_close (item->usb_device, NULL);
/* wait for reconnection */ /* wait for reconnection */
g_debug ("ColorHug: Waiting for bootloader");
if (!fu_provider_chug_wait_for_connect (item, error)) if (!fu_provider_chug_wait_for_connect (item, error))
return FALSE; return FALSE;
} }
@ -469,7 +481,7 @@ fu_provider_chug_device_added_cb (GUsbContext *ctx,
FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug); FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
FuProviderChugItem *item; FuProviderChugItem *item;
ChDeviceMode mode; ChDeviceMode mode;
const gchar *platform_id = NULL; g_autofree gchar *device_key = NULL;
/* ignore */ /* ignore */
mode = ch_device_get_mode (device); mode = ch_device_get_mode (device);
@ -482,15 +494,17 @@ fu_provider_chug_device_added_cb (GUsbContext *ctx,
return; return;
/* is already in database */ /* is already in database */
platform_id = g_usb_device_get_platform_id (device); device_key = fu_provider_chug_get_device_key (device);
item = g_hash_table_lookup (priv->devices, platform_id); item = g_hash_table_lookup (priv->devices, device_key);
if (item == NULL) { if (item == NULL) {
item = g_new0 (FuProviderChugItem, 1); item = g_new0 (FuProviderChugItem, 1);
item->loop = g_main_loop_new (NULL, FALSE); item->loop = g_main_loop_new (NULL, FALSE);
item->provider_chug = g_object_ref (provider_chug); item->provider_chug = g_object_ref (provider_chug);
item->usb_device = g_object_ref (device); item->usb_device = g_object_ref (device);
item->device = fu_device_new (); item->device = fu_device_new ();
fu_device_set_id (item->device, platform_id); fu_device_set_id (item->device, device_key);
fu_device_set_equivalent_id (item->device,
g_usb_device_get_platform_id (device));
fu_device_set_guid (item->device, ch_device_get_guid (device)); fu_device_set_guid (item->device, ch_device_get_guid (device));
fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_OFFLINE); fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_OFFLINE);
fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_ONLINE); fu_device_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_ONLINE);
@ -504,8 +518,7 @@ fu_provider_chug_device_added_cb (GUsbContext *ctx,
} }
/* insert to hash */ /* insert to hash */
g_hash_table_insert (priv->devices, g_hash_table_insert (priv->devices, g_strdup (device_key), item);
g_strdup (platform_id), item);
} else { } else {
/* update the device */ /* update the device */
g_object_unref (item->usb_device); g_object_unref (item->usb_device);
@ -565,11 +578,11 @@ fu_provider_chug_device_removed_cb (GUsbContext *ctx,
{ {
FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug); FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
FuProviderChugItem *item; FuProviderChugItem *item;
const gchar *platform_id = NULL; g_autofree gchar *device_key = NULL;
/* already in database */ /* already in database */
platform_id = g_usb_device_get_platform_id (device); device_key = fu_provider_chug_get_device_key (device);
item = g_hash_table_lookup (priv->devices, platform_id); item = g_hash_table_lookup (priv->devices, device_key);
if (item == NULL) if (item == NULL)
return; return;