mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-04 03:19:02 +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);
|
||||
}
|
||||
|
||||
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:
|
||||
*
|
||||
@ -3174,8 +3200,12 @@ fu_backend_usb_func(gconstpointer user_data)
|
||||
#ifdef HAVE_GUSB
|
||||
FuTest *self = (FuTest *)user_data;
|
||||
gboolean ret;
|
||||
guint cnt_added = 0;
|
||||
guint cnt_removed = 0;
|
||||
FuDevice *device_tmp;
|
||||
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_autoptr(FuBackend) backend = fu_usb_backend_new(self->ctx);
|
||||
g_autoptr(FuDeviceLocker) locker = NULL;
|
||||
@ -3183,33 +3213,37 @@ fu_backend_usb_func(gconstpointer user_data)
|
||||
g_autoptr(GError) error = NULL;
|
||||
g_autoptr(GPtrArray) devices = 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");
|
||||
return;
|
||||
#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 */
|
||||
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_true(fu_backend_get_enabled(backend));
|
||||
ret = fu_backend_setup(backend, progress, &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);
|
||||
gusb_emulate_fn = g_test_build_filename(G_TEST_DIST, "tests", "usb-devices.json", NULL);
|
||||
g_assert_nonnull(gusb_emulate_fn);
|
||||
fu_backend_usb_load_file(backend, gusb_emulate_fn);
|
||||
g_assert_cmpint(cnt_added, ==, 0);
|
||||
g_assert_cmpint(cnt_removed, ==, 0);
|
||||
ret = fu_backend_coldplug(backend, progress, &error);
|
||||
g_assert_no_error(error);
|
||||
g_assert_true(ret);
|
||||
g_assert_cmpint(cnt_added, ==, 1);
|
||||
g_assert_cmpint(cnt_removed, ==, 0);
|
||||
devices = fu_backend_get_devices(backend);
|
||||
g_assert_cmpint(devices->len, ==, 1);
|
||||
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);
|
||||
g_assert_no_error(error);
|
||||
g_assert_nonnull(locker);
|
||||
g_assert_true(fu_device_has_flag(device_tmp, FWUPD_DEVICE_FLAG_EMULATED));
|
||||
|
||||
/* for debugging */
|
||||
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);
|
||||
g_assert_cmpint(possible_plugins->len, ==, 1);
|
||||
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
|
||||
g_test_skip("No GUsb support");
|
||||
#endif
|
||||
|
@ -50,8 +50,25 @@ fu_usb_backend_device_notify_flags_cb(FuDevice *device, GParamSpec *pspec, FuBac
|
||||
static void
|
||||
fu_usb_backend_device_added_cb(GUsbContext *ctx, GUsbDevice *usb_device, FuBackend *backend)
|
||||
{
|
||||
FuDevice *device_tmp;
|
||||
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 */
|
||||
device = fu_usb_device_new(fu_backend_get_context(backend), usb_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 */
|
||||
device_tmp =
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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