Home | History | Annotate | Download | only in examples
      1 /*
      2 * Test suite program based of libusb-0.1-compat testlibusb
      3 * Copyright (c) 2013 Nathan Hjelm <hjelmn (at) 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 
     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 
     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 
     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 
     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 
     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 
     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 
    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 
    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 
    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 
    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