void FCServer::mainLoop() { for (;;) { struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 100000; int err = libusb_handle_events_timeout_completed(mUSB, &timeout, 0); if (err) { std::clog << "Error handling USB events: " << libusb_strerror(libusb_error(err)) << "\n"; // Sometimes this happens on Windows during normal operation if we're queueing a lot of output URBs. Meh. } // We may have been asked for a one-shot poll, to retry connecting devices that failed. if (mPollForDevicesOnce) { mPollForDevicesOnce = false; usbHotplugPoll(); } // Flush completed transfers mEventMutex.lock(); for (std::vector<USBDevice*>::iterator i = mUSBDevices.begin(), e = mUSBDevices.end(); i != e; ++i) { USBDevice *dev = *i; dev->flush(); } mEventMutex.unlock(); } }
bool OpenPortalHandle(libusb_device_handle **phPortalHandle) { int OK; libusb_device **list; ssize_t i = 0; struct libusb_device_descriptor attributes; *phPortalHandle = NULL; libusb_init (&g_ctx); libusb_set_debug(g_ctx,0); ssize_t cnt = libusb_get_device_list(g_ctx, &list); if (cnt < 0) return false; for (i = 0; i < cnt; i++) { libusb_device *device = list[i]; libusb_get_device_descriptor(device,&attributes); if (((attributes.idVendor == 0x12ba) || (attributes.idVendor == 0x54c)) || (attributes.idVendor == 0x1430)) { if ((attributes.idProduct == 0x150) || (attributes.idProduct == 0x967)) { printf("Found portal usb device\n"); int err; libusb_ref_device(device); err= libusb_open(device, phPortalHandle); printf ("usb open: %s\n",libusb_error(err)); err = libusb_claim_interface(*phPortalHandle, 0); printf ("claim interface: %s\n",libusb_error(err)); break; } } } libusb_free_device_list(list, 1); // HidD_GetHidGuid(&guid); // OK = OpenPortalHandleFromGUID(guid, phPortalHandle); return (*phPortalHandle != NULL); }
CameraUSB::CameraUSB() { _ctx = NULL; _devHandle = NULL; _device = NULL; int ret = libusb_init(&_ctx); //initialize the library for the session if(ret < 0) qDebug()<<"Init Error "<<libusb_strerror(libusb_error(ret)); }
bool CameraUSB::write(const QByteArray &array, const int timeOut) { if(!_devHandle) return false; int transferredByte = 0; int ret = libusb_bulk_transfer(_devHandle, _epOut, (unsigned char *)array.data(), array.size(), &transferredByte, timeOut); if(ret != LIBUSB_SUCCESS) { qDebug()<<"Cannot write packet: "<<libusb_strerror(libusb_error(ret)); return false; } return true; }
void FCDevice::submitTransfer(Transfer *fct) { /* * Submit a new USB transfer. The Transfer object is guaranteed to be freed eventually. * On error, it's freed right away. */ int r = libusb_submit_transfer(fct->transfer); if (r < 0) { if (mVerbose && r != LIBUSB_ERROR_PIPE) { std::clog << "Error submitting USB transfer: " << libusb_strerror(libusb_error(r)) << "\n"; } delete fct; } else { mPending.insert(fct); } }
// Send a command to the portal bool Write(libusb_device_handle *hPortalHandle, RWBlock *pb) { int transferred; int err; printf("Write\n"); pb->buf[0] = 0; // Use report 0 fprinthex(stdout,pb->buf,0x21); err = libusb_interrupt_transfer (hPortalHandle, 0x1, pb->buf, 0x21, &transferred, 30000); printf("Write, %d bytes transferred (err = %s)\n",transferred,libusb_error(err)); return err == 0; // return HidD_SetOutputReport(hPortalHandle, pb->buf, 0x21); }
bool CameraUSB::connect(const CameraInfo &info) { int ret; // com settings _vendorId = info.getParam("vendorId").toString().toInt(0, 16); _productId = info.getParam("productId").toString().toInt(0, 16); _epIn = info.getParam("EPIN").toString().toInt(0, 16); _epOut = info.getParam("EPOUT").toString().toInt(0, 16); _interfaceNumber = info.getParam("interface").toString().toInt(0, 16); if(_vendorId == 0 || _productId == 0) { qDebug()<<"USB bad vendorId/productId settings"; return false; } // connect if(info.addr().isEmpty()) { qDebug()<<"addr empty"; _devHandle = libusb_open_device_with_vid_pid(_ctx, _vendorId, _productId); } else { // get list usb device libusb_device **devs; ssize_t cnt = libusb_get_device_list(_ctx, &devs); for(int i = 0; i < cnt; i++) { libusb_device_descriptor desc; if(libusb_get_device_descriptor(devs[i], &desc)==LIBUSB_SUCCESS) { if(desc.idVendor==_vendorId && desc.idProduct==_productId) { QString addr = QString("%1.%2").arg((int)libusb_get_bus_number(devs[i])) .arg((int)libusb_get_device_address(devs[i])); if(addr==info.addr()) { _device = devs[i]; libusb_open(devs[i], &_devHandle); } } } } libusb_free_device_list(devs, 1); } if(_devHandle == NULL) { qDebug()<<"Cannot open device"<<endl; return false; } // reset device if((ret = libusb_reset_device(_devHandle)) != 0) qDebug()<<"Cannot reset device"<<libusb_strerror(libusb_error(ret)); if(libusb_kernel_driver_active(_devHandle, _interfaceNumber) == 1) //find out if kernel driver is attached { printf("Kernel Driver Active\n"); if(libusb_detach_kernel_driver(_devHandle, _interfaceNumber) == 0) //detach it printf("Kernel Driver Detached!\n"); } ret = libusb_claim_interface(_devHandle, _interfaceNumber); if(ret != 0) { qDebug()<<"Cannot claim device"<<libusb_strerror(libusb_error(ret)); return false; } if((ret = libusb_clear_halt(_devHandle, _epOut)) != 0) qDebug()<<"Cannot clear EPOUT"<<libusb_strerror(libusb_error(ret)); if((ret = libusb_clear_halt(_devHandle, _epIn)) != 0) qDebug()<<"Cannot clear EPIN"<<libusb_strerror(libusb_error(ret)); //libusb_set_debug(_ctx, LIBUSB_LOG_LEVEL_DEBUG); //flush(); return true; }
bool FCServer::usbHotplugPoll() { /* * For platforms without libusbx hotplug support, * see if we can fake it by polling for new devices. This can * happen on a different thread, and it probably should. * * We also use this for recovering from transient errors when opening * devices. E.g. a device is reported as added by the hotplug system * but it isn't actually ready to use in userspace yet. * * Returns true on success. */ libusb_device **list; ssize_t listSize; listSize = libusb_get_device_list(mUSB, &list); if (listSize < 0) { std::clog << "Error polling for USB devices: " << libusb_strerror(libusb_error(listSize)) << "\n"; return false; } // Take the lock after get_device_list completes mEventMutex.lock(); // Look for devices that were added for (ssize_t listItem = 0; listItem < listSize; ++listItem) { bool isNew = true; for (std::vector<USBDevice*>::iterator i = mUSBDevices.begin(), e = mUSBDevices.end(); i != e; ++i) { USBDevice *dev = *i; if (dev->getDevice() == list[listItem]) { isNew = false; } } if (isNew) { usbDeviceArrived(list[listItem]); } } // Look for devices that were removed for (std::vector<USBDevice*>::iterator i = mUSBDevices.begin(), e = mUSBDevices.end(); i != e; ++i) { USBDevice *dev = *i; libusb_device *usbdev = dev->getDevice(); bool isRemoved = true; for (ssize_t listItem = 0; listItem < listSize; ++listItem) { if (list[listItem] == usbdev) { isRemoved = false; } } if (isRemoved) { usbDeviceLeft(i); } } mEventMutex.unlock(); libusb_free_device_list(list, true); return true; }
void FCServer::usbDeviceArrived(libusb_device *device) { /* * New USB device. Is this a device we recognize? */ USBDevice *dev; if (FCDevice::probe(device)) { dev = new FCDevice(device, mVerbose); } else if (EnttecDMXDevice::probe(device)) { dev = new EnttecDMXDevice(device, mVerbose); } else { return; } int r = dev->open(); if (r < 0) { if (mVerbose) { switch (r) { // Errors that may occur transiently while a device is connecting... case LIBUSB_ERROR_NOT_FOUND: case LIBUSB_ERROR_NOT_SUPPORTED: #ifdef OS_WINDOWS std::clog << "Waiting for Windows to install " << dev->getName() << " driver. This may take a moment...\n"; #endif #ifdef OS_LINUX // Try again in ~100ms or so. mPollForDevicesOnce = true; #endif break; default: std::clog << "Error opening " << dev->getName() << ": " << libusb_strerror(libusb_error(r)) << "\n"; break; } } delete dev; return; } if (!dev->probeAfterOpening()) { // We were mistaken, this device isn't actually one we want. delete dev; return; } for (unsigned i = 0; i < mDevices.Size(); ++i) { if (dev->matchConfiguration(mDevices[i])) { // Found a matching configuration for this device. We're keeping it! dev->loadConfiguration(mDevices[i]); dev->writeColorCorrection(mColor); mUSBDevices.push_back(dev); if (mVerbose) { std::clog << "USB device " << dev->getName() << " attached.\n"; } jsonConnectedDevicesChanged(); return; } } if (mVerbose) { std::clog << "USB device " << dev->getName() << " has no matching configuration. Not using it.\n"; } delete dev; }
static int check (int e) { if (e < 0) throw usb_error (libusb_error (e)); return e; }
bool ReadBlock(libusb_device_handle *hPortalHandle, unsigned int block, unsigned char data[0x10], bool isNEWskylander) { RWBlock req, res; bool running = true; bool gotData; unsigned char ovlr[OVERLAP_SIZE]; unsigned short err; unsigned char followup; printf("ReadBlock\n"); if(block >= 0x40) { return false; } printf("."); for(int retries = 0; retries < 3; retries++) { // Send query request memset(req.buf, 0, rw_buf_size); req.buf[1] = 'Q'; if(isNEWskylander) { followup = 0x11; if(block == 0) { req.buf[2] = 0x21; } else { req.buf[2] = followup; } } else { followup = 0x10; if(block == 0) { req.buf[2] = 0x20; } else { req.buf[2] = followup; } } req.buf[3] = (unsigned char)block; memset(&(res.buf), 0, rw_buf_size); // Must set the Offset and OffsetHigh members of the OVERLAPPED structure to zero. // memset(&ovlr, 0, sizeof(ovlr)); // ovlr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); // read event int i=0; gotData = false; Write(hPortalHandle, &req); // Don't wait. Start polling for result immediately for(; i<40; ++i) // try up to 40 reads { int b; // bool b = ReadFile(hPortalHandle, res.buf, rw_buf_size, &(res.dwBytesTransferred), &ovlr); b = libusb_interrupt_transfer (hPortalHandle, 0x81, res.buf, rw_buf_size, &(res.dwBytesTransferred), 30000); if (b>=0) fprinthex(stdout,res.buf,res.dwBytesTransferred); if(b<0) { printf("error reading from usb handle: %s\n",libusb_error(b)); /* failed to get data immediately*/ // err = GetLastError(); if(b == 0) { /* wait for data */ // b = GetOverlappedResult(hPortalHandle, &ovlr, &res.dwBytesTransferred, TRUE); if(!b) { /* wait failed */ break; } } else { /* some other error */ break; } } if(res.dwBytesTransferred > 0) { /* has data */ if(res.buf[1] == 'Q' && res.buf[3] == (unsigned char)block) { // Got our query back if(res.buf[2] == followup) { /* got the query back with no error */ gotData = true; break; } } res.buf[0] = 0; // make sure we are using report 0 } } /* read loop */ // CloseHandle(ovlr.hEvent); if(gotData) { break; } } // retries if(gotData) { memcpy(data, res.buf + 4, 0x10); } return gotData; }