summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2022-09-10 14:00:19 +0100
committerRichard Hughes <richard@hughsie.com>2022-09-12 11:22:40 +0100
commit1affb32b667d1d16ab6eafb3303d72cb07774c71 (patch)
tree87500da0e0362e957f66cbb13fae13b5752a755a
parent0f605ed23f2f9ea5c2ac28cc772f1e781ffa08ba (diff)
downloadgusb-1affb32b667d1d16ab6eafb3303d72cb07774c71.tar.gz
Allow emulating failed events
This is required to emulate devices that just reset (without completing the current transfer) when asked to reset.
-rw-r--r--gusb/gusb-device-event-private.h2
-rw-r--r--gusb/gusb-device-event.c41
-rw-r--r--gusb/gusb-device-event.h2
-rw-r--r--gusb/gusb-device.c34
-rw-r--r--gusb/libgusb.ver1
5 files changed, 80 insertions, 0 deletions
diff --git a/gusb/gusb-device-event-private.h b/gusb/gusb-device-event-private.h
index 0e78cff..5bd8616 100644
--- a/gusb/gusb-device-event-private.h
+++ b/gusb/gusb-device-event-private.h
@@ -17,6 +17,8 @@ GUsbDeviceEvent *
_g_usb_device_event_new(const gchar *id);
void
_g_usb_device_event_set_bytes_raw(GUsbDeviceEvent *self, gconstpointer buf, gsize bufsz);
+void
+_g_usb_device_event_set_status(GUsbDeviceEvent *self, gint status);
gboolean
_g_usb_device_event_load(GUsbDeviceEvent *self, JsonObject *json_object, GError **error);
diff --git a/gusb/gusb-device-event.c b/gusb/gusb-device-event.c
index 4f38131..d268807 100644
--- a/gusb/gusb-device-event.c
+++ b/gusb/gusb-device-event.c
@@ -17,6 +17,7 @@
struct _GUsbDeviceEvent {
GObject parent_instance;
gchar *id;
+ gint status;
GBytes *bytes;
};
@@ -58,6 +59,9 @@ _g_usb_device_event_load(GUsbDeviceEvent *self, JsonObject *json_object, GError
#if JSON_CHECK_VERSION(1, 6, 0)
/* optional properties */
self->id = g_strdup(json_object_get_string_member_with_default(json_object, "Id", NULL));
+ self->status = json_object_get_int_member_with_default(json_object,
+ "Status",
+ LIBUSB_TRANSFER_COMPLETED);
/* extra data */
str = json_object_get_string_member_with_default(json_object, "Data", NULL);
@@ -92,6 +96,10 @@ _g_usb_device_event_save(GUsbDeviceEvent *self, JsonBuilder *json_builder, GErro
json_builder_set_member_name(json_builder, "Id");
json_builder_add_string_value(json_builder, self->id);
}
+ if (self->status != LIBUSB_TRANSFER_COMPLETED) {
+ json_builder_set_member_name(json_builder, "Status");
+ json_builder_add_int_value(json_builder, self->status);
+ }
if (self->bytes != NULL) {
g_autofree gchar *str = g_base64_encode(g_bytes_get_data(self->bytes, NULL),
g_bytes_get_size(self->bytes));
@@ -139,6 +147,39 @@ g_usb_device_event_get_id(GUsbDeviceEvent *self)
}
/**
+ * g_usb_device_event_get_status:
+ * @self: a #GUsbDeviceEvent
+ *
+ * Gets any status data from the event.
+ *
+ * Return value: (transfer none): a `enum libusb_transfer_status`, or -1 for failure
+ *
+ * Since: 0.4.0
+ **/
+gint
+g_usb_device_event_get_status(GUsbDeviceEvent *self)
+{
+ g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), -1);
+ return self->status;
+}
+
+/**
+ * _g_usb_device_event_set_status:
+ * @self: a #GUsbDeviceEvent
+ * @status: `enum libusb_transfer_status`
+ *
+ * Set the status of the event, e.g. `LIBUSB_TRANSFER_COMPLETED`.
+ *
+ * Since: 0.4.0
+ **/
+void
+_g_usb_device_event_set_status(GUsbDeviceEvent *self, gint status)
+{
+ g_return_if_fail(G_USB_IS_DEVICE_EVENT(self));
+ self->status = status;
+}
+
+/**
* g_usb_device_event_get_bytes:
* @self: a #GUsbDeviceEvent
*
diff --git a/gusb/gusb-device-event.h b/gusb/gusb-device-event.h
index f44db43..c9e48a9 100644
--- a/gusb/gusb-device-event.h
+++ b/gusb/gusb-device-event.h
@@ -18,6 +18,8 @@ const gchar *
g_usb_device_event_get_id(GUsbDeviceEvent *self);
GBytes *
g_usb_device_event_get_bytes(GUsbDeviceEvent *self);
+gint
+g_usb_device_event_get_status(GUsbDeviceEvent *self);
void
g_usb_device_event_set_bytes(GUsbDeviceEvent *self, GBytes *bytes);
diff --git a/gusb/gusb-device.c b/gusb/gusb-device.c
index 0458451..f1135c8 100644
--- a/gusb/gusb-device.c
+++ b/gusb/gusb-device.c
@@ -1836,6 +1836,8 @@ g_usb_device_async_transfer_cb(struct libusb_transfer *transfer)
/* did request fail? */
ret = g_usb_device_libusb_status_to_gerror(transfer->status, &error);
if (!ret) {
+ if (req->event != NULL)
+ _g_usb_device_event_set_status(req->event, transfer->status);
g_task_return_error(task, error);
} else {
if (req->event != NULL) {
@@ -1866,6 +1868,8 @@ g_usb_device_control_transfer_cb(struct libusb_transfer *transfer)
/* did request fail? */
ret = g_usb_device_libusb_status_to_gerror(transfer->status, &error);
if (!ret) {
+ if (req->event != NULL)
+ _g_usb_device_event_set_status(req->event, transfer->status);
g_task_return_error(task, error);
} else {
memmove(req->data,
@@ -1988,6 +1992,16 @@ g_usb_device_control_transfer_async(GUsbDevice *self,
event_id);
return;
}
+ if (g_usb_device_event_get_status(event) != LIBUSB_TRANSFER_COMPLETED) {
+ g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event),
+ &error);
+ g_task_report_error(self,
+ callback,
+ user_data,
+ g_usb_device_control_transfer_async,
+ error);
+ return;
+ }
bytes = g_usb_device_event_get_bytes(event);
if (bytes == NULL) {
g_task_report_new_error(self,
@@ -2165,6 +2179,16 @@ g_usb_device_bulk_transfer_async(GUsbDevice *self,
event_id);
return;
}
+ if (g_usb_device_event_get_status(event) != LIBUSB_TRANSFER_COMPLETED) {
+ g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event),
+ &error);
+ g_task_report_error(self,
+ callback,
+ user_data,
+ g_usb_device_control_transfer_async,
+ error);
+ return;
+ }
bytes = g_usb_device_event_get_bytes(event);
if (bytes == NULL) {
g_task_report_new_error(self,
@@ -2331,6 +2355,16 @@ g_usb_device_interrupt_transfer_async(GUsbDevice *self,
event_id);
return;
}
+ if (g_usb_device_event_get_status(event) != LIBUSB_TRANSFER_COMPLETED) {
+ g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event),
+ &error);
+ g_task_report_error(self,
+ callback,
+ user_data,
+ g_usb_device_control_transfer_async,
+ error);
+ return;
+ }
bytes = g_usb_device_event_get_bytes(event);
if (bytes == NULL) {
g_task_report_new_error(self,
diff --git a/gusb/libgusb.ver b/gusb/libgusb.ver
index fbe7890..9977a36 100644
--- a/gusb/libgusb.ver
+++ b/gusb/libgusb.ver
@@ -176,6 +176,7 @@ LIBGUSB_0.4.0 {
g_usb_context_save;
g_usb_device_event_get_bytes;
g_usb_device_event_get_id;
+ g_usb_device_event_get_status;
g_usb_device_event_get_type;
g_usb_device_event_set_bytes;
g_usb_device_get_bos_descriptor;