From b56401f4b27f24ebe4a23d54d226558af5f96d26 Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Tue, 13 Sep 2022 10:49:46 +0100 Subject: Allow adding tags to the JSON device event This allows us to see which phase of the emulation should be used. --- gusb/gusb-device-private.h | 2 ++ gusb/gusb-device.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++ gusb/gusb-device.h | 3 +++ gusb/libgusb.ver | 6 +++++ 4 files changed, 76 insertions(+) diff --git a/gusb/gusb-device-private.h b/gusb/gusb-device-private.h index 70218b2..e772c9e 100644 --- a/gusb/gusb-device-private.h +++ b/gusb/gusb-device-private.h @@ -22,5 +22,7 @@ libusb_device * _g_usb_device_get_device(GUsbDevice *self); gboolean _g_usb_device_open_internal(GUsbDevice *self, GError **error); +gboolean +_g_usb_device_has_tag(GUsbDevice *self, const gchar *tag); G_END_DECLS diff --git a/gusb/gusb-device.c b/gusb/gusb-device.c index 86cb8cd..b3b3efd 100644 --- a/gusb/gusb-device.c +++ b/gusb/gusb-device.c @@ -42,6 +42,7 @@ typedef struct { GPtrArray *interfaces; /* of GUsbInterface */ GPtrArray *bos_descriptors; /* of GUsbBosDescriptor */ GPtrArray *events; /* of GUsbDeviceEvent */ + GPtrArray *tags; /* of utf-8 */ guint event_idx; GDateTime *created; } GUsbDevicePrivate; @@ -87,6 +88,7 @@ g_usb_device_finalize(GObject *object) g_ptr_array_unref(priv->interfaces); g_ptr_array_unref(priv->bos_descriptors); g_ptr_array_unref(priv->events); + g_ptr_array_unref(priv->tags); G_OBJECT_CLASS(g_usb_device_parent_class)->finalize(object); } @@ -217,6 +219,7 @@ g_usb_device_init(GUsbDevice *self) priv->interfaces = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref); priv->bos_descriptors = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref); priv->events = g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref); + priv->tags = g_ptr_array_new_with_free_func(g_free); } gboolean @@ -302,6 +305,17 @@ _g_usb_device_load(GUsbDevice *self, JsonObject *json_object, GError **error) } } + /* array of tags */ + if (json_object_has_member(json_object, "Tags")) { + JsonArray *json_array = json_object_get_array_member(json_object, "Tags"); + for (guint i = 0; i < json_array_get_length(json_array); i++) { + JsonNode *node_tmp = json_array_get_element(json_array, i); + const gchar *str = json_node_get_string(node_tmp); + if (str != NULL && str[0] != '\0') + g_ptr_array_add(priv->tags, g_strdup(str)); + } + } + /* success */ priv->interfaces_valid = TRUE; priv->bos_descriptors_valid = TRUE; @@ -337,6 +351,15 @@ _g_usb_device_save(GUsbDevice *self, JsonBuilder *json_builder, GError **error) json_builder_add_string_value(json_builder, str); } #endif + if (priv->tags->len > 0) { + json_builder_set_member_name(json_builder, "Tags"); + json_builder_begin_array(json_builder); + for (guint i = 0; i < priv->tags->len; i++) { + const gchar *tag = g_ptr_array_index(priv->tags, i); + json_builder_add_string_value(json_builder, tag); + } + json_builder_end_array(json_builder); + } if (priv->desc.idVendor != 0) { json_builder_set_member_name(json_builder, "IdVendor"); json_builder_add_int_value(json_builder, priv->desc.idVendor); @@ -425,6 +448,48 @@ _g_usb_device_save(GUsbDevice *self, JsonBuilder *json_builder, GError **error) return TRUE; } +gboolean +_g_usb_device_has_tag(GUsbDevice *self, const gchar *tag) +{ + GUsbDevicePrivate *priv = GET_PRIVATE(self); + + g_return_val_if_fail(G_USB_IS_DEVICE(self), FALSE); + g_return_val_if_fail(tag != NULL, FALSE); + + for (guint i = 0; i < priv->tags->len; i++) { + const gchar *tag_tmp = g_ptr_array_index(priv->tags, i); + if (g_strcmp0(tag_tmp, tag) == 0) + return TRUE; + } + return FALSE; +} + +/** + * g_usb_device_add_tag: + * @self: a #FuDevice + * @tag: a tag, for example `bootloader` or `runtime-reload` + * + * Adds a tag, which is included in the JSON log to identify the specific device. + * + * For instance, there might be a pre-update runtime, a bootloader and a post-update runtime + * and allowing tags to be saved to the backend object allows us to identify each version of + * the same physical device. + * + * Since: 0.4.1 + **/ +void +g_usb_device_add_tag(GUsbDevice *self, const gchar *tag) +{ + GUsbDevicePrivate *priv = GET_PRIVATE(self); + + g_return_if_fail(G_USB_IS_DEVICE(self)); + g_return_if_fail(tag != NULL); + + if (_g_usb_device_has_tag(self, tag)) + return; + g_ptr_array_add(priv->tags, g_strdup(tag)); +} + /* not defined in FreeBSD */ #ifndef HAVE_LIBUSB_GET_PARENT static libusb_device * diff --git a/gusb/gusb-device.h b/gusb/gusb-device.h index 4488653..850fc8d 100644 --- a/gusb/gusb-device.h +++ b/gusb/gusb-device.h @@ -170,6 +170,9 @@ g_usb_device_get_device_subclass(GUsbDevice *self); guint8 g_usb_device_get_device_protocol(GUsbDevice *self); +void +g_usb_device_add_tag(GUsbDevice *self, const gchar *tag); + guint8 g_usb_device_get_configuration_index(GUsbDevice *self); guint8 diff --git a/gusb/libgusb.ver b/gusb/libgusb.ver index 9977a36..061ac44 100644 --- a/gusb/libgusb.ver +++ b/gusb/libgusb.ver @@ -185,3 +185,9 @@ LIBGUSB_0.4.0 { g_usb_device_invalidate; local: *; } LIBGUSB_0.3.10; + +LIBGUSB_0.4.1 { + global: + g_usb_device_add_tag; + local: *; +} LIBGUSB_0.4.0; -- cgit v1.2.1