Add proper error return code
authorKrzysztof Opasiak <k.opasiak@samsung.com>
Tue, 30 Jun 2015 07:33:52 +0000 (09:33 +0200)
committerStanislaw Wadas <s.wadas@samsung.com>
Wed, 2 Dec 2015 12:45:16 +0000 (13:45 +0100)
Change-Id: Id97901d976b22929192059257709ad889f64123f
Signed-off-by: Stanislaw Wadas <s.wadas@samsung.com>
Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
include/libhusb.h
src/libhusb.c

index 868cee16ebfb5df163db0deb36a0a1993c8280ec..1e739d1e5fb1b1457e3adc2d6b7bc5e3bd82ca58 100644 (file)
@@ -120,6 +120,33 @@ struct libhusb_endpoint_descriptor {
        int extra_length;
 };
 
+enum usb_device_error {
+       LIBHUSB_SUCCESS = 0,
+       LIBHUSB_ERROR_IO = -1,
+       LIBHUSB_ERROR_INVALID_PARAM = -2,
+       LIBHUSB_ERROR_ACCESS = -3,
+       LIBHUSB_ERROR_NO_DEVICE = -4,
+       LIBHUSB_ERROR_NOT_FOUND = -5,
+       LIBHUSB_ERROR_BUSY = -6,
+       LIBHUSB_ERROR_TIMEOUT = -7,
+       LIBHUSB_ERROR_OVERFLOW = -8,
+       LIBHUSB_ERROR_PIPE = -9,
+       LIBHUSB_ERROR_INTERRUPTED = -10,
+       LIBHUSB_ERROR_NO_MEM = -11,
+       LIBHUSB_ERROR_NOT_SUPPORTED = -12,
+       LIBHUSB_ERROR_OTHER = -99,
+};
+
+enum usb_device_transfer_status {
+       LIBHUSB_TRANSFER_COMPLETED,
+       LIBHUSB_TRANSFER_ERROR,
+       LIBHUSB_TRANSFER_TIMED_OUT,
+       LIBHUSB_TRANSFER_CANCELLED,
+       LIBHUSB_TRANSFER_STALL,
+       LIBHUSB_TRANSFER_NO_DEVICE,
+       LIBHUSB_TRANSFER_OVERFLOW,
+};
+
 int libhusb_init(libhusb_context **ctx);
 
 void libhusb_exit(libhusb_context *ctx);
@@ -184,6 +211,8 @@ int libhusb_interrupt_transfer(libhusb_device_handle *handle,
        uint8_t endpoint, unsigned char *data, int length,
        int *actual_length, unsigned int timeout);
 
+const char *libhusb_error_name(int error_code);
+
 #ifdef __cplusplus
 }
 #endif
index ef6344ee908fed144a5eb107a83f15e379ecff9b..0323c6bd0432ab53184ec0f1d70e9d229ee038ac 100644 (file)
@@ -49,27 +49,84 @@ struct libhusb_device_handle {
        unsigned char driver_detached[MAX_NMB_OF_CONFIGS];
 };
 
