libhusb_free_config_descriptor(config);
}
+static void transfer_cb(int status, unsigned char *buffer, int len, void *user_data)
+{
+ fail_msg("This function should never be called directly, libusb does it for us");
+}
+
+static void init_transfer(struct libusb_transfer *lusb_transfer,
+ struct libhusb_transfer **transfer, libusb_device_handle *handle)
+{
+ int ret;
+ struct libusb_transfer *ret_transfer;
+
+ ret_transfer = malloc(sizeof(struct libusb_transfer));
+
+ expect_value(libusb_alloc_transfer, iso_packets, 0);
+ will_return(libusb_alloc_transfer, ret_transfer);
+ ret = libhusb_create_transfer(transfer, 0);
+ assert_return_code(ret, 0);
+
+ lusb_transfer->endpoint = rand();
+ lusb_transfer->length = rand();
+ lusb_transfer->timeout = rand();
+ lusb_transfer->dev_handle = handle;
+ lusb_transfer->status = 0;
+ lusb_transfer->actual_length = rand();
+ lusb_transfer->num_iso_packets = 0;
+}
+
+static void test_fill_interrupt_transfer(void **state)
+{
+ struct libusb_transfer lusb_transfer;
+ libhusb_transfer *transfer;
+ libhusb_device_handle *dev_handle;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ init_transfer(&lusb_transfer, &transfer, dev_handle->lusb_dev_handle);
+
+ /* libusb fill functions are inline, we don't mock them, just check the result */
+ libhusb_fill_interrupt_transfer(transfer, dev_handle, transfer_cb, lusb_transfer.endpoint,
+ lusb_transfer.buffer, lusb_transfer.length, NULL, lusb_transfer.timeout);
+ assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
+ assert_int_equal(transfer->lusb_transfer->endpoint, lusb_transfer.endpoint);
+ assert_int_equal(transfer->lusb_transfer->length, lusb_transfer.length);
+ assert_int_equal(transfer->lusb_transfer->timeout, lusb_transfer.timeout);
+ assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_INTERRUPT);
+}
+
+static void test_fill_bulk_transfer(void **state)
+{
+ struct libusb_transfer lusb_transfer;
+ libhusb_transfer *transfer;
+ libhusb_device_handle *dev_handle;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ init_transfer(&lusb_transfer, &transfer, dev_handle->lusb_dev_handle);
+
+ /* libusb fill functions are inline, we don't mock them, just check the result */
+ libhusb_fill_bulk_transfer(transfer, dev_handle, transfer_cb, lusb_transfer.endpoint,
+ lusb_transfer.buffer, lusb_transfer.length, NULL, lusb_transfer.timeout);
+ assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
+ assert_int_equal(transfer->lusb_transfer->endpoint, lusb_transfer.endpoint);
+ assert_int_equal(transfer->lusb_transfer->length, lusb_transfer.length);
+ assert_int_equal(transfer->lusb_transfer->timeout, lusb_transfer.timeout);
+ assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_BULK);
+}
+
+static void test_fill_control_transfer(void **state)
+{
+ libhusb_transfer *transfer;
+ libhusb_device_handle *dev_handle;
+ struct libusb_transfer lusb_transfer;
+ int timeout;
+ uint8_t bmRequestType, bRequest;
+ uint16_t wValue, wIndex, wLength;
+ char buffer[16];
+ int ret;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ expect_value(libusb_alloc_transfer, iso_packets, 0);
+ will_return(libusb_alloc_transfer, &lusb_transfer);
+ ret = libhusb_create_transfer(&transfer, 0);
+ assert_return_code(ret, 0);
+
+ timeout = rand();
+ bmRequestType = rand();
+ bRequest = rand();
+ wValue = rand();
+ wIndex = rand();
+ wLength = rand();
+
+ libhusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex, wLength);
+ libhusb_fill_control_transfer(transfer, dev_handle, transfer_cb, buffer, NULL, timeout);
+
+ assert_ptr_equal(transfer->lusb_transfer->dev_handle, dev_handle->lusb_dev_handle);
+ assert_ptr_equal(transfer->lusb_transfer->buffer, buffer);
+ assert_int_equal(transfer->lusb_transfer->length, wLength + 8);
+ assert_int_equal(transfer->lusb_transfer->timeout, timeout);
+ assert_int_equal(transfer->lusb_transfer->type, LIBUSB_TRANSFER_TYPE_CONTROL);
+}
+
+static void test_destroy_transfer(void **state)
+{
+ libhusb_device_handle *dev_handle;
+ libhusb_transfer *transfer = NULL;
+ struct libusb_transfer lusb_transfer;
+ int ret;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ expect_value(libusb_alloc_transfer, iso_packets, 0);
+ will_return(libusb_alloc_transfer, &lusb_transfer);
+ ret = libhusb_create_transfer(&transfer, 0);
+
+ expect_value(libusb_free_transfer, transfer, &lusb_transfer);
+ libhusb_destroy_transfer(transfer);
+}
+
+static void test_submit_transfer(void **state)
+{
+ libhusb_device_handle *dev_handle = NULL;
+ libhusb_transfer *transfer= NULL;
+ struct libusb_transfer lusb_transfer;
+ int ret;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ expect_any(libusb_alloc_transfer, iso_packets);
+ will_return(libusb_alloc_transfer, &lusb_transfer);
+ ret = libhusb_create_transfer(&transfer, 0);
+
+ expect_value(libusb_submit_transfer, transfer, &lusb_transfer);
+ will_return(libusb_submit_transfer, 0);
+ ret = libhusb_submit_transfer(transfer);
+ assert_return_code(ret, 0);
+
+ expect_any(libusb_free_transfer, transfer);
+ libhusb_destroy_transfer(transfer);
+}
+
+static void test_cancel_transfer(void **state)
+{
+ libhusb_device_handle *dev_handle = NULL;
+ libhusb_transfer *transfer= NULL;
+ struct libusb_transfer lusb_transfer;
+ int ret;
+
+ dev_handle = (libhusb_device_handle *)(*state);
+
+ expect_any(libusb_alloc_transfer, iso_packets);
+ will_return(libusb_alloc_transfer, &lusb_transfer);
+ ret = libhusb_create_transfer(&transfer, 0);
+
+ expect_any(libusb_submit_transfer, transfer);
+ will_return(libusb_submit_transfer, 0);
+ ret = libhusb_submit_transfer(transfer);
+
+ expect_value(libusb_cancel_transfer, transfer, &lusb_transfer);
+ will_return(libusb_cancel_transfer, 0);
+ ret = libhusb_cancel_transfer(transfer);
+ assert_return_code(ret, 0);
+
+ expect_any(libusb_free_transfer, transfer);
+ libhusb_destroy_transfer(transfer);
+}
+
+static void test_handle_events(void **state)
+{
+ libhusb_context *ctx;
+ int completed;
+ int ret;
+
+ ctx = (libhusb_device_handle *)(*state);
+
+ expect_value(libusb_handle_events_completed, ctx, ctx->lusb_ctx);
+ expect_value(libusb_handle_events_completed, completed, &completed);
+ will_return(libusb_handle_events_completed, 0);
+ ret = libhusb_handle_events(ctx, &completed);
+ assert_return_code(ret, 0);
+}
+
/* Custom macro for defining test with given name and fixed teardown function */
#define HUSB_TEST(func, setup, teardown) \
cmocka_unit_test_setup_teardown(func, setup, teardown)
HUSB_TEST_DEV_HANDLE(test_attach_kernel_driver),
HUSB_TEST_DEV_HANDLE(test_get_string_descriptor_ascii),
HUSB_TEST_DEVICE(test_config_descriptor),
+ HUSB_TEST_DEV_HANDLE(test_submit_transfer),
+ HUSB_TEST_DEV_HANDLE(test_destroy_transfer),
+ HUSB_TEST_DEV_HANDLE(test_cancel_transfer),
+ HUSB_TEST_DEV_HANDLE(test_fill_bulk_transfer),
+ HUSB_TEST_DEV_HANDLE(test_fill_interrupt_transfer),
+ HUSB_TEST_DEV_HANDLE(test_fill_control_transfer),
+ HUSB_TEST_CTX(test_handle_events),
};