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