-/* TODO add error translation */
-/* TODO test sync transfer */
+static int translate_error(int error_code)
+{
+       switch (error_code) {
+       case LIBUSB_ERROR_IO:
+               return LIBHUSB_ERROR_IO;
+       case LIBUSB_ERROR_INVALID_PARAM:
+               return LIBHUSB_ERROR_INVALID_PARAM;
+       case LIBUSB_ERROR_ACCESS:
+               return LIBHUSB_ERROR_ACCESS;
+       case LIBUSB_ERROR_NO_DEVICE:
+               return LIBHUSB_ERROR_NO_DEVICE;
+       case LIBUSB_ERROR_NOT_FOUND:
+               return LIBHUSB_ERROR_NOT_FOUND;
+       case LIBUSB_ERROR_BUSY:
+               return LIBHUSB_ERROR_BUSY;
+       case LIBUSB_ERROR_TIMEOUT:
+               return LIBHUSB_ERROR_TIMEOUT;
+       case LIBUSB_ERROR_OVERFLOW:
+               return LIBHUSB_ERROR_OVERFLOW;
+       case LIBUSB_ERROR_PIPE:
+               return LIBHUSB_ERROR_PIPE;
+       case LIBUSB_ERROR_INTERRUPTED:
+               return LIBHUSB_ERROR_INTERRUPTED;
+       case LIBUSB_ERROR_NO_MEM:
+               return LIBHUSB_ERROR_NO_MEM;
+       case LIBUSB_ERROR_NOT_SUPPORTED:
+               return LIBHUSB_ERROR_NOT_SUPPORTED;
+       case LIBUSB_ERROR_OTHER:
+               return LIBHUSB_ERROR_OTHER;
+       case LIBUSB_TRANSFER_ERROR:
+               return LIBHUSB_TRANSFER_ERROR;
+       case LIBUSB_TRANSFER_TIMED_OUT:
+               return LIBHUSB_TRANSFER_TIMED_OUT;
+       case LIBUSB_TRANSFER_CANCELLED:
+               return LIBHUSB_TRANSFER_CANCELLED;
+       case LIBUSB_TRANSFER_STALL:
+               return LIBHUSB_TRANSFER_STALL;
+       case LIBUSB_TRANSFER_NO_DEVICE:
+               return LIBHUSB_TRANSFER_NO_DEVICE;
+       case LIBUSB_TRANSFER_OVERFLOW:
+               return LIBHUSB_TRANSFER_OVERFLOW;
+
+       case 0:
+               return LIBHUSB_SUCCESS;
+       default:
+               return LIBHUSB_ERROR_OTHER;
+       }
+}
 
 int libhusb_init(libhusb_context **ctx)
 {
-       int ret;
+       int ret = LIBHUSB_ERROR_NO_MEM;
        int count = 10;
        struct libhusb_context *_ctx;
 
        assert(ctx);
 
        _ctx = malloc(sizeof(*_ctx));
+       if (!_ctx)
+               goto out;
 
        do {
                ret = libusb_init(&(_ctx->lusb_ctx));
                count--;
-       } while (ret == -99 && count > 0);
+       } while (ret == LIBUSB_ERROR_OTHER && count > 0);
+
+       if (ret < 0)
+               goto free_ctx;
 
        *ctx = _ctx;
 
        return ret;
+
+free_ctx:
+       free(_ctx);
+       ret = translate_error(ret);
+out:
+       return ret;
 }
 
 void libhusb_exit(libhusb_context *context)
@@ -147,6 +204,7 @@ ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs)
 {
        ssize_t len;
        int i = 0;
+       int ret = LIBHUSB_ERROR_NO_MEM;
        libusb_device **lusb_list = NULL;
        struct libhusb_device *rdevice;
        struct libhusb_device **list;
@@ -155,8 +213,10 @@ ssize_t libhusb_get_devices(libhusb_context *context, libhusb_device ***devs)
        assert(devs);
 
        len = libusb_get_device_list(context->lusb_ctx, &lusb_list);
-       if (len < 0)
-               return -1;
+       if (len < 0) {
+               ret = translate_error(len);
+               goto out;
+       }
 
        list = calloc(len + 1, sizeof(*list));
        if (!list)
@@ -183,8 +243,8 @@ free_dev_list:
        free(list);
 free_lusb_list:
        libusb_free_device_list(lusb_list, 1);
-
-       return -99; /* TODO  replace with propper error*/
+out:
+       return ret;
 }
 
 libhusb_device *libhusb_ref_device(libhusb_device *dev)
@@ -220,7 +280,7 @@ int libhusb_get_max_packet_size(libhusb_device *dev, uint8_t endpoint)
 
        ret = libusb_get_max_iso_packet_size(dev->lusb_dev, endpoint);
        if (ret < 0)
