Samples: Fix no previous prototype warnings in xusb.c
[platform/upstream/libusb.git] / examples / xusb.c
1 /*
2  * xusb: Generic USB test program
3  * Copyright © 2009-2012 Pete Batard <pete@akeo.ie>
4  * Contributions to Mass Storage by Alan Stern.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 #include <stdio.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdarg.h>
26
27 #include "libusb.h"
28
29 #if defined(_WIN32)
30 #define msleep(msecs) Sleep(msecs)
31 #else
32 #include <unistd.h>
33 #define msleep(msecs) usleep(1000*msecs)
34 #endif
35
36 #if !defined(_MSC_VER) || _MSC_VER<=1200
37 #define sscanf_s sscanf
38 #endif
39
40 #if !defined(bool)
41 #define bool int
42 #endif
43 #if !defined(true)
44 #define true (1 == 1)
45 #endif
46 #if !defined(false)
47 #define false (!true)
48 #endif
49
50
51 // Future versions of libusbx will use usb_interface instead of interface
52 // in libusb_config_descriptor => catter for that
53 #define usb_interface interface
54
55 // Global variables
56 bool binary_dump = false;
57 char binary_name[64];
58
59 inline static int perr(char const *format, ...)
60 {
61         va_list args;
62         int r;
63
64         va_start (args, format);
65         r = vfprintf(stderr, format, args);
66         va_end(args);
67
68         return r;
69 }
70
71 #define ERR_EXIT(errcode) do { perr("   %s\n", libusb_error_name((enum libusb_error)errcode)); return -1; } while (0)
72 #define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
73 #define B(x) (((x)!=0)?1:0)
74 #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
75
76 #define RETRY_MAX                     5
77 #define REQUEST_SENSE_LENGTH          0x12
78 #define INQUIRY_LENGTH                0x24
79 #define READ_CAPACITY_LENGTH          0x08
80
81 // HID Class-Specific Requests values. See section 7.2 of the HID specifications
82 #define HID_GET_REPORT                0x01
83 #define HID_SET_REPORT                0x09
84 #define HID_REPORT_TYPE_INPUT         0x01
85 #define HID_REPORT_TYPE_OUTPUT        0x02
86
87 // Mass Storage Requests values. See section 3 of the Bulk-Only Mass Storage Class specifications
88 #define BOMS_RESET                    0xFF
89 #define BOMS_GET_MAX_LUN              0xFE
90
91 // Section 5.1: Command Block Wrapper (CBW)
92 struct command_block_wrapper {
93         uint8_t dCBWSignature[4];
94         uint32_t dCBWTag;
95         uint32_t dCBWDataTransferLength;
96         uint8_t bmCBWFlags;
97         uint8_t bCBWLUN;
98         uint8_t bCBWCBLength;
99         uint8_t CBWCB[16];
100 };
101
102 // Section 5.2: Command Status Wrapper (CSW)
103 struct command_status_wrapper {
104         uint8_t dCSWSignature[4];
105         uint32_t dCSWTag;
106         uint32_t dCSWDataResidue;
107         uint8_t bCSWStatus;
108 };
109
110 static uint8_t cdb_length[256] = {
111 //       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
112         06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,  //  0
113         06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,  //  1
114         10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,  //  2
115         10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,  //  3
116         10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,  //  4
117         10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,  //  5
118         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  6
119         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  7
120         16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,  //  8
121         16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,  //  9
122         12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,  //  A
123         12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,  //  B
124         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  C
125         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  D
126         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  E
127         00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,  //  F
128 };
129
130 enum test_type {
131         USE_GENERIC,
132         USE_PS3,
133         USE_XBOX,
134         USE_SCSI,
135 } test_mode;
136 uint16_t VID, PID;
137
138 static void display_buffer_hex(unsigned char *buffer, unsigned size)
139 {
140         unsigned i, j, k;
141
142         for (i=0; i<size; i+=16) {
143                 printf("\n  %08x  ", i);
144                 for(j=0,k=0; k<16; j++,k++) {
145                         if (i+j < size) {
146                                 printf("%02x", buffer[i+j]);
147                         } else {
148                                 printf("  ");
149                         }
150                         printf(" ");
151                 }
152                 printf(" ");
153                 for(j=0,k=0; k<16; j++,k++) {
154                         if (i+j < size) {
155                                 if ((buffer[i+j] < 32) || (buffer[i+j] > 126)) {
156                                         printf(".");
157                                 } else {
158                                         printf("%c", buffer[i+j]);
159                                 }
160                         }
161                 }
162         }
163         printf("\n" );
164 }
165
166 // The PS3 Controller is really a HID device that got its HID Report Descriptors
167 // removed by Sony
168 static int display_ps3_status(libusb_device_handle *handle)
169 {
170         int r;
171         uint8_t input_report[49];
172         uint8_t master_bt_address[8];
173         uint8_t device_bt_address[18];
174
175         // Get the controller's bluetooth address of its master device
176         CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
177                 HID_GET_REPORT, 0x03f5, 0, master_bt_address, sizeof(master_bt_address), 100));
178         printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", master_bt_address[2], master_bt_address[3],
179                 master_bt_address[4], master_bt_address[5], master_bt_address[6], master_bt_address[7]);
180
181         // Get the controller's bluetooth address
182         CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
183                 HID_GET_REPORT, 0x03f2, 0, device_bt_address, sizeof(device_bt_address), 100));
184         printf("\nMaster's bluetooth address: %02X:%02X:%02X:%02X:%02X:%02X\n", device_bt_address[4], device_bt_address[5],
185                 device_bt_address[6], device_bt_address[7], device_bt_address[8], device_bt_address[9]);
186
187         // Get the status of the controller's buttons via its HID report
188         printf("\nReading PS3 Input Report...\n");
189         CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
190                 HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x01, 0, input_report, sizeof(input_report), 1000));
191         switch(input_report[2]){        /** Direction pad plus start, select, and joystick buttons */
192                 case 0x01:
193                         printf("\tSELECT pressed\n");
194                         break;
195                 case 0x02:
196                         printf("\tLEFT 3 pressed\n");
197                         break;
198                 case 0x04:
199                         printf("\tRIGHT 3 pressed\n");
200                         break;
201                 case 0x08:
202                         printf("\tSTART presed\n");
203                         break;
204                 case 0x10:
205                         printf("\tUP pressed\n");
206                         break;
207                 case 0x20:
208                         printf("\tRIGHT pressed\n");
209                         break;
210                 case 0x40:
211                         printf("\tDOWN pressed\n");
212                         break;
213                 case 0x80:
214                         printf("\tLEFT pressed\n");
215                         break;
216         }
217         switch(input_report[3]){        /** Shapes plus top right and left buttons */
218                 case 0x01:
219                         printf("\tLEFT 2 pressed\n");
220                         break;
221                 case 0x02:
222                         printf("\tRIGHT 2 pressed\n");
223                         break;
224                 case 0x04:
225                         printf("\tLEFT 1 pressed\n");
226                         break;
227                 case 0x08:
228                         printf("\tRIGHT 1 presed\n");
229                         break;
230                 case 0x10:
231                         printf("\tTRIANGLE pressed\n");
232                         break;
233                 case 0x20:
234                         printf("\tCIRCLE pressed\n");
235                         break;
236                 case 0x40:
237                         printf("\tCROSS pressed\n");
238                         break;
239                 case 0x80:
240                         printf("\tSQUARE pressed\n");
241                         break;
242         }
243         printf("\tPS button: %d\n", input_report[4]);
244         printf("\tLeft Analog (X,Y): (%d,%d)\n", input_report[6], input_report[7]);
245         printf("\tRight Analog (X,Y): (%d,%d)\n", input_report[8], input_report[9]);
246         printf("\tL2 Value: %d\tR2 Value: %d\n", input_report[18], input_report[19]);
247         printf("\tL1 Value: %d\tR1 Value: %d\n", input_report[20], input_report[21]);
248         printf("\tRoll (x axis): %d Yaw (y axis): %d Pitch (z axis) %d\n",
249                         //(((input_report[42] + 128) % 256) - 128),
250                         (int8_t)(input_report[42]),
251                         (int8_t)(input_report[44]),
252                         (int8_t)(input_report[46]));
253         printf("\tAcceleration: %d\n\n", (int8_t)(input_report[48]));
254         return 0;
255 }
256 // The XBOX Controller is really a HID device that got its HID Report Descriptors
257 // removed by Microsoft.
258 // Input/Output reports described at http://euc.jp/periphs/xbox-controller.ja.html
259 static int display_xbox_status(libusb_device_handle *handle)
260 {
261         int r;
262         uint8_t input_report[20];
263         printf("\nReading XBox Input Report...\n");
264         CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
265                 HID_GET_REPORT, (HID_REPORT_TYPE_INPUT<<8)|0x00, 0, input_report, 20, 1000));
266         printf("   D-pad: %02X\n", input_report[2]&0x0F);
267         printf("   Start:%d, Back:%d, Left Stick Press:%d, Right Stick Press:%d\n", B(input_report[2]&0x10), B(input_report[2]&0x20),
268                 B(input_report[2]&0x40), B(input_report[2]&0x80));
269         // A, B, X, Y, Black, White are pressure sensitive
270         printf("   A:%d, B:%d, X:%d, Y:%d, White:%d, Black:%d\n", input_report[4], input_report[5],
271                 input_report[6], input_report[7], input_report[9], input_report[8]);
272         printf("   Left Trigger: %d, Right Trigger: %d\n", input_report[10], input_report[11]);
273         printf("   Left Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[13]<<8)|input_report[12]),
274                 (int16_t)((input_report[15]<<8)|input_report[14]));
275         printf("   Right Analog (X,Y): (%d,%d)\n", (int16_t)((input_report[17]<<8)|input_report[16]),
276                 (int16_t)((input_report[19]<<8)|input_report[18]));
277         return 0;
278 }
279
280 static int set_xbox_actuators(libusb_device_handle *handle, uint8_t left, uint8_t right)
281 {
282         int r;
283         uint8_t output_report[6];
284
285         printf("\nWriting XBox Controller Output Report...\n");
286
287         memset(output_report, 0, sizeof(output_report));
288         output_report[1] = sizeof(output_report);
289         output_report[3] = left;
290         output_report[5] = right;
291
292         CALL_CHECK(libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
293                 HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT<<8)|0x00, 0, output_report, 06, 1000));
294         return 0;
295 }
296
297 static int send_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint, uint8_t lun,
298         uint8_t *cdb, uint8_t direction, int data_length, uint32_t *ret_tag)
299 {
300         static uint32_t tag = 1;
301         uint8_t cdb_len;
302         int i, r, size;
303         struct command_block_wrapper cbw;
304
305         if (cdb == NULL) {
306                 return -1;
307         }
308
309         if (endpoint & LIBUSB_ENDPOINT_IN) {
310                 perr("send_mass_storage_command: cannot send command on IN endpoint\n");
311                 return -1;
312         }
313
314         cdb_len = cdb_length[cdb[0]];
315         if ((cdb_len == 0) || (cdb_len > sizeof(cbw.CBWCB))) {
316                 perr("send_mass_storage_command: don't know how to handle this command (%02X, length %d)\n",
317                         cdb[0], cdb_len);
318                 return -1;
319         }
320
321         memset(&cbw, 0, sizeof(cbw));
322         cbw.dCBWSignature[0] = 'U';
323         cbw.dCBWSignature[1] = 'S';
324         cbw.dCBWSignature[2] = 'B';
325         cbw.dCBWSignature[3] = 'C';
326         *ret_tag = tag;
327         cbw.dCBWTag = tag++;
328         cbw.dCBWDataTransferLength = data_length;
329         cbw.bmCBWFlags = direction;
330         cbw.bCBWLUN = lun;
331         // Subclass is 1 or 6 => cdb_len
332         cbw.bCBWCBLength = cdb_len;
333         memcpy(cbw.CBWCB, cdb, cdb_len);
334
335         i = 0;
336         do {
337                 // The transfer length must always be exactly 31 bytes.
338                 r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&cbw, 31, &size, 1000);
339                 if (r == LIBUSB_ERROR_PIPE) {
340                         libusb_clear_halt(handle, endpoint);
341                 }
342                 i++;
343         } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
344         if (r != LIBUSB_SUCCESS) {
345                 perr("   send_mass_storage_command: %s\n", libusb_error_name(r));
346                 return -1;
347         }
348
349         printf("   sent %d CDB bytes\n", cdb_len);
350         return 0;
351 }
352
353 static int get_mass_storage_status(libusb_device_handle *handle, uint8_t endpoint, uint32_t expected_tag)
354 {
355         int i, r, size;
356         struct command_status_wrapper csw;
357
358         // The device is allowed to STALL this transfer. If it does, you have to
359         // clear the stall and try again.
360         i = 0;
361         do {
362                 r = libusb_bulk_transfer(handle, endpoint, (unsigned char*)&csw, 13, &size, 1000);
363                 if (r == LIBUSB_ERROR_PIPE) {
364                         libusb_clear_halt(handle, endpoint);
365                 }
366                 i++;
367         } while ((r == LIBUSB_ERROR_PIPE) && (i<RETRY_MAX));
368         if (r != LIBUSB_SUCCESS) {
369                 perr("   get_mass_storage_status: %s\n", libusb_error_name(r));
370                 return -1;
371         }
372         if (size != 13) {
373                 perr("   get_mass_storage_status: received %d bytes (expected 13)\n", size);
374                 return -1;
375         }
376         if (csw.dCSWTag != expected_tag) {
377                 perr("   get_mass_storage_status: mismatched tags (expected %08X, received %08X)\n",
378                         expected_tag, csw.dCSWTag);
379                 return -1;
380         }
381         // For this test, we ignore the dCSWSignature check for validity...
382         printf("   Mass Storage Status: %02X (%s)\n", csw.bCSWStatus, csw.bCSWStatus?"FAILED":"Success");
383         if (csw.dCSWTag != expected_tag)
384                 return -1;
385         if (csw.bCSWStatus) {
386                 // REQUEST SENSE is appropriate only if bCSWStatus is 1, meaning that the
387                 // command failed somehow.  Larger values (2 in particular) mean that
388                 // the command couldn't be understood.
389                 if (csw.bCSWStatus == 1)
390                         return -2;      // request Get Sense
391                 else
392                         return -1;
393         }
394
395         // In theory we also should check dCSWDataResidue.  But lots of devices
396         // set it wrongly.
397         return 0;
398 }
399
400 static void get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
401 {
402         uint8_t cdb[16];        // SCSI Command Descriptor Block
403         uint8_t sense[18];
404         uint32_t expected_tag;
405         int size;
406
407         // Request Sense
408         printf("Request Sense:\n");
409         memset(sense, 0, sizeof(sense));
410         memset(cdb, 0, sizeof(cdb));
411         cdb[0] = 0x03;  // Request Sense
412         cdb[4] = REQUEST_SENSE_LENGTH;
413
414         send_mass_storage_command(handle, endpoint_out, 0, cdb, LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH, &expected_tag);
415         libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&sense, REQUEST_SENSE_LENGTH, &size, 1000);
416         printf("   received %d bytes\n", size);
417
418         if ((sense[0] != 0x70) && (sense[0] != 0x71)) {
419                 perr("   ERROR No sense data\n");
420         } else {
421                 perr("   ERROR Sense: %02X %02X %02X\n", sense[2]&0x0F, sense[12], sense[13]);
422         }
423         // Strictly speaking, the get_mass_storage_status() call should come
424         // before these perr() lines.  If the status is nonzero then we must
425         // assume there's no data in the buffer.  For xusb it doesn't matter.
426         get_mass_storage_status(handle, endpoint_in, expected_tag);
427 }
428
429 // Mass Storage device to test bulk transfers (non destructive test)
430 static int test_mass_storage(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
431 {
432         int r, size;
433         uint8_t lun;
434         uint32_t expected_tag;
435         uint32_t i, max_lba, block_size;
436         double device_size;
437         uint8_t cdb[16];        // SCSI Command Descriptor Block
438         uint8_t buffer[64];
439         char vid[9], pid[9], rev[5];
440         unsigned char *data;
441         FILE *fd;
442
443         printf("Reading Max LUN:\n");
444         r = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
445                 BOMS_GET_MAX_LUN, 0, 0, &lun, 1, 1000);
446         // Some devices send a STALL instead of the actual value.
447         // In such cases we should set lun to 0.
448         if (r == 0) {
449                 lun = 0;
450         } else if (r < 0) {
451                 perr("   Failed: %s", libusb_error_name((enum libusb_error)r));
452         }
453         printf("   Max LUN = %d\n", lun);
454
455         // Send Inquiry
456         printf("Sending Inquiry:\n");
457         memset(buffer, 0, sizeof(buffer));
458         memset(cdb, 0, sizeof(cdb));
459         cdb[0] = 0x12;  // Inquiry
460         cdb[4] = INQUIRY_LENGTH;
461
462         send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, INQUIRY_LENGTH, &expected_tag);
463         CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, INQUIRY_LENGTH, &size, 1000));
464         printf("   received %d bytes\n", size);
465         // The following strings are not zero terminated
466         for (i=0; i<8; i++) {
467                 vid[i] = buffer[8+i];
468                 pid[i] = buffer[16+i];
469                 rev[i/2] = buffer[32+i/2];      // instead of another loop
470         }
471         vid[8] = 0;
472         pid[8] = 0;
473         rev[4] = 0;
474         printf("   VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid, pid, rev);
475         if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
476                 get_sense(handle, endpoint_in, endpoint_out);
477         }
478
479         // Read capacity
480         printf("Reading Capacity:\n");
481         memset(buffer, 0, sizeof(buffer));
482         memset(cdb, 0, sizeof(cdb));
483         cdb[0] = 0x25;  // Read Capacity
484
485         send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, READ_CAPACITY_LENGTH, &expected_tag);
486         CALL_CHECK(libusb_bulk_transfer(handle, endpoint_in, (unsigned char*)&buffer, READ_CAPACITY_LENGTH, &size, 1000));
487         printf("   received %d bytes\n", size);
488         max_lba = be_to_int32(&buffer[0]);
489         block_size = be_to_int32(&buffer[4]);
490         device_size = ((double)(max_lba+1))*block_size/(1024*1024*1024);
491         printf("   Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba, block_size, device_size);
492         if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
493                 get_sense(handle, endpoint_in, endpoint_out);
494         }
495
496         data = (unsigned char*) calloc(1, block_size);
497         if (data == NULL) {
498                 perr("   unable to allocate data buffer\n");
499                 return -1;
500         }
501
502         // Send Read
503         printf("Attempting to read %d bytes:\n", block_size);
504         memset(cdb, 0, sizeof(cdb));
505
506         cdb[0] = 0x28;  // Read(10)
507         cdb[8] = 0x01;  // 1 block
508
509         send_mass_storage_command(handle, endpoint_out, lun, cdb, LIBUSB_ENDPOINT_IN, block_size, &expected_tag);
510         libusb_bulk_transfer(handle, endpoint_in, data, block_size, &size, 5000);
511         printf("   READ: received %d bytes\n", size);
512         if (get_mass_storage_status(handle, endpoint_in, expected_tag) == -2) {
513                 get_sense(handle, endpoint_in, endpoint_out);
514         } else {
515                 display_buffer_hex(data, size);
516                 if ((binary_dump) && ((fd = fopen(binary_name, "w")) != NULL)) {
517                         if (fwrite(data, 1, (size_t)size, fd) != (unsigned int)size) {
518                                 perr("   unable to write binary data\n");
519                         }
520                         fclose(fd);
521                 }
522         }
523         free(data);
524
525         return 0;
526 }
527
528 // Read the MS WinUSB Feature Descriptors, that are used on Windows 8 for automated driver installation
529 static void read_ms_winsub_feature_descriptors(libusb_device_handle *handle, uint8_t bRequest, int iface_number)
530 {
531 #define MAX_OS_FD_LENGTH 256
532         int i, r;
533         uint8_t os_desc[MAX_OS_FD_LENGTH];
534         uint32_t length;
535         void* le_type_punning_IS_fine;
536         struct {
537                 char* desc;
538                 uint8_t recipient;
539                 uint16_t index;
540                 uint16_t header_size;
541         } os_fd[2] = {
542                 {"Extended Compat ID", LIBUSB_RECIPIENT_DEVICE, 0x0004, 0x10},
543                 {"Extended Properties", LIBUSB_RECIPIENT_INTERFACE, 0x0005, 0x0A}
544         };
545
546         if (iface_number < 0) return;
547
548         for (i=0; i<2; i++) {
549                 printf("\nReading %s OS Feature Descriptor (wIndex = 0x%04d):\n", os_fd[i].desc, os_fd[i].index);
550
551                 // Read the header part
552                 r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|LIBUSB_RECIPIENT_DEVICE),
553                         // NB: We should use os_fd[i].recipient instead of LIBUSB_RECIPIENT_DEVICE above, as
554                         // LIBUSB_RECIPIENT_INTERFACE should be used for the Extended Properties.
555                         // However, for Interface requests, the WinUSB DLL forces the low byte of wIndex
556                         // to the interface number, regardless of what you set it to, so we have to
557                         // fallback to Device and hope the firmware answers both equally.
558                         // See http://www.lvr.com/forum/index.php?topic=331
559                         bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, os_fd[i].header_size, 1000);
560                 if (r < os_fd[i].header_size) {
561                         perr("   Failed: %s", (r<0)?libusb_error_name((enum libusb_error)r):"header size is too small");
562                         return;
563                 }
564                 le_type_punning_IS_fine = (void*)os_desc;
565                 length = *((uint32_t*)le_type_punning_IS_fine);
566                 if (length > MAX_OS_FD_LENGTH) {
567                         length = MAX_OS_FD_LENGTH;
568                 }
569
570                 // Read the full feature descriptor
571                 r = libusb_control_transfer(handle, (uint8_t)(LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_VENDOR|os_fd[i].recipient),
572                         bRequest, (uint16_t)(((iface_number)<< 8)|0x00), os_fd[i].index, os_desc, (uint16_t)length, 1000);
573                 if (r < 0) {
574                         perr("   Failed: %s", libusb_error_name((enum libusb_error)r));
575                         return;
576                 } else {
577                         display_buffer_hex(os_desc, r);
578                 }
579         }
580 }
581
582 static int test_device(uint16_t vid, uint16_t pid)
583 {
584         libusb_device_handle *handle;
585         libusb_device *dev;
586 #ifdef HAS_GETPORTPATH
587         uint8_t bus, port_path[8];
588 #endif
589         struct libusb_config_descriptor *conf_desc;
590         const struct libusb_endpoint_descriptor *endpoint;
591         int i, j, k, r;
592         int iface, nb_ifaces, first_iface = -1;
593 #if defined(__linux)
594         // Attaching/detaching the kernel driver is only relevant for Linux
595         int iface_detached = -1;
596 #endif
597         struct libusb_device_descriptor dev_desc;
598         char* speed_name[5] = { "Unknown", "1.5 Mbit/s (USB 1.0 LowSpeed)", "12 Mbit/s (USB 1.0 FullSpeed)",
599                 "480 Mbit/s (USB 2.0 HighSpeed)", "5000 Mbit/s (USB 3.0 SuperSpeed)"};
600         char string[128];
601         uint8_t string_index[3];        // indexes of the string descriptors
602         uint8_t endpoint_in = 0, endpoint_out = 0;      // default IN and OUT endpoints
603
604         printf("Opening device...\n");
605         handle = libusb_open_device_with_vid_pid(NULL, vid, pid);
606
607         if (handle == NULL) {
608                 perr("  Failed.\n");
609                 return -1;
610         }
611
612         dev = libusb_get_device(handle);
613 #ifdef HAS_GETPORTPATH
614         bus = libusb_get_bus_number(dev);
615         r = libusb_get_port_path(NULL, dev, port_path, sizeof(port_path));
616         if (r > 0) {
617                 printf("bus: %d, port path from HCD: %d", bus, port_path[0]);
618                 for (i=1; i<r; i++) {
619                         printf("->%d", port_path[i]);
620                 }
621                 printf("\n");
622         }
623 #endif
624         r = libusb_get_device_speed(dev);
625         if ((r<0) || (r>4)) r=0;
626         printf("speed: %s\n", speed_name[r]);
627
628         printf("\nReading device descriptor:\n");
629         CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc));
630         printf("            length: %d\n", dev_desc.bLength);
631         printf("      device class: %d\n", dev_desc.bDeviceClass);
632         printf("               S/N: %d\n", dev_desc.iSerialNumber);
633         printf("           VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
634         printf("         bcdDevice: %04X\n", dev_desc.bcdDevice);
635         printf("   iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
636         printf("          nb confs: %d\n", dev_desc.bNumConfigurations);
637         // Copy the string descriptors for easier parsing
638         string_index[0] = dev_desc.iManufacturer;
639         string_index[1] = dev_desc.iProduct;
640         string_index[2] = dev_desc.iSerialNumber;
641
642         printf("\nReading configuration descriptors:\n");
643         CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc));
644         nb_ifaces = conf_desc->bNumInterfaces;
645         printf("             nb interfaces: %d\n", nb_ifaces);
646         if (nb_ifaces > 0)
647                 first_iface = conf_desc->usb_interface[0].altsetting[0].bInterfaceNumber;
648         for (i=0; i<nb_ifaces; i++) {
649                 printf("              interface[%d]: id = %d\n", i,
650                         conf_desc->usb_interface[i].altsetting[0].bInterfaceNumber);
651                 for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) {
652                         printf("interface[%d].altsetting[%d]: num endpoints = %d\n",
653                                 i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints);
654                         printf("   Class.SubClass.Protocol: %02X.%02X.%02X\n",
655                                 conf_desc->usb_interface[i].altsetting[j].bInterfaceClass,
656                                 conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass,
657                                 conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol);
658                         if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE)
659                           && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01)
660                           || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) )
661                           && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) {
662                                 // Mass storage devices that can use basic SCSI commands
663                                 test_mode = USE_SCSI;
664                         }
665                         for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
666                                 endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
667                                 printf("       endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
668                                 // Use the first bulk IN/OUT endpoints found as default for testing
669                                 if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) {
670                                         if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
671                                                 if (!endpoint_in)
672                                                         endpoint_in = endpoint->bEndpointAddress;
673                                         } else {
674                                                 if (!endpoint_out)
675                                                         endpoint_out = endpoint->bEndpointAddress;
676                                         }
677                                 }
678                                 printf("           max packet size: %04X\n", endpoint->wMaxPacketSize);
679                                 printf("          polling interval: %02X\n", endpoint->bInterval);
680                         }
681                 }
682         }
683         libusb_free_config_descriptor(conf_desc);
684
685         for (iface = 0; iface < nb_ifaces; iface++)
686         {
687                 printf("\nClaiming interface %d...\n", iface);
688                 r = libusb_claim_interface(handle, iface);
689 #if defined(__linux)
690                 if ((r != LIBUSB_SUCCESS) && (iface == 0)) {
691                         // Maybe we need to detach the driver
692                         perr("   Failed. Trying to detach driver...\n");
693                         libusb_detach_kernel_driver(handle, iface);
694                         iface_detached = iface;
695                         printf("   Claiming interface again...\n");
696                         r = libusb_claim_interface(handle, iface);
697                 }
698 #endif
699                 if (r != LIBUSB_SUCCESS) {
700                         perr("   Failed.\n");
701                 }
702         }
703
704         printf("\nReading string descriptors:\n");
705         for (i=0; i<3; i++) {
706                 if (string_index[i] == 0) {
707                         continue;
708                 }
709                 if (libusb_get_string_descriptor_ascii(handle, string_index[i], (unsigned char*)string, 128) >= 0) {
710                         printf("   String (0x%02X): \"%s\"\n", string_index[i], string);
711                 }
712         }
713         // Read the OS String Descriptor
714         if (libusb_get_string_descriptor_ascii(handle, 0xEE, (unsigned char*)string, 128) >= 0) {
715                 printf("   String (0x%02X): \"%s\"\n", 0xEE, string);
716                 // If this is a Microsoft OS String Descriptor,
717                 // attempt to read the WinUSB extended Feature Descriptors
718                 if (strncmp(string, "MSFT100", 7) == 0)
719                         read_ms_winsub_feature_descriptors(handle, string[7], first_iface);
720         }
721
722         switch(test_mode) {
723         case USE_PS3:
724                 CALL_CHECK(display_ps3_status(handle));
725                 break;
726         case USE_XBOX:
727                 CALL_CHECK(display_xbox_status(handle));
728                 CALL_CHECK(set_xbox_actuators(handle, 128, 222));
729                 msleep(2000);
730                 CALL_CHECK(set_xbox_actuators(handle, 0, 0));
731                 break;
732         case USE_SCSI:
733                 CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out));
734         default:
735                 break;
736         }
737
738         printf("\n");
739         for (iface = 0; iface<nb_ifaces; iface++) {
740                 printf("Releasing interface %d...\n", iface);
741                 libusb_release_interface(handle, iface);
742         }
743
744 #if defined(__linux)
745         if (iface_detached >= 0) {
746                 printf("Re-attaching kernel driver...\n");
747                 libusb_attach_kernel_driver(handle, iface_detached);
748         }
749 #endif
750
751         printf("Closing device...\n");
752         libusb_close(handle);
753
754         return 0;
755 }
756
757 int main(int argc, char** argv)
758 {
759         bool show_help = false;
760         bool debug_mode = false;
761         const struct libusb_version* version;
762         int j, r;
763         size_t i, arglen;
764         unsigned tmp_vid, tmp_pid;
765         uint16_t endian_test = 0xBE00;
766
767         // Default to generic, expecting VID:PID
768         VID = 0;
769         PID = 0;
770         test_mode = USE_GENERIC;
771
772         if (((uint8_t*)&endian_test)[0] == 0xBE) {
773                 printf("Despite their natural superiority for end users, big endian\n"
774                         "CPUs are not supported with this program, sorry.\n");
775                 return 0;
776         }
777
778         if (argc >= 2) {
779                 for (j = 1; j<argc; j++) {
780                         arglen = strlen(argv[j]);
781                         if ( ((argv[j][0] == '-') || (argv[j][0] == '/'))
782                           && (arglen >= 2) ) {
783                                 switch(argv[j][1]) {
784                                 case 'd':
785                                         debug_mode = true;
786                                         break;
787                                 case 'b':
788                                         strcat(binary_name, "raw.bin");
789                                         if (j+1 < argc) {
790                                                 strncpy(binary_name, argv[j+1], 64);
791                                                 j++;
792                                         }
793                                         binary_dump = true;
794                                         break;
795                                 case 'g':
796                                         break;
797                                 case 'j':
798                                         // OLIMEX ARM-USB-TINY JTAG, 2 channel composite device - 2 interfaces
799                                         if (!VID && !PID) {
800                                                 VID = 0x15BA;
801                                                 PID = 0x0004;
802                                         }
803                                         break;
804                                 case 'k':
805                                         // Generic 2 GB USB Key (SCSI Transparent/Bulk Only) - 1 interface
806                                         if (!VID && !PID) {
807                                                 VID = 0x0204;
808                                                 PID = 0x6025;
809                                         }
810                                         break;
811                                 // The following tests will force VID:PID if already provided
812                                 case 'p':
813                                         // Sony PS3 Controller - 1 interface
814                                         VID = 0x054C;
815                                         PID = 0x0268;
816                                         test_mode = USE_PS3;
817                                         break;
818                                 case 'x':
819                                         // Microsoft XBox Controller Type S - 1 interface
820                                         VID = 0x045E;
821                                         PID = 0x0289;
822                                         test_mode = USE_XBOX;
823                                         break;
824                                 default:
825                                         show_help = true;
826                                         break;
827                                 }
828                         } else {
829                                 for (i=0; i<arglen; i++) {
830                                         if (argv[j][i] == ':')
831                                                 break;
832                                 }
833                                 if (i != arglen) {
834                                         if (sscanf_s(argv[j], "%x:%x" , &tmp_vid, &tmp_pid) != 2) {
835                                                 printf("   Please specify VID & PID as \"vid:pid\" in hexadecimal format\n");
836                                                 return 1;
837                                         }
838                                         VID = (uint16_t)tmp_vid;
839                                         PID = (uint16_t)tmp_pid;
840                                 } else {
841                                         show_help = true;
842                                 }
843                         }
844                 }
845         }
846
847         if ((show_help) || (argc == 1) || (argc > 7)) {
848                 printf("usage: %s [-d] [-b [file]] [-h] [-i] [-j] [-k] [-x] [vid:pid]\n", argv[0]);
849                 printf("   -h: display usage\n");
850                 printf("   -d: enable debug output (if library was compiled with debug enabled)\n");
851                 printf("   -b: dump Mass Storage first block to binary file\n");
852                 printf("   -g: short generic test (default)\n");
853                 printf("   -k: test generic Mass Storage USB device (using WinUSB)\n");
854                 printf("   -j: test FTDI based JTAG device (using WinUSB)\n");
855                 printf("   -p: test Sony PS3 SixAxis controller (using WinUSB)\n");
856                 printf("   -x: test Microsoft XBox Controller Type S (using WinUSB)\n");
857                 return 0;
858         }
859
860         version = libusb_get_version();
861         printf("Using libusbx v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);
862         r = libusb_init(NULL);
863         if (r < 0)
864                 return r;
865
866         // Info = 3, Debug = 4
867         libusb_set_debug(NULL, debug_mode?4:3);
868
869         test_device(VID, PID);
870
871         libusb_exit(NULL);
872
873         return 0;
874 }