summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2022-09-13 10:49:46 +0100
committerRichard Hughes <richard@hughsie.com>2022-09-13 11:33:50 +0100
commitb56401f4b27f24ebe4a23d54d226558af5f96d26 (patch)
tree4fa2c21aff7b0454555e0a0a24df2bccb713a477
parent81de6a5122ae617d5635576bc37a620f85b1c3be (diff)
downloadgusb-b56401f4b27f24ebe4a23d54d226558af5f96d26.tar.gz
Allow adding tags to the JSON device event
This allows us to see which phase of the emulation should be used.
-rw-r--r--gusb/gusb-device-private.h2
-rw-r--r--gusb/gusb-device.c65
-rw-r--r--gusb/gusb-device.h3
-rw-r--r--gusb/libgusb.ver6
4 files changed, 76 insertions, 0 deletions
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;