|
From: Maxime B. <bla...@gm...> - 2015-02-09 20:06:27
|
Hi guys, I'm having problems claiming an interface on Windows, my code works fine on OSX for example. I tried resetting the device, getting and setting back the configuration, but still have the problem. The rest of the libUsb functions seems to work fine, if I could just get access to the interface.. Thanks in advance if that rings a bell for you and can help. https://maximumtrainer.com *Here is my full code :* #include "utilusb.h" #include <QDebug> #include "libusb.h" UtilUSB::~UtilUSB() { if (handle) { libusb_release_interface(handle, interface); libusb_close(handle); } libusb_exit(NULL); } //-------------------------------------------------------------- UtilUSB::UtilUSB() { handle = NULL; interface = -1; // libusb_context** context; int err = libusb_init(NULL); if (err) qDebug() << "error init libUsb" << libusb_error_name(err); libusb_set_debug(NULL, 2); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// bool UtilUSB::openAntStick() { qDebug() << "findStick"; bool success = false; // discover devices libusb_device **list; libusb_device *foundDevice = NULL; ssize_t cnt = libusb_get_device_list(NULL, &list); ssize_t i = 0; if (cnt < 0) { libusb_free_device_list(list, 1); return false; } // Iterate on all devices to see if we find a Garmin Ant Stick for (i = 0; i < cnt; i++) { libusb_device *device = list[i]; libusb_device_descriptor desc = {0}; libusb_config_descriptor *config; int rc = libusb_get_device_descriptor(device, &desc); if (!rc) { if (desc.idVendor == GARMIN_USB2_VID && (desc.idProduct == GARMIN_USB2_PID || desc.idProduct == GARMIN_OEM_PID)) { qDebug() << "idProduct :" << desc.idProduct; qDebug() << "WE FOUND ANT STICK!"; libusb_get_config_descriptor(device, 0, &config); qDebug() <<"Interfaces: "<<(int)config->bNumInterfaces; const libusb_interface *inter; const libusb_interface_descriptor *interdesc; const libusb_endpoint_descriptor *epdesc; for(int i=0; i<(int)config->bNumInterfaces; i++) { inter = &config->interface[i]; qDebug() <<"Number of alternate settings: "<< inter->num_altsetting; for(int j=0; j<inter->num_altsetting; j++) { interdesc = &inter->altsetting[j]; qDebug() <<"Interface Number: "<< (int)interdesc->bInterfaceNumber; qDebug() <<"Number of endpoints: "<< (int)interdesc->bNumEndpoints; this->interface = (int)interdesc->bInterfaceNumber; for(int k=0; k<(int)interdesc->bNumEndpoints; k++) { epdesc = &interdesc->endpoint[k]; qDebug() <<"Descriptor Type: "<<(int)epdesc->bDescriptorType; qDebug() <<"EP Address: "<<(int)epdesc->bEndpointAddress; if (epdesc->bEndpointAddress & (1 << 7)) { qDebug() << "FOUND LIBUSB_ENDPOINT_IN"; endPointAddressRead = epdesc->bEndpointAddress; } else { qDebug() << "FOUND LIBUSB_ENDPOINT_OUT"; endPointAddressWrite = epdesc->bEndpointAddress; } } } } libusb_free_config_descriptor(config); success = true; foundDevice = device; break; } } } // Did not find a device, leave if (!success) return false; int r = libusb_open(foundDevice, &handle); if (r) { qDebug() << "error openning device" << libusb_error_name(r); // -12 = LIBUSB_ERROR_NOT_SUPPORTED return false; } else { qDebug() << "libusb_open done"; } // Claim interface - Error Access on Windows ATM r = libusb_claim_interface(handle, interface); if (r < 0) { qDebug() << "error claiming interface" << libusb_error_name(r); } else { qDebug() << "claim interface done"; } // Clear halt is needed, but ignore return code // libusb_reset_device ( libusb_device_handle * dev ) Reset the device first? libusb_clear_halt(handle, endPointAddressRead); libusb_clear_halt(handle, endPointAddressWrite); return success; } ////////////////////////////////////////////////////////////////////////////////////////////////// int UtilUSB::read(unsigned char *buf, int bytes) { qDebug() << "reading."; if (handle == NULL || interface == -1) { qDebug() << "not ready to read"; return -1; } else { qDebug() << "Ready to read!"; } int actual_length; int rc = libusb_bulk_transfer(handle, endPointAddressRead, readData, sizeof(readData), &actual_length, 125); // libusb_fill_bulk_transfer(); if (rc == 0 && actual_length == sizeof(readData)) { // results of the transaction can now be found in the data buffer // parse them here and report button press qDebug() << "Read 64, good"; memcpy(buf, readData, 64); } else { qDebug() << "libusb_bulk_transfer error" << libusb_error_name(rc); return rc; } return 1; } ************************************* Here is the log on Windows : findStick idProduct : 4104 WE FOUND ANT STICK! Interfaces: 1 Number of alternate settings: 1 Interface Number: 0 Number of endpoints: 2 Descriptor Type: 5 EP Address: 129 FOUND LIBUSB_ENDPOINT_IN Descriptor Type: 5 EP Address: 1 FOUND LIBUSB_ENDPOINT_OUT libusb_open done error claiming interface LIBUSB_ERROR_ACCESS stick found? true reading. Ready to read! libusb_bulk_transfer error LIBUSB_ERROR_NOT_FOUND rc is: -5 -- libusb: error [winusbx_claim_interface] could not access interface 0: [8] Not enough storage is available to process this command. libusb: error [winusbx_clear_halt] unable to match endpoint to an open interface - cannot clear libusb: error [winusbx_clear_halt] unable to match endpoint to an open interface - cannot clear libusb: error [winusbx_submit_bulk_transfer] unable to match endpoint to an open interface - cancelling transfer |