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);
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
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)
{
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;
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)
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)
ret = libusb_get_max_iso_packet_size(dev->lusb_dev, endpoint);
if (ret < 0)
- ret = -99;
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_get_configuration(handle->lusb_dev_handle, config);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_set_configuration(handle->lusb_dev_handle, configuration);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
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);
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;
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);
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]) {
/*
assert(handle);
ret = libusb_clear_halt(handle->lusb_dev_handle, endpoint);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_reset_device(handle->lusb_dev_handle);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_kernel_driver_active(handle->lusb_dev_handle, interface_number);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_detach_kernel_driver(handle->lusb_dev_handle, interface_number);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
assert(handle);
ret = libusb_attach_kernel_driver(handle->lusb_dev_handle, interface_number);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
descriptor = libusb_get_device_descriptor(dev->lusb_dev,
(struct libusb_device_descriptor *)desc);
+ if (descriptor < 0)
+ descriptor = translate_error(descriptor);
+
return descriptor;
}
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;
}
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;
}
ret = libusb_bulk_transfer(handle->lusb_dev_handle, endpoint, data, length,
actual_length, timeout);
+ if (ret < 0)
+ ret = translate_error(ret);
return ret;
}
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";
+ }
+}
+