@@ -179,6 +179,10 @@ struct hid_device_ {
179
179
int transfer_loop_finished ;
180
180
struct libusb_transfer * transfer ;
181
181
182
+ /* Quirks */
183
+ int skip_output_report_id ;
184
+ int no_output_reports_on_intr_ep ;
185
+
182
186
/* List of received input reports. */
183
187
struct input_report * input_reports ;
184
188
@@ -1329,6 +1333,19 @@ static void init_xboxone(libusb_device_handle *device_handle, unsigned short idV
1329
1333
}
1330
1334
}
1331
1335
1336
+ static void calculate_device_quirks (hid_device * dev , unsigned short idVendor , unsigned short idProduct )
1337
+ {
1338
+ static const int VENDOR_SONY = 0x054c ;
1339
+ static const int PRODUCT_PS3_CONTROLLER = 0x0268 ;
1340
+ static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f ;
1341
+
1342
+ if (idVendor == VENDOR_SONY &&
1343
+ (idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER )) {
1344
+ dev -> skip_output_report_id = 1 ;
1345
+ dev -> no_output_reports_on_intr_ep = 1 ;
1346
+ }
1347
+ }
1348
+
1332
1349
static int hidapi_initialize_device (hid_device * dev , int config_number , const struct libusb_interface_descriptor * intf_desc , const struct libusb_config_descriptor * conf_desc )
1333
1350
{
1334
1351
int i = 0 ;
@@ -1426,6 +1443,8 @@ static int hidapi_initialize_device(hid_device *dev, int config_number, const st
1426
1443
}
1427
1444
}
1428
1445
1446
+ calculate_device_quirks (dev , desc .idVendor , desc .idProduct );
1447
+
1429
1448
pthread_create (& dev -> thread , NULL , read_thread , dev );
1430
1449
1431
1450
/* Wait here for the read thread to be initialized. */
@@ -1591,14 +1610,14 @@ int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t
1591
1610
1592
1611
report_number = data [0 ];
1593
1612
1594
- if (report_number == 0x0 ) {
1613
+ if (report_number == 0x0 || dev -> skip_output_report_id ) {
1595
1614
data ++ ;
1596
1615
length -- ;
1597
1616
skipped_report_id = 1 ;
1598
1617
}
1599
1618
1600
1619
1601
- if (dev -> output_endpoint <= 0 ) {
1620
+ if (dev -> output_endpoint <= 0 || dev -> no_output_reports_on_intr_ep ) {
1602
1621
/* No interrupt out endpoint. Use the Control Endpoint */
1603
1622
res = libusb_control_transfer (dev -> device_handle ,
1604
1623
LIBUSB_REQUEST_TYPE_CLASS |LIBUSB_RECIPIENT_INTERFACE |LIBUSB_ENDPOINT_OUT ,
0 commit comments