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