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