mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-08 19:31:23 +00:00
Fix hotplug events when emulating devices
This commit is contained in:
parent
af5fb429c8
commit
3ab4e386c5
@ -3145,6 +3145,32 @@ _plugin_device_register_cb(FuPlugin *plugin, FuDevice *device, gpointer user_dat
|
|||||||
fu_plugin_runner_device_register(plugin, device);
|
fu_plugin_runner_device_register(plugin, device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_backend_usb_hotplug_cb(FuBackend *backend, FuDevice *device, gpointer user_data)
|
||||||
|
{
|
||||||
|
guint *cnt = (guint *)user_data;
|
||||||
|
(*cnt)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fu_backend_usb_load_file(FuBackend *backend, const gchar *fn)
|
||||||
|
{
|
||||||
|
gboolean ret;
|
||||||
|
g_autoptr(GError) error = NULL;
|
||||||
|
g_autoptr(JsonParser) parser = json_parser_new();
|
||||||
|
|
||||||
|
ret = json_parser_load_from_file(parser, fn, &error);
|
||||||
|
g_assert_no_error(error);
|
||||||
|
g_assert_true(ret);
|
||||||
|
ret = fu_backend_load(backend,
|
||||||
|
json_node_get_object(json_parser_get_root(parser)),
|
||||||
|
NULL,
|
||||||
|
FU_BACKEND_LOAD_FLAG_NONE,
|
||||||
|
&error);
|
||||||
|
g_assert_no_error(error);
|
||||||
|
g_assert_true(ret);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To generate the fwupd DS20 descriptor in the usb-devices.json file save fw-ds20.builder.xml:
|
* To generate the fwupd DS20 descriptor in the usb-devices.json file save fw-ds20.builder.xml:
|
||||||
*
|
*
|
||||||
@ -3174,8 +3200,12 @@ fu_backend_usb_func(gconstpointer user_data)
|
|||||||
#ifdef HAVE_GUSB
|
#ifdef HAVE_GUSB
|
||||||
FuTest *self = (FuTest *)user_data;
|
FuTest *self = (FuTest *)user_data;
|
||||||
gboolean ret;
|
gboolean ret;
|
||||||
|
guint cnt_added = 0;
|
||||||
|
guint cnt_removed = 0;
|
||||||
FuDevice *device_tmp;
|
FuDevice *device_tmp;
|
||||||
g_autofree gchar *gusb_emulate_fn = NULL;
|
g_autofree gchar *gusb_emulate_fn = NULL;
|
||||||
|
g_autofree gchar *gusb_emulate_fn2 = NULL;
|
||||||
|
g_autofree gchar *gusb_emulate_fn3 = NULL;
|
||||||
g_autofree gchar *devicestr = NULL;
|
g_autofree gchar *devicestr = NULL;
|
||||||
g_autoptr(FuBackend) backend = fu_usb_backend_new(self->ctx);
|
g_autoptr(FuBackend) backend = fu_usb_backend_new(self->ctx);
|
||||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||||
@ -3183,33 +3213,37 @@ fu_backend_usb_func(gconstpointer user_data)
|
|||||||
g_autoptr(GError) error = NULL;
|
g_autoptr(GError) error = NULL;
|
||||||
g_autoptr(GPtrArray) devices = NULL;
|
g_autoptr(GPtrArray) devices = NULL;
|
||||||
g_autoptr(GPtrArray) possible_plugins = NULL;
|
g_autoptr(GPtrArray) possible_plugins = NULL;
|
||||||
g_autoptr(JsonParser) parser = json_parser_new();
|
|
||||||
|
|
||||||
#if !G_USB_CHECK_VERSION(0, 4, 2)
|
#if !G_USB_CHECK_VERSION(0, 4, 4)
|
||||||
g_test_skip("GUsb version too old");
|
g_test_skip("GUsb version too old");
|
||||||
return;
|
return;
|
||||||
#endif
|
#endif
|
||||||
|
/* check there were events */
|
||||||
|
g_signal_connect(backend,
|
||||||
|
"device-added",
|
||||||
|
G_CALLBACK(fu_backend_usb_hotplug_cb),
|
||||||
|
&cnt_added);
|
||||||
|
g_signal_connect(backend,
|
||||||
|
"device-removed",
|
||||||
|
G_CALLBACK(fu_backend_usb_hotplug_cb),
|
||||||
|
&cnt_removed);
|
||||||
|
|
||||||
/* load the JSON into the backend */
|
/* load the JSON into the backend */
|
||||||
gusb_emulate_fn = g_test_build_filename(G_TEST_DIST, "tests", "usb-devices.json", NULL);
|
|
||||||
ret = json_parser_load_from_file(parser, gusb_emulate_fn, &error);
|
|
||||||
g_assert_no_error(error);
|
|
||||||
g_assert_true(ret);
|
|
||||||
g_assert_cmpstr(fu_backend_get_name(backend), ==, "usb");
|
g_assert_cmpstr(fu_backend_get_name(backend), ==, "usb");
|
||||||
g_assert_true(fu_backend_get_enabled(backend));
|
g_assert_true(fu_backend_get_enabled(backend));
|
||||||
ret = fu_backend_setup(backend, progress, &error);
|
ret = fu_backend_setup(backend, progress, &error);
|
||||||
g_assert_no_error(error);
|
g_assert_no_error(error);
|
||||||
g_assert_true(ret);
|
g_assert_true(ret);
|
||||||
ret = fu_backend_load(backend,
|
gusb_emulate_fn = g_test_build_filename(G_TEST_DIST, "tests", "usb-devices.json", NULL);
|
||||||
json_node_get_object(json_parser_get_root(parser)),
|
g_assert_nonnull(gusb_emulate_fn);
|
||||||
NULL,
|
fu_backend_usb_load_file(backend, gusb_emulate_fn);
|
||||||
FU_BACKEND_LOAD_FLAG_NONE,
|
g_assert_cmpint(cnt_added, ==, 0);
|
||||||
&error);
|
g_assert_cmpint(cnt_removed, ==, 0);
|
||||||
g_assert_no_error(error);
|
|
||||||
g_assert_true(ret);
|
|
||||||
ret = fu_backend_coldplug(backend, progress, &error);
|
ret = fu_backend_coldplug(backend, progress, &error);
|
||||||
g_assert_no_error(error);
|
g_assert_no_error(error);
|
||||||
g_assert_true(ret);
|
g_assert_true(ret);
|
||||||
|
g_assert_cmpint(cnt_added, ==, 1);
|
||||||
|
g_assert_cmpint(cnt_removed, ==, 0);
|
||||||
devices = fu_backend_get_devices(backend);
|
devices = fu_backend_get_devices(backend);
|
||||||
g_assert_cmpint(devices->len, ==, 1);
|
g_assert_cmpint(devices->len, ==, 1);
|
||||||
device_tmp = g_ptr_array_index(devices, 0);
|
device_tmp = g_ptr_array_index(devices, 0);
|
||||||
@ -3217,6 +3251,7 @@ fu_backend_usb_func(gconstpointer user_data)
|
|||||||
locker = fu_device_locker_new(device_tmp, &error);
|
locker = fu_device_locker_new(device_tmp, &error);
|
||||||
g_assert_no_error(error);
|
g_assert_no_error(error);
|
||||||
g_assert_nonnull(locker);
|
g_assert_nonnull(locker);
|
||||||
|
g_assert_true(fu_device_has_flag(device_tmp, FWUPD_DEVICE_FLAG_EMULATED));
|
||||||
|
|
||||||
/* for debugging */
|
/* for debugging */
|
||||||
devicestr = fu_device_to_string(device_tmp);
|
devicestr = fu_device_to_string(device_tmp);
|
||||||
@ -3232,6 +3267,22 @@ fu_backend_usb_func(gconstpointer user_data)
|
|||||||
possible_plugins = fu_device_get_possible_plugins(device_tmp);
|
possible_plugins = fu_device_get_possible_plugins(device_tmp);
|
||||||
g_assert_cmpint(possible_plugins->len, ==, 1);
|
g_assert_cmpint(possible_plugins->len, ==, 1);
|
||||||
g_assert_cmpstr(g_ptr_array_index(possible_plugins, 0), ==, "dfu");
|
g_assert_cmpstr(g_ptr_array_index(possible_plugins, 0), ==, "dfu");
|
||||||
|
|
||||||
|
/* load another device with the same VID:PID, and check that we did not get a replug */
|
||||||
|
gusb_emulate_fn2 =
|
||||||
|
g_test_build_filename(G_TEST_DIST, "tests", "usb-devices-replace.json", NULL);
|
||||||
|
g_assert_nonnull(gusb_emulate_fn2);
|
||||||
|
fu_backend_usb_load_file(backend, gusb_emulate_fn2);
|
||||||
|
g_assert_cmpint(cnt_added, ==, 1);
|
||||||
|
g_assert_cmpint(cnt_removed, ==, 0);
|
||||||
|
|
||||||
|
/* load another device with a different VID:PID, and check that we *did* get a replug */
|
||||||
|
gusb_emulate_fn3 =
|
||||||
|
g_test_build_filename(G_TEST_DIST, "tests", "usb-devices-bootloader.json", NULL);
|
||||||
|
g_assert_nonnull(gusb_emulate_fn3);
|
||||||
|
fu_backend_usb_load_file(backend, gusb_emulate_fn3);
|
||||||
|
g_assert_cmpint(cnt_added, ==, 2);
|
||||||
|
g_assert_cmpint(cnt_removed, ==, 1);
|
||||||
#else
|
#else
|
||||||
g_test_skip("No GUsb support");
|
g_test_skip("No GUsb support");
|
||||||
#endif
|
#endif
|
||||||
|
@ -50,8 +50,25 @@ fu_usb_backend_device_notify_flags_cb(FuDevice *device, GParamSpec *pspec, FuBac
|
|||||||
static void
|
static void
|
||||||
fu_usb_backend_device_added_cb(GUsbContext *ctx, GUsbDevice *usb_device, FuBackend *backend)
|
fu_usb_backend_device_added_cb(GUsbContext *ctx, GUsbDevice *usb_device, FuBackend *backend)
|
||||||
{
|
{
|
||||||
|
FuDevice *device_tmp;
|
||||||
g_autoptr(FuUsbDevice) device = NULL;
|
g_autoptr(FuUsbDevice) device = NULL;
|
||||||
|
|
||||||
|
/* is emulated? */
|
||||||
|
device_tmp = fu_backend_lookup_by_id(backend, g_usb_device_get_platform_id(usb_device));
|
||||||
|
if (device_tmp != NULL && fu_device_has_flag(device_tmp, FWUPD_DEVICE_FLAG_EMULATED)) {
|
||||||
|
if (g_usb_device_get_vid(usb_device) ==
|
||||||
|
fu_usb_device_get_vid(FU_USB_DEVICE(device_tmp)) &&
|
||||||
|
g_usb_device_get_pid(usb_device) ==
|
||||||
|
fu_usb_device_get_pid(FU_USB_DEVICE(device_tmp))) {
|
||||||
|
g_debug("replacing GUsbDevice of emulated device %s",
|
||||||
|
fu_device_get_id(device_tmp));
|
||||||
|
fu_usb_device_set_dev(FU_USB_DEVICE(device_tmp), usb_device);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_debug("delayed removal of emulated device as VID:PID changed");
|
||||||
|
fu_backend_device_removed(backend, device_tmp);
|
||||||
|
}
|
||||||
|
|
||||||
/* success */
|
/* success */
|
||||||
device = fu_usb_device_new(fu_backend_get_context(backend), usb_device);
|
device = fu_usb_device_new(fu_backend_get_context(backend), usb_device);
|
||||||
fu_backend_device_added(backend, FU_DEVICE(device));
|
fu_backend_device_added(backend, FU_DEVICE(device));
|
||||||
@ -66,8 +83,14 @@ fu_usb_backend_device_removed_cb(GUsbContext *ctx, GUsbDevice *usb_device, FuBac
|
|||||||
/* find the device we enumerated */
|
/* find the device we enumerated */
|
||||||
device_tmp =
|
device_tmp =
|
||||||
fu_backend_lookup_by_id(FU_BACKEND(self), g_usb_device_get_platform_id(usb_device));
|
fu_backend_lookup_by_id(FU_BACKEND(self), g_usb_device_get_platform_id(usb_device));
|
||||||
if (device_tmp != NULL)
|
if (device_tmp != NULL) {
|
||||||
|
if (fu_device_has_flag(device_tmp, FWUPD_DEVICE_FLAG_EMULATED)) {
|
||||||
|
g_debug("ignoring removal of emulated device %s",
|
||||||
|
fu_device_get_id(device_tmp));
|
||||||
|
return;
|
||||||
|
}
|
||||||
fu_backend_device_removed(backend, device_tmp);
|
fu_backend_device_removed(backend, device_tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
9
src/tests/usb-devices-bootloader.json
Normal file
9
src/tests/usb-devices-bootloader.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"UsbDevices": [
|
||||||
|
{
|
||||||
|
"PlatformId": "usb:01:00:06",
|
||||||
|
"IdVendor": 999,
|
||||||
|
"IdProduct": 999
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
9
src/tests/usb-devices-replace.json
Normal file
9
src/tests/usb-devices-replace.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"UsbDevices": [
|
||||||
|
{
|
||||||
|
"PlatformId": "usb:01:00:06",
|
||||||
|
"IdVendor": 10047,
|
||||||
|
"IdProduct": 4100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user