-               ret = -99;
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -232,6 +292,8 @@ int libhusb_get_active_config(libhusb_device_handle *handle, int *config)
        assert(handle);
 
        ret = libusb_get_configuration(handle->lusb_dev_handle, config);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -243,6 +305,8 @@ int libhusb_set_config(libhusb_device_handle *handle, int configuration)
        assert(handle);
 
        ret = libusb_set_configuration(handle->lusb_dev_handle, configuration);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -250,7 +314,7 @@ int libhusb_set_config(libhusb_device_handle *handle, int configuration)
 int libhusb_claim_interface(libhusb_device_handle *handle, int interface_number,
                            int force)
 {
-       int ret = -1;
+       int ret = LIBHUSB_ERROR_INVALID_PARAM;
        int driver_detached = 0;
 
        assert(handle);
@@ -267,20 +331,25 @@ int libhusb_claim_interface(libhusb_device_handle *handle, int interface_number,
        ret = libusb_kernel_driver_active(handle->lusb_dev_handle,
                                          interface_number);
        if (ret < 0) {
+               ret = translate_error(ret);
                goto out;
        } else if (ret == 1) {
                ret = libusb_detach_kernel_driver(handle->lusb_dev_handle,
                                                  interface_number);
-               if (ret < 0)
+               if (ret < 0) {
+                       ret = translate_error(ret);
                        goto out;
+               }
 
                driver_detached = 1;
        }
 
 claim_interface:
        ret = libusb_claim_interface(handle->lusb_dev_handle, interface_number);
-       if (ret < 0)
+       if (ret < 0) {
+               ret = translate_error(ret);
                goto claim_failed;
+       }
 
        handle->driver_detached[interface_number] = 1;
 
@@ -291,13 +360,12 @@ claim_failed:
                libusb_attach_kernel_driver(handle->lusb_dev_handle,
                                            interface_number);
 out:
-       /* Add proper error handling */
        return ret;
 }
 
 int libhusb_release_interface(libhusb_device_handle *handle, int interface_number)
 {
-       int ret = -1;
+       int ret = LIBHUSB_ERROR_INVALID_PARAM;
 
        assert(handle);
 
@@ -306,8 +374,10 @@ int libhusb_release_interface(libhusb_device_handle *handle, int interface_numbe
 
        ret = libusb_release_interface(handle->lusb_dev_handle,
                                       interface_number);
-       if (ret != 0)
+       if (ret != 0) {
+               ret = translate_error(ret);
                goto out;
+       }
 
        if (handle->driver_detached[interface_number]) {
                /*
@@ -330,6 +400,8 @@ int libhusb_clear_halt(libhusb_device_handle *handle, uint8_t endpoint)
        assert(handle);
 
        ret = libusb_clear_halt(handle->lusb_dev_handle, endpoint);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -341,6 +413,8 @@ int libhusb_reset_device(libhusb_device_handle *handle)
        assert(handle);
 
        ret = libusb_reset_device(handle->lusb_dev_handle);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -352,6 +426,8 @@ int libhusb_kernel_driver_active(libhusb_device_handle *handle, int interface_nu
        assert(handle);
 
        ret = libusb_kernel_driver_active(handle->lusb_dev_handle, interface_number);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -363,6 +439,8 @@ int libhusb_detach_kernel_driver(libhusb_device_handle *handle, int interface_nu
        assert(handle);
 
        ret = libusb_detach_kernel_driver(handle->lusb_dev_handle, interface_number);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -374,6 +452,8 @@ int libhusb_attach_kernel_driver(libhusb_device_handle *handle, int interface_nu
        assert(handle);
 
        ret = libusb_attach_kernel_driver(handle->lusb_dev_handle, interface_number);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -387,6 +467,9 @@ int libhusb_get_device_descriptor(libhusb_device *dev, struct libhusb_device_des
        descriptor = libusb_get_device_descriptor(dev->lusb_dev,
                                                 (struct libusb_device_descriptor *)desc);
 
+       if (descriptor < 0)
+               descriptor = translate_error(descriptor);
+
        return descriptor;
 }
 
@@ -413,6 +496,8 @@ int libhusb_get_string_descriptor_ascii(libhusb_device_handle *handle,
        assert(handle);
 
        ret = libusb_get_string_descriptor_ascii(handle->lusb_dev_handle, desc_index, data, length);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -427,6 +512,8 @@ int libhusb_control_transfer(libhusb_device_handle *handle, uint8_t request_type
 
        ret = libusb_control_transfer(handle->lusb_dev_handle, request_type, bRequest,
                                       wValue, wIndex, data, wLength, timeout);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -441,6 +528,8 @@ int libhusb_bulk_transfer(libhusb_device_handle *handle, uint8_t endpoint,
 
        ret = libusb_bulk_transfer(handle->lusb_dev_handle, endpoint, data, length,
                                   actual_length, timeout);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
@@ -455,6 +544,58 @@ int libhusb_interrupt_transfer(libhusb_device_handle *handle,
 
        ret = libusb_interrupt_transfer(handle->lusb_dev_handle, endpoint, data, length,
                                        actual_length, timeout);
+       if (ret < 0)
+               ret = translate_error(ret);
 
        return ret;
 }
+
+const char *libhusb_error_name(int error_code)
+{
+       switch (error_code) {
+       case LIBHUSB_ERROR_IO:
+               return "LIBHUSB_ERROR_IO";
+       case LIBHUSB_ERROR_INVALID_PARAM:
+               return "LIBHUSB_ERROR_INVALID_PARAM";
+       case LIBHUSB_ERROR_ACCESS:
+               return "LIBHUSB_ERROR_ACCESS";
+       case LIBHUSB_ERROR_NO_DEVICE:
+               return "LIBHUSB_ERROR_NO_DEVICE";
+       case LIBHUSB_ERROR_NOT_FOUND:
+               return "LIBHUSB_ERROR_NOT_FOUND";
+       case LIBHUSB_ERROR_BUSY:
+               return "LIBHUSB_ERROR_BUSY";
+       case LIBHUSB_ERROR_TIMEOUT:
+               return "LIBHUSB_ERROR_TIMEOUT";
+       case LIBHUSB_ERROR_OVERFLOW:
+               return "LIBHUSB_ERROR_OVERFLOW";
+       case LIBHUSB_ERROR_PIPE:
+               return "LIBHUSB_ERROR_PIPE";
+       case LIBHUSB_ERROR_INTERRUPTED:
+               return "LIBHUSB_ERROR_INTERRUPTED";
+       case LIBHUSB_ERROR_NO_MEM:
+               return "LIBHUSB_ERROR_NO_MEM";
+       case LIBHUSB_ERROR_NOT_SUPPORTED:
+               return "LIBHUSB_ERROR_NOT_SUPPORTED";
+       case LIBHUSB_ERROR_OTHER:
+               return "LIBHUSB_ERROR_OTHER";
+       case LIBHUSB_TRANSFER_ERROR:
+               return "LIBHUSB_TRANSFER_ERROR";
+       case LIBHUSB_TRANSFER_TIMED_OUT:
+               return "LIBHUSB_TRANSFER_TIMED_OUT";
+       case LIBHUSB_TRANSFER_CANCELLED:
+               return "LIBHUSB_TRANSFER_CANCELLED";
+       case LIBHUSB_TRANSFER_STALL:
+               return "LIBHUSB_TRANSFER_STALL";
+       case LIBHUSB_TRANSFER_NO_DEVICE:
+               return "LIBHUSB_TRANSFER_NO_DEVICE";
+       case LIBHUSB_TRANSFER_OVERFLOW:
+               return "LIBHUSB_TRANSFER_OVERFLOW";
+
+       case 0:
+               return "LIBHUSB_SUCCESS / LIBHUSB_TRANSFER_COMPLETED";
+       default:
+               return "LIBHUSB_ERROR_OTHER";
+       }
+}
+