7 char _debug_buffer[512]; \
8 int _dbg_size = sprintf(_debug_buffer, ##__VA_ARGS__); \
9 sceNetSend(netdbg_sock, _debug_buffer, _dbg_size, 0); \
13 /* Grabbed from libusb/examples/xusb.c */
15 #define ERR_EXIT(errcode) do { debug(" %i\n", errcode); return -1; } while (0)
16 #define CALL_CHECK(fcall) do { r=fcall; if (r < 0) ERR_EXIT(r); } while (0);
17 #define B(x) (((x)!=0)?1:0)
18 #define be_to_int32(buf) (((buf)[0]<<24)|((buf)[1]<<16)|((buf)[2]<<8)|(buf)[3])
21 #define REQUEST_SENSE_LENGTH 0x12
22 #define INQUIRY_LENGTH 0x24
23 #define READ_CAPACITY_LENGTH 0x08
25 // Mass Storage Requests values. See section 3 of the Bulk-Only Mass Storage Class specifications
26 #define BOMS_RESET 0xFF
27 #define BOMS_GET_MAX_LUN 0xFE
29 // Section 5.1: Command Block Wrapper (CBW)
30 struct command_block_wrapper
{
31 uint8_t dCBWSignature
[4];
33 uint32_t dCBWDataTransferLength
;
40 // Section 5.2: Command Status Wrapper (CSW)
41 struct command_status_wrapper
{
42 uint8_t dCSWSignature
[4];
44 uint32_t dCSWDataResidue
;
48 static uint8_t cdb_length
[256] = {
49 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
50 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 0
51 06,06,06,06,06,06,06,06,06,06,06,06,06,06,06,06, // 1
52 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 2
53 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 3
54 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 4
55 10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10, // 5
56 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 6
57 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // 7
58 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 8
59 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16, // 9
60 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // A
61 12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, // B
62 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // C
63 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // D
64 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // E
65 00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00, // F
68 static void display_buffer_hex(unsigned char *buffer
, unsigned size
)
72 for (i
=0; i
<size
; i
+=16) {
74 for(j
=0,k
=0; k
<16; j
++,k
++) {
76 debug("%02x", buffer
[i
+j
]);
83 for(j
=0,k
=0; k
<16; j
++,k
++) {
85 if ((buffer
[i
+j
] < 32) || (buffer
[i
+j
] > 126)) {
88 debug("%c", buffer
[i
+j
]);
96 static int send_mass_storage_command(libusb_device_handle
*handle
, uint8_t endpoint
, uint8_t lun
,
97 uint8_t *cdb
, uint8_t direction
, int data_length
, uint32_t *ret_tag
)
99 static uint32_t tag
= 1;
102 struct command_block_wrapper cbw
;
108 if (endpoint
& LIBUSB_ENDPOINT_IN
) {
109 debug("send_mass_storage_command: cannot send command on IN endpoint\n");
113 cdb_len
= cdb_length
[cdb
[0]];
114 if ((cdb_len
== 0) || (cdb_len
> sizeof(cbw
.CBWCB
))) {
115 debug("send_mass_storage_command: don't know how to handle this command (%02X, length %d)\n",
120 memset(&cbw
, 0, sizeof(cbw
));
121 cbw
.dCBWSignature
[0] = 'U';
122 cbw
.dCBWSignature
[1] = 'S';
123 cbw
.dCBWSignature
[2] = 'B';
124 cbw
.dCBWSignature
[3] = 'C';
127 cbw
.dCBWDataTransferLength
= data_length
;
128 cbw
.bmCBWFlags
= direction
;
130 // Subclass is 1 or 6 => cdb_len
131 cbw
.bCBWCBLength
= cdb_len
;
132 memcpy(cbw
.CBWCB
, cdb
, cdb_len
);
136 // The transfer length must always be exactly 31 bytes.
137 r
= sceUsbdBulkTransfer(handle
, endpoint
, (unsigned char*)&cbw
, 31, &size
, 1000);
138 if (r
== LIBUSB_ERROR_PIPE
) {
139 sceUsbdClearHalt(handle
, endpoint
);
142 } while ((r
== LIBUSB_ERROR_PIPE
) && (i
<RETRY_MAX
));
143 if (r
!= LIBUSB_SUCCESS
) {
144 debug(" send_mass_storage_command\n");
148 debug(" sent %d CDB bytes\n", cdb_len
);
153 static int get_mass_storage_status(libusb_device_handle
*handle
, uint8_t endpoint
, uint32_t expected_tag
)
156 struct command_status_wrapper csw
;
158 // The device is allowed to STALL this transfer. If it does, you have to
159 // clear the stall and try again.
162 r
= sceUsbdBulkTransfer(handle
, endpoint
, (unsigned char*)&csw
, 13, &size
, 1000);
163 if (r
== LIBUSB_ERROR_PIPE
) {
164 sceUsbdClearHalt(handle
, endpoint
);
167 } while ((r
== LIBUSB_ERROR_PIPE
) && (i
<RETRY_MAX
));
168 if (r
!= LIBUSB_SUCCESS
) {
169 debug(" get_mass_storage_status\n");
173 debug(" get_mass_storage_status: received %d bytes (expected 13)\n", size
);
176 if (csw
.dCSWTag
!= expected_tag
) {
177 debug(" get_mass_storage_status: mismatched tags (expected %08X, received %08X)\n",
178 expected_tag
, csw
.dCSWTag
);
181 // For this test, we ignore the dCSWSignature check for validity...
182 debug(" Mass Storage Status: %02X (%s)\n", csw
.bCSWStatus
, csw
.bCSWStatus
?"FAILED":"Success");
183 if (csw
.dCSWTag
!= expected_tag
)
185 if (csw
.bCSWStatus
) {
186 // REQUEST SENSE is appropriate only if bCSWStatus is 1, meaning that the
187 // command failed somehow. Larger values (2 in particular) mean that
188 // the command couldn't be understood.
189 if (csw
.bCSWStatus
== 1)
190 return -2; // request Get Sense
195 // In theory we also should check dCSWDataResidue. But lots of devices
200 static void get_sense(libusb_device_handle
*handle
, uint8_t endpoint_in
, uint8_t endpoint_out
)
202 uint8_t cdb
[16]; // SCSI Command Descriptor Block
204 uint32_t expected_tag
;
209 debug("Request Sense:\n");
210 memset(sense
, 0, sizeof(sense
));
211 memset(cdb
, 0, sizeof(cdb
));
212 cdb
[0] = 0x03; // Request Sense
213 cdb
[4] = REQUEST_SENSE_LENGTH
;
215 send_mass_storage_command(handle
, endpoint_out
, 0, cdb
, LIBUSB_ENDPOINT_IN
, REQUEST_SENSE_LENGTH
, &expected_tag
);
216 rc
= sceUsbdBulkTransfer(handle
, endpoint_in
, (unsigned char*)&sense
, REQUEST_SENSE_LENGTH
, &size
, 1000);
219 debug("sceUsbdBulkTransfer failed\n");
222 debug(" received %d bytes\n", size
);
224 if ((sense
[0] != 0x70) && (sense
[0] != 0x71)) {
225 debug(" ERROR No sense data\n");
227 debug(" ERROR Sense: %02X %02X %02X\n", sense
[2]&0x0F, sense
[12], sense
[13]);
229 // Strictly speaking, the get_mass_storage_status() call should come
230 // before these debug() lines. If the status is nonzero then we must
231 // assume there's no data in the buffer. For xusb it doesn't matter.
232 get_mass_storage_status(handle
, endpoint_in
, expected_tag
);
235 // Mass Storage device to test bulk transfers (non destructive test)
236 static int test_mass_storage(libusb_device_handle
*handle
, uint8_t endpoint_in
, uint8_t endpoint_out
)
240 uint32_t expected_tag
;
241 uint32_t i
, max_lba
, block_size
;
243 uint8_t cdb
[16]; // SCSI Command Descriptor Block
245 char vid
[9], pid
[9], rev
[5];
248 debug("Reading Max LUN:\n");
249 r
= sceUsbdControlTransfer(handle
, LIBUSB_ENDPOINT_IN
|LIBUSB_REQUEST_TYPE_CLASS
|LIBUSB_RECIPIENT_INTERFACE
,
250 BOMS_GET_MAX_LUN
, 0, 0, &lun
, 1, 1000);
251 // Some devices send a STALL instead of the actual value.
252 // In such cases we should set lun to 0.
258 debug(" Max LUN = %d\n", lun
);
261 debug("Sending Inquiry:\n");
262 memset(buffer
, 0, sizeof(buffer
));
263 memset(cdb
, 0, sizeof(cdb
));
264 cdb
[0] = 0x12; // Inquiry
265 cdb
[4] = INQUIRY_LENGTH
;
267 send_mass_storage_command(handle
, endpoint_out
, lun
, cdb
, LIBUSB_ENDPOINT_IN
, INQUIRY_LENGTH
, &expected_tag
);
268 CALL_CHECK(sceUsbdBulkTransfer(handle
, endpoint_in
, (unsigned char*)&buffer
, INQUIRY_LENGTH
, &size
, 1000));
269 debug(" received %d bytes\n", size
);
270 // The following strings are not zero terminated
271 for (i
=0; i
<8; i
++) {
272 vid
[i
] = buffer
[8+i
];
273 pid
[i
] = buffer
[16+i
];
274 rev
[i
/2] = buffer
[32+i
/2]; // instead of another loop
279 debug(" VID:PID:REV \"%8s\":\"%8s\":\"%4s\"\n", vid
, pid
, rev
);
280 if (get_mass_storage_status(handle
, endpoint_in
, expected_tag
) == -2) {
281 get_sense(handle
, endpoint_in
, endpoint_out
);
285 debug("Reading Capacity:\n");
286 memset(buffer
, 0, sizeof(buffer
));
287 memset(cdb
, 0, sizeof(cdb
));
288 cdb
[0] = 0x25; // Read Capacity
290 send_mass_storage_command(handle
, endpoint_out
, lun
, cdb
, LIBUSB_ENDPOINT_IN
, READ_CAPACITY_LENGTH
, &expected_tag
);
291 CALL_CHECK(sceUsbdBulkTransfer(handle
, endpoint_in
, (unsigned char*)&buffer
, READ_CAPACITY_LENGTH
, &size
, 1000));
292 debug(" received %d bytes\n", size
);
293 max_lba
= be_to_int32(&buffer
[0]);
294 block_size
= be_to_int32(&buffer
[4]);
295 device_size
= ((double)(max_lba
+1))*block_size
/(1024*1024*1024);
296 debug(" Max LBA: %08X, Block Size: %08X (%.2f GB)\n", max_lba
, block_size
, device_size
);
297 if (get_mass_storage_status(handle
, endpoint_in
, expected_tag
) == -2) {
298 get_sense(handle
, endpoint_in
, endpoint_out
);
301 // coverity[tainted_data]
302 data
= (unsigned char*) calloc(1, block_size
);
304 debug(" unable to allocate data buffer\n");
309 debug("Attempting to read %d bytes:\n", block_size
);
310 memset(cdb
, 0, sizeof(cdb
));
312 cdb
[0] = 0x28; // Read(10)
313 cdb
[8] = 0x01; // 1 block
315 send_mass_storage_command(handle
, endpoint_out
, lun
, cdb
, LIBUSB_ENDPOINT_IN
, block_size
, &expected_tag
);
316 sceUsbdBulkTransfer(handle
, endpoint_in
, data
, block_size
, &size
, 5000);
317 debug(" READ: received %d bytes\n", size
);
318 if (get_mass_storage_status(handle
, endpoint_in
, expected_tag
) == -2) {
319 get_sense(handle
, endpoint_in
, endpoint_out
);
321 display_buffer_hex(data
, size
);
337 struct sockaddr_in server
;
338 server
.sin_len
= sizeof(server
);
339 server
.sin_family
= AF_INET
;
340 server
.sin_addr
.s_addr
= IP(192, 168, 0, 4);
341 server
.sin_port
= sceNetHtons(9023);
342 memset(server
.sin_zero
, 0, sizeof(server
.sin_zero
));
344 netdbg_sock
= sceNetSocket("netdebug", AF_INET
, SOCK_STREAM
, 0);
345 sceNetConnect(netdbg_sock
, (struct sockaddr
*)&server
, sizeof(server
));
347 uint8_t endpoint_in
= 0, endpoint_out
= 0;
348 int usb_storage_found
= 0;
349 unsigned short usb_stor_vid
;
350 unsigned short usb_stor_pid
;
353 libusb_device
**list
;
354 libusb_device_descriptor desc
;
355 struct libusb_config_descriptor
*config
;
356 const struct libusb_interface
*inter
;
357 const struct libusb_interface_descriptor
*interdesc
;
358 const struct libusb_endpoint_descriptor
*epdesc
;
360 int ret
= sceUsbdInit();
361 debug("sceUsbdInit %d\n", ret
);
363 int count
= sceUsbdGetDeviceList(&list
);
364 debug("Device list count %d\n", count
);
367 for(i
= 0; i
< count
; i
++) {
369 debug("Device %i\n", i
);
371 ret
= sceUsbdGetDeviceDescriptor(list
[i
], &desc
);
372 debug(" Get device descriptor: %d\n", ret
);
374 debug(" Device Class: 0x%02X\n", desc
.bDeviceClass
);
375 debug(" Vendor ID: 0x%04X\n", desc
.idVendor
);
376 debug(" Product ID: 0x%04X\n", desc
.idProduct
);
377 debug(" Number of possible configurations: %i\n", desc
.bNumConfigurations
);
379 ret
= sceUsbdGetConfigDescriptor(list
[i
], 0, &config
);
380 debug("\n Get config descriptor: %d\n", ret
);
382 debug(" Number of interfaces: %i\n\n", config
->bNumInterfaces
);
385 for (j
= 0; j
< config
->bNumInterfaces
; j
++) {
386 debug(" Interface %i\n", j
);
387 inter
= &config
->interface
[j
];
389 debug(" Number of alternate settings: %i\n", inter
->num_altsetting
);
392 for (k
= 0; k
< inter
->num_altsetting
; k
++) {
393 debug(" Interface %i\n", j
);
394 interdesc
= &inter
->altsetting
[j
];
396 debug(" Interface Number: %i\n", interdesc
->bInterfaceNumber
);
397 debug(" Number of endpoints: %i\n", interdesc
->bNumEndpoints
);
399 if ( (interdesc
->bInterfaceClass
== LIBUSB_CLASS_MASS_STORAGE
)
400 && ( (interdesc
->bInterfaceSubClass
== 0x01)
401 || (interdesc
->bInterfaceSubClass
== 0x06) )
402 && (interdesc
->bInterfaceProtocol
== 0x50) ) {
403 usb_storage_found
= 1;
404 usb_stor_vid
= desc
.idVendor
;
405 usb_stor_pid
= desc
.idProduct
;
409 for(l
= 0; l
< interdesc
->bNumEndpoints
; l
++) {
410 debug(" Endpoint %i\n", l
);
411 epdesc
= &interdesc
->endpoint
[l
];
413 debug(" Descriptor Type: 0x%02X\n", epdesc
->bDescriptorType
);
414 debug(" EP Address: 0x%02X\n", epdesc
->bEndpointAddress
);
415 debug(" EP Attributes: 0x%02X\n", epdesc
->bmAttributes
);
417 if ((epdesc
->bmAttributes
& LIBUSB_TRANSFER_TYPE_MASK
) & (LIBUSB_TRANSFER_TYPE_BULK
| LIBUSB_TRANSFER_TYPE_INTERRUPT
)) {
418 if (epdesc
->bEndpointAddress
& LIBUSB_ENDPOINT_IN
) {
420 endpoint_in
= epdesc
->bEndpointAddress
;
423 endpoint_out
= epdesc
->bEndpointAddress
;
430 sceUsbdFreeConfigDescriptor(config
);
433 sceUsbdFreeDeviceList(list
, 1);
435 if (usb_storage_found
) {
436 libusb_device_handle
*handle
;
437 handle
= sceUsbdOpenDeviceWithVidPid(usb_stor_vid
, usb_stor_pid
);
438 test_mass_storage(handle
, endpoint_in
, endpoint_out
);
440 debug("USB storage not found.\n");
445 sceNetSocketClose(netdbg_sock
);