179 lines · c
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, or5 * distribute this software, either in source code form or as a compiled6 * binary, for any purpose, commercial or non-commercial, and by any7 * means.8 *9 * In jurisdictions that recognize copyright laws, the author or authors10 * of this software dedicate any and all copyright interest in the11 * software to the public domain. We make this dedication for the benefit12 * of the public at large and to the detriment of our heirs and13 * successors. We intend this dedication to be an overt act of14 * relinquishment in perpetuity of all present and future rights to this15 * 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 OF19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.20 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR21 * 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 OR23 * 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 0x1d6b34#define PRODUCT 0x010535 36#define BUF_LEN 819237 38/*39 * struct test_state - describes test program state40 * @list: list of devices returned by libusb_get_device_list function41 * @found: pointer to struct describing tested device42 * @ctx: context, set to NULL43 * @handle: handle of tested device44 * @attached: indicates that device was attached to kernel, and has to be45 * reattached at the end of test program46 */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 program57 */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 program143 */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}179