1e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev/*
2e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev * testlibusb.c
3e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev *
4e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev *  Test suite program
5e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev */
6e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
7e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev#include <stdio.h>
8e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev#include <string.h>
9e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev#include <usb.h>
10e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
11e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevint verbose = 0;
12e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
13e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevvoid print_endpoint(struct usb_endpoint_descriptor *endpoint)
14e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
15e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      bEndpointAddress: %02xh\n", endpoint->bEndpointAddress);
16e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      bmAttributes:     %02xh\n", endpoint->bmAttributes);
17e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      wMaxPacketSize:   %d\n", endpoint->wMaxPacketSize);
18e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      bInterval:        %d\n", endpoint->bInterval);
19e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      bRefresh:         %d\n", endpoint->bRefresh);
20e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("      bSynchAddress:    %d\n", endpoint->bSynchAddress);
21e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
22e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
23e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevvoid print_altsetting(struct usb_interface_descriptor *interface)
24e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
25e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  int i;
26e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
27e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bInterfaceNumber:   %d\n", interface->bInterfaceNumber);
28e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bAlternateSetting:  %d\n", interface->bAlternateSetting);
29e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bNumEndpoints:      %d\n", interface->bNumEndpoints);
30e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bInterfaceClass:    %d\n", interface->bInterfaceClass);
31e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bInterfaceSubClass: %d\n", interface->bInterfaceSubClass);
32e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    bInterfaceProtocol: %d\n", interface->bInterfaceProtocol);
33e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("    iInterface:         %d\n", interface->iInterface);
34e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
35e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  for (i = 0; i < interface->bNumEndpoints; i++)
36e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    print_endpoint(&interface->endpoint[i]);
37e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
38e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
39e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevvoid print_interface(struct usb_interface *interface)
40e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
41e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  int i;
42e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
43e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  for (i = 0; i < interface->num_altsetting; i++)
44e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    print_altsetting(&interface->altsetting[i]);
45e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
46e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
47e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevvoid print_configuration(struct usb_config_descriptor *config)
48e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
49e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  int i;
50e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
51e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  wTotalLength:         %d\n", config->wTotalLength);
52e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  bNumInterfaces:       %d\n", config->bNumInterfaces);
53e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  bConfigurationValue:  %d\n", config->bConfigurationValue);
54e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  iConfiguration:       %d\n", config->iConfiguration);
55e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  bmAttributes:         %02xh\n", config->bmAttributes);
56e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("  MaxPower:             %d\n", config->MaxPower);
57e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
58e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  for (i = 0; i < config->bNumInterfaces; i++)
59e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    print_interface(&config->interface[i]);
60e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
61e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
62e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevint print_device(struct usb_device *dev, int level)
63e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
64e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  usb_dev_handle *udev;
65e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  char description[256];
66e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  char string[256];
67e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  int ret, i;
68e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
69e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  udev = usb_open(dev);
70e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  if (udev) {
71e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    if (dev->descriptor.iManufacturer) {
72e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      ret = usb_get_string_simple(udev, dev->descriptor.iManufacturer, string, sizeof(string));
73e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      if (ret > 0)
74e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        snprintf(description, sizeof(description), "%s - ", string);
75e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      else
76e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        snprintf(description, sizeof(description), "%04X - ",
77e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev                 dev->descriptor.idVendor);
78e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    } else
79e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      snprintf(description, sizeof(description), "%04X - ",
80e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev               dev->descriptor.idVendor);
81e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
82e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    if (dev->descriptor.iProduct) {
83e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      ret = usb_get_string_simple(udev, dev->descriptor.iProduct, string, sizeof(string));
84e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      if (ret > 0)
85e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        snprintf(description + strlen(description), sizeof(description) -
86e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev                 strlen(description), "%s", string);
87e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      else
88e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        snprintf(description + strlen(description), sizeof(description) -
89e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev                 strlen(description), "%04X", dev->descriptor.idProduct);
90e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    } else
91e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      snprintf(description + strlen(description), sizeof(description) -
92e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev               strlen(description), "%04X", dev->descriptor.idProduct);
93e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
94e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  } else
95e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    snprintf(description, sizeof(description), "%04X - %04X",
96e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev             dev->descriptor.idVendor, dev->descriptor.idProduct);
97e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
98e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  printf("%.*sDev #%d: %s\n", level * 2, "                    ", dev->devnum,
99e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev         description);
100e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
101e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  if (udev && verbose) {
102e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    if (dev->descriptor.iSerialNumber) {
103e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      ret = usb_get_string_simple(udev, dev->descriptor.iSerialNumber, string, sizeof(string));
104e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      if (ret > 0)
105e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        printf("%.*s  - Serial Number: %s\n", level * 2,
106e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev               "                    ", string);
107e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    }
108e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  }
109e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
110e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  if (udev)
111e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    usb_close(udev);
112e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
113e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  if (verbose) {
114e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    if (!dev->config) {
115e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      printf("  Couldn't retrieve descriptors\n");
116e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      return 0;
117e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    }
118e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
119e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
120e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      print_configuration(&dev->config[i]);
121e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  } else {
122e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    for (i = 0; i < dev->num_children; i++)
123e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      print_device(dev->children[i], level + 1);
124e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  }
125e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
126e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  return 0;
127e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
128e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
129e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishevint main(int argc, char *argv[])
130e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev{
131e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  struct usb_bus *bus;
132e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
133e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  if (argc > 1 && !strcmp(argv[1], "-v"))
134e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    verbose = 1;
135e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
136e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  usb_init();
137e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
138e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  usb_find_busses();
139e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  usb_find_devices();
140e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
141e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  for (bus = usb_busses; bus; bus = bus->next) {
142e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    if (bus->root_dev && !verbose)
143e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      print_device(bus->root_dev, 0);
144e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    else {
145e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      struct usb_device *dev;
146e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
147e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev      for (dev = bus->devices; dev; dev = dev->next)
148e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev        print_device(dev, 0);
149e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev    }
150e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  }
151e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
152e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev  return 0;
153e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev}
154e9a683104ef3f40d38459c0ca62a2d46f20b0714Yavor Goulishev
155