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