summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2023-02-01 14:33:27 +0000
committerRichard Hughes <richard@hughsie.com>2023-02-01 16:24:02 +0000
commit4db790b78afc0642be95416cccba9c05b7ca5c5a (patch)
tree47e4caebdb110c869cd7f26398e0ebced7a90d22
parente62f8f76d0bbf755ed5d90f44c10ae8f58605202 (diff)
downloadgusb-4db790b78afc0642be95416cccba9c05b7ca5c5a.tar.gz
Save the libusb error if libusb_submit_transfer() fails
If the return code is LIBUSB_ERROR_NO_DEVICE we want to record that.
-rw-r--r--gusb/gusb-context.c3
-rw-r--r--gusb/gusb-device-event-private.h2
-rw-r--r--gusb/gusb-device-event.c40
-rw-r--r--gusb/gusb-device-event.h2
-rw-r--r--gusb/gusb-device.c42
-rw-r--r--gusb/libgusb.ver1
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));
@@ -180,6 +186,40 @@ _g_usb_device_event_set_status(GUsbDeviceEvent *self, gint 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;