Examples: Ported testlibusb from libus-0.1 to libusb-1.0
[platform/upstream/libusb.git] / examples / testlibusb.c
1 /*\r
2 * Test suite program based of libusb-0.1-compat testlibusb\r
3 * Copyright (c) 2013 Nathan Hjelm <hjelmn@mac.ccom>\r
4 *\r
5 * This library is free software; you can redistribute it and/or\r
6 * modify it under the terms of the GNU Lesser General Public\r
7 * License as published by the Free Software Foundation; either\r
8 * version 2.1 of the License, or (at your option) any later version.\r
9 *\r
10 * This library is distributed in the hope that it will be useful,\r
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
13 * Lesser General Public License for more details.\r
14 *\r
15 * You should have received a copy of the GNU Lesser General Public\r
16 * License along with this library; if not, write to the Free Software\r
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
18 */\r
19 \r
20 #include <stdio.h>\r
21 #include <string.h>\r
22 #include "libusb.h"\r
23 \r
24 int verbose = 0;\r
25 \r
26 static void print_endpoint_comp(const struct libusb_ss_endpoint_companion_descriptor *ep_comp)\r
27 {\r
28         printf("      USB 3.0 Endpoint Companion:\n");\r
29         printf("        bMaxBurst:        %d\n", ep_comp->bMaxBurst);\r
30         printf("        bmAttributes:     0x%02x\n", ep_comp->bmAttributes);\r
31         printf("        wBytesPerInterval: %d\n", ep_comp->wBytesPerInterval);\r
32 }\r
33 \r
34 static void print_endpoint(const struct libusb_endpoint_descriptor *endpoint)\r
35 {\r
36         int i, ret;\r
37 \r
38         printf("      Endpoint:\n");\r
39         printf("        bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);\r
40         printf("        bmAttributes:     %02xh\n", endpoint->bmAttributes);\r
41         printf("        wMaxPacketSize:   %d\n", endpoint->wMaxPacketSize);\r
42         printf("        bInterval:        %d\n", endpoint->bInterval);\r
43         printf("        bRefresh:         %d\n", endpoint->bRefresh);\r
44         printf("        bSynchAddress:    %d\n", endpoint->bSynchAddress);\r
45 \r
46         for (i = 0; i < endpoint->extra_length;) {\r
47                 if (LIBUSB_DT_SS_ENDPOINT_COMPANION == endpoint->extra[i + 1]) {\r
48                         struct libusb_ss_endpoint_companion_descriptor *ep_comp;\r
49 \r
50                         ret = libusb_get_ss_endpoint_companion_descriptor(NULL, endpoint, &ep_comp);\r
51                         if (LIBUSB_SUCCESS != ret) {\r
52                                 continue;\r
53                         }\r
54 \r
55                         print_endpoint_comp(ep_comp);\r
56 \r
57                         libusb_free_ss_endpoint_companion_descriptor(ep_comp);\r
58                 }\r
59 \r
60                 i += endpoint->extra[i];\r
61         }\r
62 }\r
63 \r
64 static void print_altsetting(const struct libusb_interface_descriptor *interface)\r
65 {\r
66         int i;\r
67 \r
68         printf("    Interface:\n");\r
69         printf("      bInterfaceNumber:   %d\n", interface->bInterfaceNumber);\r
70         printf("      bAlternateSetting:  %d\n", interface->bAlternateSetting);\r
71         printf("      bNumEndpoints:      %d\n", interface->bNumEndpoints);\r
72         printf("      bInterfaceClass:    %d\n", interface->bInterfaceClass);\r
73         printf("      bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);\r
74         printf("      bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);\r
75         printf("      iInterface:         %d\n", interface->iInterface);\r
76 \r
77         for (i = 0; i < interface->bNumEndpoints; i++)\r
78                 print_endpoint(&interface->endpoint[i]);\r
79 }\r
80 \r
81 static void print_2_0_ext_cap(struct libusb_usb_2_0_extension_descriptor *usb_2_0_ext_cap)\r
82 {\r
83         printf("    USB 2.0 Extension Capabilities:\n");\r
84         printf("      bDevCapabilityType: %d\n", usb_2_0_ext_cap->bDevCapabilityType);\r
85         printf("      bmAttributes:       0x%x\n", usb_2_0_ext_cap->bmAttributes);\r
86 }\r
87 \r
88 static void print_ss_usb_cap(struct libusb_ss_usb_device_capability_descriptor *ss_usb_cap)\r
89 {\r
90         printf("    USB 3.0 Capabilities:\n");\r
91         printf("      bDevCapabilityType: %d\n", ss_usb_cap->bDevCapabilityType);\r
92         printf("      bmAttributes:       0x%x\n", ss_usb_cap->bmAttributes);\r
93         printf("      wSpeedSupported:    0x%x\n", ss_usb_cap->wSpeedSupported);\r
94         printf("      bFunctionalitySupport: %d\n", ss_usb_cap->bFunctionalitySupport);\r
95         printf("      bU1devExitLat:      %d\n", ss_usb_cap->bU1DevExitLat);\r
96         printf("      bU2devExitLat:      %d\n", ss_usb_cap->bU2DevExitLat);\r
97 }\r
98 \r
99 static void print_bos(libusb_device_handle *handle)\r
100 {\r
101         struct libusb_bos_descriptor *bos;\r
102         int ret;\r
103 \r
104         ret = libusb_get_bos_descriptor(handle, &bos);\r
105         if (0 > ret) {\r
106                 return;\r
107         }\r
108         \r
109         printf("  Binary Object Store (BOS):\n");\r
110         printf("    wTotalLength:       %d\n", bos->wTotalLength);\r
111         printf("    bNumDeviceCaps:     %d\n", bos->bNumDeviceCaps);\r
112                 \r
113         if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_USB_2_0_EXTENSION) {\r
114         \r
115                 struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension;\r
116                 ret =  libusb_get_usb_2_0_extension_descriptor(NULL, bos->dev_capability[0],&usb_2_0_extension);\r
117                 if (0 > ret) {\r
118                         return;\r
119                 }\r
120                 \r
121                 print_2_0_ext_cap(usb_2_0_extension);\r
122                 libusb_free_usb_2_0_extension_descriptor(usb_2_0_extension);\r
123         }\r
124         \r
125         if(bos->dev_capability[0]->bDevCapabilityType == LIBUSB_BT_SS_USB_DEVICE_CAPABILITY) {\r
126         \r
127                 struct libusb_ss_usb_device_capability_descriptor *dev_cap;\r
128                 ret = libusb_get_ss_usb_device_capability_descriptor(NULL, bos->dev_capability[0],&dev_cap);\r
129                 if (0 > ret) {\r
130                         return;\r
131                 }\r
132                 \r
133                 print_ss_usb_cap(dev_cap);\r
134                 libusb_free_ss_usb_device_capability_descriptor(dev_cap);\r
135         }\r
136         \r
137         libusb_free_bos_descriptor(bos);\r
138 }\r
139 \r
140 static void print_interface(const struct libusb_interface *interface)\r
141 {\r
142         int i;\r
143 \r
144         for (i = 0; i < interface->num_altsetting; i++)\r
145                 print_altsetting(&interface->altsetting[i]);\r
146 }\r
147 \r
148 static void print_configuration(struct libusb_config_descriptor *config)\r
149 {\r
150         int i;\r
151 \r
152         printf("  Configuration:\n");\r
153         printf("    wTotalLength:         %d\n", config->wTotalLength);\r
154         printf("    bNumInterfaces:       %d\n", config->bNumInterfaces);\r
155         printf("    bConfigurationValue:  %d\n", config->bConfigurationValue);\r
156         printf("    iConfiguration:       %d\n", config->iConfiguration);\r
157         printf("    bmAttributes:         %02xh\n", config->bmAttributes);\r
158         printf("    MaxPower:             %d\n", config->MaxPower);\r
159 \r
160         for (i = 0; i < config->bNumInterfaces; i++)\r
161                 print_interface(&config->interface[i]);\r
162 }\r
163 \r
164 static int print_device(libusb_device *dev, int level)\r
165 {\r
166         struct libusb_device_descriptor desc;\r
167         libusb_device_handle *handle = NULL;\r
168         char description[256];\r
169         char string[256];\r
170         int ret, i;\r
171 \r
172         ret = libusb_get_device_descriptor(dev, &desc);\r
173         if (ret < 0) {\r
174                 fprintf(stderr, "failed to get device descriptor");\r
175                 return -1;\r
176         }\r
177 \r
178         ret = libusb_open(dev, &handle);\r
179         if (LIBUSB_SUCCESS == ret) {\r
180                 if (desc.iManufacturer) {\r
181                         ret = libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, string, sizeof(string));\r
182                         if (ret > 0)\r
183                                 snprintf(description, sizeof(description), "%s - ", string);\r
184                         else\r
185                                 snprintf(description, sizeof(description), "%04X - ",\r
186                                 desc.idVendor);\r
187                 }\r
188                 else\r
189                         snprintf(description, sizeof(description), "%04X - ",\r
190                         desc.idVendor);\r
191 \r
192                 if (desc.iProduct) {\r
193                         ret = libusb_get_string_descriptor_ascii(handle, desc.iProduct, string, sizeof(string));\r
194                         if (ret > 0)\r
195                                 snprintf(description + strlen(description), sizeof(description) -\r
196                                 strlen(description), "%s", string);\r
197                         else\r
198                                 snprintf(description + strlen(description), sizeof(description) -\r
199                                 strlen(description), "%04X", desc.idProduct);\r
200                 }\r
201                 else\r
202                         snprintf(description + strlen(description), sizeof(description) -\r
203                         strlen(description), "%04X", desc.idProduct);\r
204         }\r
205         else {\r
206                 snprintf(description, sizeof(description), "%04X - %04X",\r
207                         desc.idVendor, desc.idProduct);\r
208         }\r
209 \r
210         printf("%.*sDev (bus %d, device %d): %s\n", level * 2, "                    ",\r
211                 libusb_get_bus_number(dev), libusb_get_device_address(dev), description);\r
212 \r
213         if (handle && verbose) {\r
214                 if (desc.iSerialNumber) {\r
215                         ret = libusb_get_string_descriptor_ascii(handle, desc.iSerialNumber, string, sizeof(string));\r
216                         if (ret > 0)\r
217                                 printf("%.*s  - Serial Number: %s\n", level * 2,\r
218                                 "                    ", string);\r
219                 }\r
220         }\r
221 \r
222         if (verbose) {\r
223                 for (i = 0; i < desc.bNumConfigurations; i++) {\r
224                         struct libusb_config_descriptor *config;\r
225                         ret = libusb_get_config_descriptor(dev, i, &config);\r
226                         if (LIBUSB_SUCCESS != ret) {\r
227                                 printf("  Couldn't retrieve descriptors\n");\r
228                                 continue;\r
229                         }\r
230 \r
231                         print_configuration(config);\r
232 \r
233                         libusb_free_config_descriptor(config);\r
234                 }\r
235 \r
236                 \r
237                 if (handle && desc.bcdUSB >= 0x0201) {\r
238                         print_bos(handle);\r
239                 }\r
240         }\r
241 \r
242         if (handle)\r
243                 libusb_close(handle);\r
244 \r
245         return 0;\r
246 }\r
247 \r
248 int main(int argc, char *argv[])\r
249 {\r
250         libusb_device **devs;\r
251         ssize_t cnt;\r
252         int r, i;\r
253 \r
254         if (argc > 1 && !strcmp(argv[1], "-v"))\r
255                 verbose = 1;\r
256 \r
257         r = libusb_init(NULL);\r
258         if (r < 0)\r
259                 return r;\r
260 \r
261         cnt = libusb_get_device_list(NULL, &devs);\r
262         if (cnt < 0)\r
263                 return (int)cnt;\r
264 \r
265         for (i = 0; devs[i]; ++i) {\r
266                 print_device(devs[i], 0);\r
267         }\r
268 \r
269         libusb_free_device_list(devs, 1);\r
270 \r
271         libusb_exit(NULL);\r
272         return 0;\r
273 }\r