예제 #1
0
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;
}
예제 #2
0
/*! \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);
}