xref: /OK3568_Linux_fs/kernel/tools/usb/ffs-aio-example/simple/host_app/test.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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