test.c (4554B)
1/* 2 * This is free and unencumbered software released into the public domain. 3 * 4 * Anyone is free to copy, modify, publish, use, compile, sell, or 5 * distribute this software, either in source code form or as a compiled 6 * binary, for any purpose, commercial or non-commercial, and by any 7 * means. 8 * 9 * In jurisdictions that recognize copyright laws, the author or authors 10 * of this software dedicate any and all copyright interest in the 11 * software to the public domain. We make this dedication for the benefit 12 * of the public at large and to the detriment of our heirs and 13 * successors. We intend this dedication to be an overt act of 14 * relinquishment in perpetuity of all present and future rights to this 15 * software under copyright law. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 * OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * For more information, please refer to <http://unlicense.org/> 26 */ 27 28#include <libusb.h> 29#include <stdio.h> 30#include <string.h> 31#include <unistd.h> 32 33#define VENDOR 0x1d6b 34#define PRODUCT 0x0105 35 36#define BUF_LEN 8192 37 38/* 39 * struct test_state - describes test program state 40 * @list: list of devices returned by libusb_get_device_list function 41 * @found: pointer to struct describing tested device 42 * @ctx: context, set to NULL 43 * @handle: handle of tested device 44 * @attached: indicates that device was attached to kernel, and has to be 45 * reattached at the end of test program 46 */ 47 48struct test_state { 49 libusb_device *found; 50 libusb_context *ctx; 51 libusb_device_handle *handle; 52 int attached; 53}; 54 55/* 56 * test_init - initialize test program 57 */ 58 59int test_init(struct test_state *state) 60{ 61 int i, ret; 62 ssize_t cnt; 63 libusb_device **list; 64 65 state->found = NULL; 66 state->ctx = NULL; 67 state->handle = NULL; 68 state->attached = 0; 69 70 ret = libusb_init(&state->ctx); 71 if (ret) { 72 printf("cannot init libusb: %s\n", libusb_error_name(ret)); 73 return 1; 74 } 75 76 cnt = libusb_get_device_list(state->ctx, &list); 77 if (cnt <= 0) { 78 printf("no devices found\n"); 79 goto error1; 80 } 81 82 for (i = 0; i < cnt; ++i) { 83 libusb_device *dev = list[i]; 84 struct libusb_device_descriptor desc; 85 ret = libusb_get_device_descriptor(dev, &desc); 86 if (ret) { 87 printf("unable to get device descriptor: %s\n", 88 libusb_error_name(ret)); 89 goto error2; 90 } 91 if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) { 92 state->found = dev; 93 break; 94 } 95 } 96 97 if (!state->found) { 98 printf("no devices found\n"); 99 goto error2; 100 } 101 102 ret = libusb_open(state->found, &state->handle); 103 if (ret) { 104 printf("cannot open device: %s\n", libusb_error_name(ret)); 105 goto error2; 106 } 107 108 if (libusb_claim_interface(state->handle, 0)) { 109 ret = libusb_detach_kernel_driver(state->handle, 0); 110 if (ret) { 111 printf("unable to detach kernel driver: %s\n", 112 libusb_error_name(ret)); 113 goto error3; 114 } 115 state->attached = 1; 116 ret = libusb_claim_interface(state->handle, 0); 117 if (ret) { 118 printf("cannot claim interface: %s\n", 119 libusb_error_name(ret)); 120 goto error4; 121 } 122 } 123 124 return 0; 125 126error4: 127 if (state->attached == 1) 128 libusb_attach_kernel_driver(state->handle, 0); 129 130error3: 131 libusb_close(state->handle); 132 133error2: 134 libusb_free_device_list(list, 1); 135 136error1: 137 libusb_exit(state->ctx); 138 return 1; 139} 140 141/* 142 * test_exit - cleanup test program 143 */ 144 145void test_exit(struct test_state *state) 146{ 147 libusb_release_interface(state->handle, 0); 148 if (state->attached == 1) 149 libusb_attach_kernel_driver(state->handle, 0); 150 libusb_close(state->handle); 151 libusb_exit(state->ctx); 152} 153 154int main(void) 155{ 156 struct test_state state; 157 struct libusb_config_descriptor *conf; 158 struct libusb_interface_descriptor const *iface; 159 unsigned char in_addr, out_addr; 160 161 if (test_init(&state)) 162 return 1; 163 164 libusb_get_config_descriptor(state.found, 0, &conf); 165 iface = &conf->interface[0].altsetting[0]; 166 in_addr = iface->endpoint[0].bEndpointAddress; 167 out_addr = iface->endpoint[1].bEndpointAddress; 168 169 while (1) { 170 static unsigned char buffer[BUF_LEN]; 171 int bytes; 172 libusb_bulk_transfer(state.handle, in_addr, buffer, BUF_LEN, 173 &bytes, 500); 174 libusb_bulk_transfer(state.handle, out_addr, buffer, BUF_LEN, 175 &bytes, 500); 176 } 177 test_exit(&state); 178}