From 4db790b78afc0642be95416cccba9c05b7ca5c5a Mon Sep 17 00:00:00 2001 From: Richard Hughes Date: Wed, 1 Feb 2023 14:33:27 +0000 Subject: Save the libusb error if libusb_submit_transfer() fails If the return code is LIBUSB_ERROR_NO_DEVICE we want to record that. --- gusb/gusb-context.c | 3 ++- gusb/gusb-device-event-private.h | 2 ++ gusb/gusb-device-event.c | 40 ++++++++++++++++++++++++++++++++++++++ gusb/gusb-device-event.h | 2 ++ gusb/gusb-device.c | 42 +++++++++++++++++++++++++++++++--------- gusb/libgusb.ver | 1 + 6 files changed, 80 insertions(+), 10 deletions(-) diff --git a/gusb/gusb-context.c b/gusb/gusb-context.c index b233209..f8ec3cf 100644 --- a/gusb/gusb-context.c +++ b/gusb/gusb-context.c @@ -401,7 +401,8 @@ g_usb_context_load_with_tag(GUsbContext *self, { GUsbContextPrivate *priv = GET_PRIVATE(self); JsonArray *json_array; - g_autoptr(GPtrArray) devices_to_remove = g_ptr_array_new_with_free_func((GDestroyNotify) g_object_unref); + g_autoptr(GPtrArray) devices_to_remove = + g_ptr_array_new_with_free_func((GDestroyNotify)g_object_unref); g_return_val_if_fail(G_USB_IS_CONTEXT(self), FALSE); g_return_val_if_fail(json_object != NULL, FALSE); diff --git a/gusb/gusb-device-event-private.h b/gusb/gusb-device-event-private.h index 5bd8616..4d4551a 100644 --- a/gusb/gusb-device-event-private.h +++ b/gusb/gusb-device-event-private.h @@ -19,6 +19,8 @@ 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); +void +_g_usb_device_event_set_rc(GUsbDeviceEvent *self, gint rc); 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 0d9eb2e..648dbe2 100644 --- a/gusb/gusb-device-event.c +++ b/gusb/gusb-device-event.c @@ -18,6 +18,7 @@ struct _GUsbDeviceEvent { GObject parent_instance; gchar *id; gint status; + gint rc; GBytes *bytes; }; @@ -62,6 +63,7 @@ _g_usb_device_event_load(GUsbDeviceEvent *self, JsonObject *json_object, GError self->status = json_object_get_int_member_with_default(json_object, "Status", LIBUSB_TRANSFER_COMPLETED); + self->rc = json_object_get_int_member_with_default(json_object, "Error", LIBUSB_SUCCESS); /* extra data */ str = json_object_get_string_member_with_default(json_object, "Data", NULL); @@ -100,6 +102,10 @@ _g_usb_device_event_save(GUsbDeviceEvent *self, JsonBuilder *json_builder, GErro json_builder_set_member_name(json_builder, "Status"); json_builder_add_int_value(json_builder, self->status); } + if (self->rc != LIBUSB_SUCCESS) { + json_builder_set_member_name(json_builder, "Error"); + json_builder_add_int_value(json_builder, self->rc); + } if (self->bytes != NULL) { g_autofree gchar *str = g_base64_encode(g_bytes_get_data(self->bytes, NULL), g_bytes_get_size(self->bytes)); @@ -179,6 +185,40 @@ _g_usb_device_event_set_status(GUsbDeviceEvent *self, gint status) self->status = status; } +/** + * g_usb_device_event_get_rc: + * @self: a #GUsbDeviceEvent + * + * Gets any return code from the event. + * + * Return value: a `enum libusb_error` + * + * Since: 0.4.5 + **/ +gint +g_usb_device_event_get_rc(GUsbDeviceEvent *self) +{ + g_return_val_if_fail(G_USB_IS_DEVICE_EVENT(self), LIBUSB_ERROR_OTHER); + return self->rc; +} + +/** + * _g_usb_device_event_set_rc: + * @self: a #GUsbDeviceEvent + * @status: `enum libusb_error` + * + * Set the return code of the event, e.g. `LIBUSB_ERROR_TIMEOUT`. + * + * Since: 0.4.5 + **/ +void +_g_usb_device_event_set_rc(GUsbDeviceEvent *self, gint rc) +{ + g_return_if_fail(G_USB_IS_DEVICE_EVENT(self)); + g_return_if_fail(rc <= 0); + self->rc = rc; +} + /** * g_usb_device_event_get_bytes: * @self: a #GUsbDeviceEvent diff --git a/gusb/gusb-device-event.h b/gusb/gusb-device-event.h index c9e48a9..73ba808 100644 --- a/gusb/gusb-device-event.h +++ b/gusb/gusb-device-event.h @@ -20,6 +20,8 @@ GBytes * g_usb_device_event_get_bytes(GUsbDeviceEvent *self); gint g_usb_device_event_get_status(GUsbDeviceEvent *self); +gint +g_usb_device_event_get_rc(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 69901b6..60c70c1 100644 --- a/gusb/gusb-device.c +++ b/gusb/gusb-device.c @@ -959,6 +959,10 @@ g_usb_device_get_custom_index(GUsbDevice *self, event_id); return 0x00; } + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + error)) + return 0x00; bytes = g_usb_device_event_get_bytes(event); if (bytes == NULL || g_bytes_get_size(bytes) != 1) { g_set_error(error, @@ -1611,6 +1615,10 @@ g_usb_device_get_string_descriptor(GUsbDevice *self, guint8 desc_index, GError * event_id); return NULL; } + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + error)) + return NULL; bytes = g_usb_device_event_get_bytes(event); if (bytes == NULL) { g_set_error(error, @@ -1694,6 +1702,10 @@ g_usb_device_get_string_descriptor_bytes_full(GUsbDevice *self, event_id); return NULL; } + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + error)) + return 0x00; bytes = g_usb_device_event_get_bytes(event); if (bytes == NULL) { g_set_error(error, @@ -2199,9 +2211,11 @@ 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); + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + &error) || + !g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event), + &error)) { g_task_report_error(self, callback, user_data, @@ -2283,6 +2297,8 @@ g_usb_device_control_transfer_async(GUsbDevice *self, /* submit transfer */ rc = libusb_submit_transfer(req->transfer); if (rc < 0) { + if (event != NULL) + _g_usb_device_event_set_rc(event, rc); g_usb_device_libusb_error_to_gerror(self, rc, &error); g_task_return_error(task, error); g_object_unref(task); @@ -2386,9 +2402,11 @@ 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); + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + &error) || + !g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event), + &error)) { g_task_report_error(self, callback, user_data, @@ -2459,6 +2477,8 @@ g_usb_device_bulk_transfer_async(GUsbDevice *self, /* submit transfer */ rc = libusb_submit_transfer(req->transfer); if (rc < 0) { + if (event != NULL) + _g_usb_device_event_set_rc(event, rc); g_usb_device_libusb_error_to_gerror(self, rc, &error); g_task_return_error(task, error); g_object_unref(task); @@ -2562,9 +2582,11 @@ 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); + if (!g_usb_device_libusb_error_to_gerror(self, + g_usb_device_event_get_rc(event), + &error) || + !g_usb_device_libusb_status_to_gerror(g_usb_device_event_get_status(event), + &error)) { g_task_report_error(self, callback, user_data, @@ -2635,6 +2657,8 @@ g_usb_device_interrupt_transfer_async(GUsbDevice *self, /* submit transfer */ rc = libusb_submit_transfer(req->transfer); if (rc < 0) { + if (event != NULL) + _g_usb_device_event_set_rc(event, rc); g_usb_device_libusb_error_to_gerror(self, rc, &error); g_task_return_error(task, error); g_object_unref(task); diff --git a/gusb/libgusb.ver b/gusb/libgusb.ver index 50165b1..c2c7fbb 100644 --- a/gusb/libgusb.ver +++ b/gusb/libgusb.ver @@ -211,6 +211,7 @@ LIBGUSB_0.4.4 { LIBGUSB_0.4.5 { global: + g_usb_device_event_get_rc; g_usb_device_get_created; local: *; } LIBGUSB_0.4.4; -- cgit v1.2.1