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 {
gchar *id;
gchar *equivalent_id;
guint64 flags;
GHashTable *metadata;
} FuDevicePrivate;
@ -75,6 +76,29 @@ fu_device_set_id (FuDevice *device, const gchar *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:
**/

View File

@ -66,6 +66,9 @@ GVariant *fu_device_to_variant (FuDevice *device);
const gchar *fu_device_get_id (FuDevice *device);
void fu_device_set_id (FuDevice *device,
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);
void fu_device_set_flags (FuDevice *device,
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);
if (g_strcmp0 (fu_device_get_id (item->device), id) == 0)
return item;
if (g_strcmp0 (fu_device_get_equivalent_id (item->device), id) == 0)
return item;
}
return NULL;
}

View File

@ -41,7 +41,7 @@ static void fu_provider_chug_finalize (GObject *object);
* FuProviderChugPrivate:
**/
typedef struct {
GHashTable *devices;
GHashTable *devices; /* DeviceKey:FuProviderChugItem */
GUsbContext *usb_ctx;
ChDeviceQueue *device_queue;
} FuProviderChugPrivate;
@ -70,6 +70,17 @@ fu_provider_chug_get_name (FuProvider *provider)
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:
**/
@ -330,6 +341,7 @@ fu_provider_chug_update (FuProvider *provider,
g_usb_device_close (item->usb_device, NULL);
/* wait for reconnection */
g_debug ("ColorHug: Waiting for bootloader");
if (!fu_provider_chug_wait_for_connect (item, error))
return FALSE;
}
@ -469,7 +481,7 @@ fu_provider_chug_device_added_cb (GUsbContext *ctx,
FuProviderChugPrivate *priv = GET_PRIVATE (provider_chug);
FuProviderChugItem *item;
ChDeviceMode mode;
const gchar *platform_id = NULL;
g_autofree gchar *device_key = NULL;
/* ignore */
mode = ch_device_get_mode (device);
@ -482,15 +494,17 @@ fu_provider_chug_device_added_cb (GUsbContext *ctx,
return;
/* is already in database */
platform_id = g_usb_device_get_platform_id (device);
item = g_hash_table_lookup (priv->devices, platform_id);
device_key = fu_provider_chug_get_device_key (device);
item = g_hash_table_lookup (priv->devices, device_key);
if (item == NULL) {
item = g_new0 (FuProviderChugItem, 1);
item->loop = g_main_loop_new (NULL, FALSE);
item->provider_chug = g_object_ref (provider_chug);
item->usb_device = g_object_ref (device);
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_add_flag (item->device, FU_DEVICE_FLAG_ALLOW_OFFLINE);
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 */
g_hash_table_insert (priv->devices,
g_strdup (platform_id), item);
g_hash_table_insert (priv->devices, g_strdup (device_key), item);
} else {
/* update the 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);
FuProviderChugItem *item;
const gchar *platform_id = NULL;
g_autofree gchar *device_key = NULL;
/* already in database */
platform_id = g_usb_device_get_platform_id (device);
item = g_hash_table_lookup (priv->devices, platform_id);
device_key = fu_provider_chug_get_device_key (device);
item = g_hash_table_lookup (priv->devices, device_key);
if (item == NULL)
return;