Skip to content

Commit 8868a2c

Browse files
committed
Claim the interface before doing bulk transfers
1 parent d235308 commit 8868a2c

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
@@ -1320,64 +1320,67 @@ static bool is_ns2(unsigned short idVendor, unsigned short idProduct)
13201320
return false;
13211321
}
13221322

1323-
static bool ns2_find_bulk_out_endpoint(libusb_device_handle* handle, uint8_t* endpoint_out)
1323+
static void init_ns2(libusb_device_handle *device_handle, const struct libusb_config_descriptor *conf_desc)
13241324
{
1325-
struct libusb_config_descriptor* config;
1326-
if (libusb_get_config_descriptor(libusb_get_device(handle), 0, &config) != 0) {
1327-
return false;
1328-
}
1329-
1330-
for (int i = 0; i < config->bNumInterfaces; i++) {
1331-
const struct libusb_interface* iface = &config->interface[i];
1332-
for (int j = 0; j < iface->num_altsetting; j++) {
1333-
const struct libusb_interface_descriptor* altsetting = &iface->altsetting[j];
1334-
if (altsetting->bInterfaceNumber == 1) {
1335-
for (int k = 0; k < altsetting->bNumEndpoints; k++) {
1336-
const struct libusb_endpoint_descriptor* ep = &altsetting->endpoint[k];
1325+
int j, k, l, res;
1326+
1327+
for (j = 0; j < conf_desc->bNumInterfaces; j++) {
1328+
const struct libusb_interface *intf = &conf_desc->interface[j];
1329+
for (k = 0; k < intf->num_altsetting; k++) {
1330+
const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k];
1331+
if (intf_desc->bInterfaceNumber == 1) {
1332+
uint8_t endpoint = 0;
1333+
for (l = 0; l < intf_desc->bNumEndpoints; l++) {
1334+
const struct libusb_endpoint_descriptor* ep = &intf_desc->endpoint[l];
13371335
if ((ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK && (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT) {
1338-
*endpoint_out = ep->bEndpointAddress;
1339-
libusb_free_config_descriptor(config);
1340-
return true;
1336+
endpoint = ep->bEndpointAddress;
1337+
break;
13411338
}
13421339
}
1343-
}
1344-
}
1345-
}
13461340

1347-
libusb_free_config_descriptor(config);
1348-
return false;
1349-
}
1341+
if (endpoint) {
1342+
res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber);
1343+
if (res < 0) {
1344+
LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
1345+
continue;
1346+
}
13501347

1351-
static void init_ns2(libusb_device_handle *device_handle)
1352-
{
1353-
const unsigned char DEFAULT_REPORT_DATA[] = {
1354-
0x03, 0x91, 0x00, 0x0d, 0x00, 0x08,
1355-
0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1356-
};
1357-
const unsigned char SET_LED_DATA[] = {
1358-
0x09, 0x91, 0x00, 0x07, 0x00, 0x08,
1359-
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1360-
};
1348+
const unsigned char DEFAULT_REPORT_DATA[] = {
1349+
0x03, 0x91, 0x00, 0x0d, 0x00, 0x08,
1350+
0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
1351+
};
1352+
const unsigned char SET_LED_DATA[] = {
1353+
0x09, 0x91, 0x00, 0x07, 0x00, 0x08,
1354+
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
1355+
};
1356+
1357+
int transferred;
1358+
res = libusb_bulk_transfer(device_handle,
1359+
endpoint,
1360+
(unsigned char*)DEFAULT_REPORT_DATA,
1361+
sizeof(DEFAULT_REPORT_DATA),
1362+
&transferred,
1363+
1000);
1364+
if (res < 0) {
1365+
LOG("can't set report data: %d\n", res);
1366+
}
13611367

1362-
uint8_t endpoint_out = 0;
1363-
if (!ns2_find_bulk_out_endpoint(device_handle, &endpoint_out)) {
1364-
return;
1365-
}
1368+
res = libusb_bulk_transfer(device_handle,
1369+
endpoint,
1370+
(unsigned char*)SET_LED_DATA,
1371+
sizeof(SET_LED_DATA),
1372+
&transferred,
1373+
1000);
1374+
if (res < 0) {
1375+
LOG("can't set LED data: %d\n", res);
1376+
}
13661377

1367-
int transferred;
1368-
libusb_bulk_transfer(device_handle,
1369-
endpoint_out,
1370-
(unsigned char*)DEFAULT_REPORT_DATA,
1371-
sizeof(DEFAULT_REPORT_DATA),
1372-
&transferred,
1373-
1000);
1374-
1375-
libusb_bulk_transfer(device_handle,
1376-
endpoint_out,
1377-
(unsigned char*)SET_LED_DATA,
1378-
sizeof(SET_LED_DATA),
1379-
&transferred,
1380-
1000);
1378+
libusb_release_interface(device_handle, intf_desc->bInterfaceNumber);
1379+
return;
1380+
}
1381+
}
1382+
}
1383+
}
13811384
}
13821385

13831386
static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct)
@@ -1441,9 +1444,9 @@ static int hidapi_initialize_device(hid_device *dev, const struct libusb_interfa
14411444
init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc);
14421445
}
14431446

1444-
/* Initialize NSO GameCube controllers */
1447+
/* Initialize Nintendo Switch 2 controllers */
14451448
if (is_ns2(desc.idVendor, desc.idProduct)) {
1446-
init_ns2(dev->device_handle);
1449+
init_ns2(dev->device_handle, conf_desc);
14471450
}
14481451

14491452
/* Store off the string descriptor indexes */

0 commit comments

Comments
 (0)