BOOL WiiMouse_DrvUtil_GetInterfaceHandles(WiiMouse_HandleInfo_t *handleInfo) { BOOL retval = FALSE; UCHAR interfaceIndex = 0; UCHAR pipeIndex = 0; USB_INTERFACE_DESCRIPTOR usbInterfaceDesc; WINUSB_PIPE_INFORMATION pipeInfo; while( WinUsb_QueryInterfaceSettings(handleInfo->winUsbHandle, interfaceIndex, &usbInterfaceDesc) ) { if( _IsValidInterface(&usbInterfaceDesc) ) { break; } interfaceIndex++; } if( GetLastError() == ERROR_INVALID_HANDLE ) { WiiMouse_AddMsg(DERR,"Error, WinUsb_QueryInterfaceSettings invalid handle\n"); return FALSE; } if( !WinUsb_GetAssociatedInterface(handleInfo->winUsbHandle, interfaceIndex, &handleInfo->interfaceHandle) ) { DWORD err = GetLastError(); if( err != ERROR_ALREADY_EXISTS ) { WiiMouse_AddMsg(DERR,"Error, WinUsb_GetAssociatedInterface failed: %d\n", err); return FALSE; } else { handleInfo->interfaceHandle = handleInfo->winUsbHandle; handleInfo->interfaceId = 0; } } handleInfo->interfaceId = interfaceIndex; for( pipeIndex = 0; pipeIndex < usbInterfaceDesc.bNumEndpoints; pipeIndex++ ) { if( !WinUsb_QueryPipe(handleInfo->winUsbHandle, interfaceIndex, pipeIndex, &pipeInfo) ) { WiiMouse_AddMsg(DERR,"Error, WinUsb_QueryPipe failed: %d\n", GetLastError()); retval = FALSE; break; } else { _SetEndpoint(handleInfo, &pipeInfo); } } /* if( !_ValidateEndpoints(handleInfo) ) { WiiMouse_AddMsg(DERR,"Error, endpoint validation failed\n"); retval = FALSE; }*/ if( !retval ) { WinUsb_Free(handleInfo->interfaceHandle); } return retval; }
/*! \brief Open a communcation channel to the given USB port name. */ XsResultValue UsbInterface::open(const XsPortInfo &portInfo, uint32_t, uint32_t) { d->m_endTime = 0; #ifdef USE_WINUSB JLDEBUG(gJournal, "Open usb port " << portInfo.portName().toStdString()); #else JLDEBUG(gJournal, "Open usb port " << portInfo.usbBus() << ":" << portInfo.usbAddress()); #endif if (isOpen()) { JLALERT(gJournal, "Port " << portInfo.portName().toStdString() << " already open"); return (d->m_lastResult = XRV_ALREADYOPEN); } #ifdef USE_WINUSB d->m_deviceHandle = CreateFileA(portInfo.portName().c_str(), GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); if (d->m_deviceHandle == INVALID_HANDLE_VALUE) { d->m_deviceHandle = NULL; return (d->m_lastResult = XRV_PORTNOTFOUND); } BOOL result = FALSE; UCHAR speed = 0; ULONG length = 0; USB_INTERFACE_DESCRIPTOR interfaceDescriptor = {0,0,0,0,0,0,0,0,0}; WINUSB_PIPE_INFORMATION pipeInfo; result = WinUsb_Initialize(d->m_deviceHandle, &d->m_usbHandle[0]); if (result) { result = WinUsb_GetAssociatedInterface(d->m_usbHandle[0],0,&d->m_usbHandle[1]); } else { #ifdef XSENS_DEBUG DWORD err = GetLastError(); assert(result); #endif return (d->m_lastResult = XRV_ERROR); } for (int k = 0; k<2;k++) { if(result) { assert(d->m_usbHandle[k] != 0); length = sizeof(UCHAR); result = WinUsb_QueryDeviceInformation(d->m_usbHandle[k], DEVICE_SPEED, &length, &speed); } if(result) { d->m_deviceSpeed = speed; result = WinUsb_QueryInterfaceSettings(d->m_usbHandle[k], 0, &interfaceDescriptor); } if(result) { for(int i=0;i<interfaceDescriptor.bNumEndpoints;i++) { result = WinUsb_QueryPipe(d->m_usbHandle[k], 0, (UCHAR) i, &pipeInfo); if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId)) { d->m_bulkInPipe = pipeInfo.PipeId; d->m_bulkInPipePacketSize = pipeInfo.MaximumPacketSize; } else if(pipeInfo.PipeType == UsbdPipeTypeBulk && USB_ENDPOINT_DIRECTION_OUT(pipeInfo.PipeId)) { d->m_bulkOutPipe = pipeInfo.PipeId; } else if(pipeInfo.PipeType == UsbdPipeTypeInterrupt) { d->m_interruptPipe = pipeInfo.PipeId; } else { result = FALSE; break; } } } } setTimeout(0); //lint !e534 flushData(); //lint !e534 sprintf(d->m_portname, "%s", portInfo.portName().c_str()); // d->m_offset = 0; ::ResetEvent(&d->m_quitEvent); //lint !e534 d->m_threadHandle = xsStartThread(usbReadThreadFunc, d, &d->m_threadId); if (d->m_threadHandle == XSENS_INVALID_THREAD) { #ifdef XSENS_DEBUG assert(0); #endif return (d->m_lastResult = XRV_ERROR); } #else // !USE_WINUSB static UsbInterfacePrivate::UsbContext contextManager; //m_contextManager; libusb_device **deviceList; ssize_t listLength = libusb_get_device_list(contextManager.m_usbContext /*d->m_contextManager.m_usbContext*/, &deviceList); if (listLength < 0) return d->m_lastResult = d->libusbErrorToXrv((int)listLength); // "USBxxx:yyy" uint8_t bus = XsPortInfo_usbBus(&portInfo); uint8_t address = XsPortInfo_usbAddress(&portInfo); XsResultValue xrv = XRV_OK; int result; libusb_device *device = NULL; for (int i = 0; i < listLength && device == NULL; ++i) { libusb_device *dev = deviceList[i]; if (libusb_get_bus_number(dev) != bus || libusb_get_device_address(dev) != address) continue; libusb_device_descriptor desc; result = libusb_get_device_descriptor(dev, &desc); if (result != LIBUSB_SUCCESS) break; libusb_config_descriptor *configDesc; result = libusb_get_active_config_descriptor(dev, &configDesc); if (result != LIBUSB_SUCCESS) break; d->m_interface = -1; d->m_interfaceCount = configDesc->bNumInterfaces; // find the bulk transfer endpoints for (uint8_t ifCount = 0; ifCount < configDesc->bNumInterfaces && d->m_interface == -1; ++ifCount) { for (uint8_t altsettingCount = 0; altsettingCount < configDesc->interface[ifCount].num_altsetting; altsettingCount++) { const libusb_endpoint_descriptor *endpoints = configDesc->interface[ifCount].altsetting[altsettingCount].endpoint; int inEndpoint = -1, outEndpoint = -1; for (uint8_t i = 0; i < configDesc->interface[ifCount].altsetting[altsettingCount].bNumEndpoints; i++) { if ((endpoints[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK) continue; switch (endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK) { case LIBUSB_ENDPOINT_IN: inEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; case LIBUSB_ENDPOINT_OUT: outEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK; break; } } if (outEndpoint == -1 || inEndpoint == -1) continue; d->m_interface = ifCount; d->m_dataOutEndPoint = outEndpoint; d->m_dataInEndPoint = inEndpoint; } } if (d->m_interface == -1) { xrv = XRV_INPUTCANNOTBEOPENED; break; } libusb_free_config_descriptor(configDesc); libusb_ref_device(dev); device = dev; result = LIBUSB_SUCCESS; } libusb_free_device_list(deviceList, 1); if (result != LIBUSB_SUCCESS) { libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } if (xrv != XRV_OK) { libusb_unref_device(device); return d->m_lastResult = xrv; } libusb_device_handle *handle; result = libusb_open(device, &handle); if (result != LIBUSB_SUCCESS) { libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } // be rude and claim all interfaces for (int i = 0; i < d->m_interfaceCount; i++) { result = libusb_kernel_driver_active(handle, i); if (result > 0) result = libusb_detach_kernel_driver(handle, i); if (result == LIBUSB_SUCCESS) result = libusb_claim_interface(handle, i); if (result != LIBUSB_SUCCESS) { for (int j = 0; j < i; j++) { while (result != LIBUSB_SUCCESS) { result = libusb_release_interface(handle, j); libusb_attach_kernel_driver(handle, j); } } libusb_close(handle); libusb_unref_device(device); return d->m_lastResult = d->libusbErrorToXrv(result); } } d->m_deviceHandle = handle; sprintf(d->m_portname, "%s", portInfo.portName().c_str()); flushData(); #endif // !USE_WINUSB JLDEBUG(gJournal, "USB Port opened"); return (d->m_lastResult = XRV_OK); }