Skip to content

Commit 2bb51e1

Browse files
committed
Claim the interface before doing bulk transfers
1 parent a798da2 commit 2bb51e1

File tree

1 file changed

+55
-52
lines changed

1 file changed

+55
-52
lines changed

src/hidapi/libusb/hid.c

Lines changed: 55 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,64 +1337,67 @@ static bool is_ns2(unsigned short idVendor, unsigned short idProduct)
13371337
return false;
13381338
}
13391339

1340-
static bool ns2_find_bulk_out_endpoint(libusb_device_handle* handle, uint8_t* endpoint_out)
1340+
static void init_ns2(libusb_device_handle *device_handle, const struct libusb_config_descriptor *conf_desc)
13411341
{
1342-
struct libusb_config_descriptor* config;
1343-
if (libusb_get_config_descriptor(libusb_get_device(handle), 0, &config) != 0) {
1344-
return false;
1345-
}
1346-
1347-
for (int i = 0; i < config->bNumInterfaces; i++) {
1348-
const struct libusb_interface* iface = &config->interface[i];
1349-
for (int j = 0; j < iface->num_altsetting; j++) {
1350-
const struct libusb_interface_descriptor* altsetting = &iface->altsetting[j];
1351-
if (altsetting->bInterfaceNumber == 1) {
1352-
for (int k = 0; k < altsetting->bNumEndpoints; k++) {
1353-
const struct libusb_endpoint_descriptor* ep = &altsetting->endpoint[k];
1342+
int j, k, l, res;
1343+
1344+
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
1345+
const struct libusb_interface *intf = &conf_desc->interface[j];
1346+
for (k = 0; k < intf->num_altsetting; k++) {
1347+
const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1348+
if (intf_desc->bInterfaceNumber == 1) {
1349+
uint8_t endpoint = 0;
1350+
for (l = 0; l < intf_desc->bNumEndpoints; l++) {
1351+
const struct libusb_endpoint_descriptor* ep = &intf_desc->endpoint[l];
13541352
if ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
1355-
*endpoint_out = ep->bEndpointAddress;
1356-
libusb_free_config_descriptor(config);
1357-
return true;
1353+
endpoint = ep->bEndpointAddress;
1354+
break;
13581355
}
13591356
}
1360-
}
1361-
}
1362-
}
13631357

1364-
libusb_free_config_descriptor(config);
1365-
return false;
1366-
}
1358+
if (endpoint) {
1359+
res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber);
1360+
if (res < 0) {
1361+
LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
1362+
continue;
1363+
}
13671364

1368-
static void init_ns2(libusb_device_handle *device_handle)
1369-
{
1370-
const unsigned char DEFAULT_REPORT_DATA[] = {
1371-
0x03, 0x91, 0x00, 0x0d, 0x00, 0x08,
1372-
0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1373-
};
1374-
const unsigned char SET_LED_DATA[] = {
1375-
0x09, 0x91, 0x00, 0x07, 0x00, 0x08,
1376-
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1377-
};
1365+
const unsigned char DEFAULT_REPORT_DATA[] = {
1366+
0x03, 0x91, 0x00, 0x0d, 0x00, 0x08,
1367+
0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1368+
};
1369+
const unsigned char SET_LED_DATA[] = {
1370+
0x09, 0x91, 0x00, 0x07, 0x00, 0x08,
1371+
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1372+
};
1373+
1374+
int transferred;
1375+
res = libusb_bulk_transfer(device_handle,
1376+
endpoint,
1377+
(unsigned char*)DEFAULT_REPORT_DATA,
1378+
sizeof(DEFAULT_REPORT_DATA),
1379+
&transferred,
1380+
1000);
1381+
if (res < 0) {
1382+
LOG("can't set report data: %d\n", res);
1383+
}
13781384

1379-
uint8_t endpoint_out = 0;
1380-
if (!ns2_find_bulk_out_endpoint(device_handle, &endpoint_out)) {
1381-
return;
1382-
}
1385+
res = libusb_bulk_transfer(device_handle,
1386+
endpoint,
1387+
(unsigned char*)SET_LED_DATA,
1388+
sizeof(SET_LED_DATA),
1389+
&transferred,
1390+
1000);
1391+
if (res < 0) {
1392+
LOG("can't set LED data: %d\n", res);
1393+
}
13831394

1384-
int transferred;
1385-
libusb_bulk_transfer(device_handle,
1386-
endpoint_out,
1387-
(unsigned char*)DEFAULT_REPORT_DATA,
1388-
sizeof(DEFAULT_REPORT_DATA),
1389-
&transferred,
1390-
1000);
1391-
1392-
libusb_bulk_transfer(device_handle,
1393-
endpoint_out,
1394-
(unsigned char*)SET_LED_DATA,
1395-
sizeof(SET_LED_DATA),
1396-
&transferred,
1397-
1000);
1395+
libusb_release_interface(device_handle, intf_desc->bInterfaceNumber);
1396+
return;
1397+
}
1398+
}
1399+
}
1400+
}
13981401
}
13991402

14001403
static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct)
@@ -1458,9 +1461,9 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
14581461
init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
14591462
}
14601463

1461-
/* Initialize NSO GameCube controllers */
1464+
/* Initialize Nintendo Switch 2 controllers */
14621465
if (is_ns2(desc.idVendor, desc.idProduct)) {
1463-
init_ns2(dev->device_handle);
1466+
init_ns2(dev->device_handle, conf_desc);
14641467
}
14651468

14661469
/* Store off the string descriptor indexes */

0 commit comments

Comments
 (0)