XN_C_API XnStatus xnUSBGetInterface(XN_USB_DEV_HANDLE pDevHandle, XnUInt8* pnInterface, XnUInt8* pnAltInterface) { // Local variables XnBool bResult = FALSE; ULONG nRetBytes = 0; PSUSBDRV_INTERFACE_PROPERTY InterfaceProp; // Validate xnUSB XN_VALIDATE_USB_INIT(); XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pnInterface); XN_VALIDATE_OUTPUT_PTR(pnAltInterface); // Do the get interface bResult = DeviceIoControl(pDevHandle->hUSBDevHandle, IOCTL_PSDRV_GET_INTERFACE, NULL, 0, &InterfaceProp, sizeof(PSUSBDRV_INTERFACE_PROPERTY), &nRetBytes, NULL); if (bResult == FALSE) { return (XN_STATUS_USB_GET_INTERFACE_FAILED); } // Update the data... *pnInterface = InterfaceProp.nIF; *pnAltInterface = InterfaceProp.nAltIF; // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBIsDevicePresent(XnUInt16 nVendorID, XnUInt16 nProductID, void* pExtraParam, XnBool* pbDevicePresent) { XnStatus nRetVal = XN_STATUS_OK; // make sure library was initialized XN_VALIDATE_USB_INIT(); // Validate parameters XN_VALIDATE_OUTPUT_PTR(pbDevicePresent); *pbDevicePresent = FALSE; libusb_device* pDevice; nRetVal = FindDevice(nVendorID, nProductID, pExtraParam, &pDevice); XN_IS_STATUS_OK(nRetVal); if (pDevice != NULL) { *pbDevicePresent = TRUE; // unref device libusb_unref_device(pDevice); } return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBGetDeviceSpeed(XN_USB_DEV_HANDLE pDevHandle, XnUSBDeviceSpeed* pDevSpeed) { // validate parameters XN_VALIDATE_USB_INIT(); XN_VALIDATE_DEVICE_HANDLE(pDevHandle); XN_VALIDATE_OUTPUT_PTR(pDevSpeed); *pDevSpeed = pDevHandle->nDevSpeed; return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBGetDeviceSpeed(XN_USB_DEV_HANDLE pDevHandle, XnUSBDeviceSpeed* pDevSpeed) { // Validate xnUSB XN_VALIDATE_USB_INIT(); XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pDevSpeed); // Update the data... *pDevSpeed = pDevHandle->nDevSpeed; // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBCloseDevice(XN_USB_DEV_HANDLE pDevHandle) { // Validate xnUSB XN_VALIDATE_USB_INIT(); XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle); // Close the device handle CloseHandle(pDevHandle->hUSBDevHandle); // Free the device handle xnOSFreeAligned(pDevHandle); // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBSetInterface(XN_USB_DEV_HANDLE pDevHandle, XnUInt8 nInterface, XnUInt8 nAltInterface) { // validate parameters XN_VALIDATE_USB_INIT(); XN_VALIDATE_DEVICE_HANDLE(pDevHandle); int rc = libusb_set_interface_alt_setting(pDevHandle->hDevice, nInterface, nAltInterface); if (rc != 0) { return (XN_STATUS_USB_SET_INTERFACE_FAILED); } pDevHandle->nInterface = nInterface; pDevHandle->nAltSetting = nAltInterface; return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBCloseDevice(XN_USB_DEV_HANDLE pDevHandle) { // validate parameters XN_VALIDATE_USB_INIT(); XN_VALIDATE_DEVICE_HANDLE(pDevHandle); int rc = libusb_release_interface(pDevHandle->hDevice, pDevHandle->nInterface); if (0 != rc) { return (XN_STATUS_USB_DEVICE_CLOSE_FAILED); } libusb_close(pDevHandle->hDevice); XN_FREE_AND_NULL(pDevHandle); return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBOpenDevice(XnUInt16 nVendorID, XnUInt16 nProductID, void* pExtraParam, void* pExtraParam2, XN_USB_DEV_HANDLE* pDevHandlePtr) { XnStatus nRetVal = XN_STATUS_OK; // make sure library was initialized XN_VALIDATE_USB_INIT(); // Validate parameters XN_VALIDATE_OUTPUT_PTR(pDevHandlePtr); libusb_device* pDevice; nRetVal = FindDevice(nVendorID, nProductID, pExtraParam, &pDevice); XN_IS_STATUS_OK(nRetVal); nRetVal = xnUSBOpenDeviceImpl(pDevice, pDevHandlePtr); XN_IS_STATUS_OK(nRetVal); return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr) { // Local variables XnBool bResult = TRUE; XnStatus nRetVal = XN_STATUS_OK; XnInt32 nRetBytes = 0; XnChar pConfigDescBuf[MAX_CONFIG_DESC_SIZE]; XnChar* pBuf = NULL; PUSB_CONFIGURATION_DESCRIPTOR pUSBConfigDesc = NULL; PUSB_INTERFACE_DESCRIPTOR pUSBInterfaceDesc = NULL; PUSB_ENDPOINT_DESCRIPTOR pUSBEndPointDesc = NULL; XN_USB_EP_HANDLE pEPHandle = NULL; XnChar cpPipeID[3]; // Validate xnUSB XN_VALIDATE_USB_INIT(); XN_VALIDATE_USB_PDEV_HANDLE(pDevHandle); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pEPHandlePtr); // Allocate a new xnUSB EP handle XN_VALIDATE_ALIGNED_CALLOC(*pEPHandlePtr, xnUSBEPHandle, 1, XN_DEFAULT_MEM_ALIGN); pEPHandle = *pEPHandlePtr; // Read the config descriptor bResult = DeviceIoControl(pDevHandle->hUSBDevHandle, IOCTL_PSDRV_GET_CONFIG_DESCRIPTOR, pConfigDescBuf, sizeof(pConfigDescBuf), pConfigDescBuf, sizeof(pConfigDescBuf), (PULONG)&nRetBytes, NULL); if (bResult) { XnUInt32 nIFIdx = 0; UCHAR nEPIdx = 0; XnUInt32 nUBBEPType = 0; XnUInt32 nCurrIF = 0; pBuf = pConfigDescBuf; pUSBConfigDesc = (PUSB_CONFIGURATION_DESCRIPTOR)pBuf; pBuf += pUSBConfigDesc->bLength; // Scan all the interfaces do { pUSBInterfaceDesc = (PUSB_INTERFACE_DESCRIPTOR)pBuf; pBuf += pUSBInterfaceDesc->bLength; // Scan all the endpoints for (nEPIdx = 0; nEPIdx < pUSBInterfaceDesc->bNumEndpoints; nEPIdx++) { pUSBEndPointDesc = (PUSB_ENDPOINT_DESCRIPTOR)pBuf; // Is this the EP we're looking for? if ((pUSBEndPointDesc->bEndpointAddress == nEndPointID) && (pDevHandle->nAltInterface == nCurrIF)) { // Get the EP type nUBBEPType = pUSBEndPointDesc->bmAttributes & USB_ENDPOINT_TYPE_MASK; // Verify that the EP type matches the requested EP if (nEPType == XN_USB_EP_BULK) { if (nUBBEPType != USB_ENDPOINT_TYPE_BULK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else if (nEPType == XN_USB_EP_INTERRUPT) { if (nUBBEPType != USB_ENDPOINT_TYPE_INTERRUPT) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else if (nEPType == XN_USB_EP_ISOCHRONOUS) { if (nUBBEPType != USB_ENDPOINT_TYPE_ISOCHRONOUS) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_TYPE); } } else { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_UNKNOWN_ENDPOINT_TYPE); } // Verify that the EP direction matches the requested direction if (nDirType == XN_USB_DIRECTION_IN) { if (USB_ENDPOINT_DIRECTION_IN(pUSBEndPointDesc->bEndpointAddress) == FALSE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION); } } else if (nDirType == XN_USB_DIRECTION_OUT) { if (USB_ENDPOINT_DIRECTION_OUT(pUSBEndPointDesc->bEndpointAddress) == FALSE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_WRONG_ENDPOINT_DIRECTION); } } else { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_UNKNOWN_ENDPOINT_DIRECTION); } // Construct the pipe file name pEPHandle->cpPipeName[0] = 0; cpPipeID[0] = '0'; cpPipeID[1] = '0' + nEPIdx; cpPipeID[2] = 0; StringCchCopy(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, pDevHandle->cpDeviceName); StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, PSDRV_PIPE_PREFIX); StringCchCat(pEPHandle->cpPipeName, MAX_DEVICE_STR_LENGTH, cpPipeID); // Open the regular pipe handle pEPHandle->hEPHandle = CreateFile(pEPHandle->cpPipeName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (pEPHandle->hEPHandle == INVALID_HANDLE_VALUE) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED); } // Init the overlapped I/O structs nRetVal = xnUSBInitOvlp(pEPHandle); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (XN_STATUS_USB_OPEN_ENDPOINT_FAILED); } // Init the ThreadData variables xnOSMemSet(&pEPHandle->ThreadData, 0, sizeof(xnUSBReadThreadData)); pEPHandle->ThreadData.bInUse = FALSE; // Init the default endpoint properties pEPHandle->nTimeOut = XN_USB_DEFAULT_EP_TIMEOUT; pEPHandle->nEPType = nEPType; pEPHandle->nEPDir = nDirType; pEPHandle->nEndPointID = nEndPointID; // Set the default endpoint timeout nRetVal = xnUSBSetPipeProperty(pEPHandle, PSUSBDRV_PIPE_PROPERTY_TIMEOUT, XN_USB_DEFAULT_EP_TIMEOUT); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pEPHandle); return (nRetVal); } if (nUBBEPType == USB_ENDPOINT_TYPE_ISOCHRONOUS) { // bits 11 and 12 mark the number of additional transactions, bits 0-10 mark the size XnUInt32 nAdditionalTransactions = pUSBEndPointDesc->wMaxPacketSize >> 11; XnUInt32 nPacketSize = pUSBEndPointDesc->wMaxPacketSize & 0x7FF; pEPHandle->nMaxPacketSize = (nAdditionalTransactions + 1) * (nPacketSize); } else { pEPHandle->nMaxPacketSize = pUSBEndPointDesc->wMaxPacketSize; } // Mark the endpoint as valid pEPHandle->bValid = TRUE; // The end... (Happy) return (XN_STATUS_OK); } pBuf += pUSBEndPointDesc->bLength; }
XnStatus xnUSBOpenDeviceImpl(const XnChar* strDevicePath, XN_USB_DEV_HANDLE* pDevHandlePtr) { // Local variables XnStatus nRetVal = XN_STATUS_OK; LPCGUID pInterfaceGuid = NULL; XN_USB_DEV_HANDLE pDevHandle = NULL; ULONG nNumberDevices = 0; HDEVINFO hDevInfo = NULL; BOOLEAN bDone = FALSE; SP_DEVICE_INTERFACE_DATA devInterfaceData; PUSB_DEVICE_DESCRIPTOR pUsbDeviceInst = NULL; PUSB_DEVICE_DESCRIPTOR* ppUsbDevices = &pUsbDeviceInst; PUSB_DEVICE_DESCRIPTOR pTempDevDesc = NULL; ULONG nIdx = 0; HANDLE hSelectedDevice = INVALID_HANDLE_VALUE; PSUSBDRV_DRIVER_VERSION UsbDriverVersion; PSUSBDRV_INTERFACE_PROPERTY pInterfaceProp; // Validate xnUSB XN_VALIDATE_USB_INIT(); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pDevHandlePtr); // Allocate a new xnUSB Device handle XN_VALIDATE_ALIGNED_CALLOC(*pDevHandlePtr, XnUSBDeviceHandle, 1, XN_DEFAULT_MEM_ALIGN); pDevHandle = *pDevHandlePtr; // Get Device Path pInterfaceGuid = &GUID_CLASS_PSDRV_USB; // See if the driver is installed hDevInfo = SetupDiGetClassDevs (pInterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (hDevInfo == INVALID_HANDLE_VALUE) { // No devices are present... XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (XN_STATUS_USB_DRIVER_NOT_FOUND); } // Guess how much devices we're going to have. If it's too little, we'll realloc it soon. nNumberDevices = 4; // Scan the hardware for any devices that are attached to our driver. Stop only after we have successfully opened a device. devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); nIdx = 0; bDone = FALSE; while (!bDone) { // Allocate enough memory for all the devices that are attached to the driver nNumberDevices *= 2; if (*ppUsbDevices) { pTempDevDesc = (USB_DEVICE_DESCRIPTOR*)realloc(*ppUsbDevices, (nNumberDevices * sizeof (USB_DEVICE_DESCRIPTOR))); if(pTempDevDesc) { // We have enough memory! *ppUsbDevices = pTempDevDesc; pTempDevDesc = NULL; } else { // Out of memory... realloc failed... free(*ppUsbDevices); *ppUsbDevices = NULL; } } else { *ppUsbDevices = (USB_DEVICE_DESCRIPTOR*)calloc (nNumberDevices, sizeof (USB_DEVICE_DESCRIPTOR)); } // Make sure we have found some devices if (NULL == *ppUsbDevices) { SetupDiDestroyDeviceInfoList(hDevInfo); XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (XN_STATUS_USB_DEVICE_GETINFO_FAILED); } pUsbDeviceInst = *ppUsbDevices + nIdx; // Scan all the devices that are attached to the driver. Stop when one of them open successfully. for (; nIdx < nNumberDevices; nIdx++) { // Get information about the device if (SetupDiEnumDeviceInterfaces (hDevInfo, 0, pInterfaceGuid, nIdx, &devInterfaceData)) { // Try to open this device hSelectedDevice = xnUSBOpenOneDevice(hDevInfo, &devInterfaceData, pDevHandle->cpDeviceName, strDevicePath); if (hSelectedDevice != INVALID_HANDLE_VALUE) { // Success! We have a valid device handle. bDone = TRUE; break; } } else { // Did we reach the end? if (ERROR_NO_MORE_ITEMS == GetLastError()) { // Yup... and we didn't find any devices... bDone = TRUE; break; } } } } // Save the number of devices nNumberDevices = nIdx; // Cleanup memory SetupDiDestroyDeviceInfoList (hDevInfo); free (*ppUsbDevices); // Do we have a valid device? if (hSelectedDevice == INVALID_HANDLE_VALUE) { // Nope... XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (XN_STATUS_USB_DEVICE_NOT_FOUND); } // Save the device handle pDevHandle->hUSBDevHandle = hSelectedDevice; // Get the device speed nRetVal = xnUSBGetDeviceSpeedInternal(pDevHandle, &pDevHandle->nDevSpeed); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } // Get the driver version nRetVal = xnUSBGetDriverVersion(pDevHandle, &UsbDriverVersion); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } xnLogVerbose(XN_MASK_USB, "USB Driver Version is: %d.%d.%d.%d", UsbDriverVersion.nMajor, UsbDriverVersion.nMinor, UsbDriverVersion.nMaintenance, UsbDriverVersion.nBuild); // Mark the device handle as valid pDevHandle->bValid = TRUE; // Read the current alt-if settings nRetVal = xnUSBGetInterface(pDevHandle, &pInterfaceProp.nIF, &pInterfaceProp.nAltIF); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } pDevHandle->nAltInterface = pInterfaceProp.nAltIF; xnLogVerbose(XN_MASK_USB, "USB Driver Current Alt Setting is: %d", pDevHandle->nAltInterface); // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBEnumerateDevices(XnUInt16 nVendorID, XnUInt16 nProductID, const XnUSBConnectionString** pastrDevicePaths, XnUInt32* pnCount) { // support up to 30 devices XnUSBConnectionString cpUSBID; XnUSBConnectionString cpUSBPathCmp; XnUSBConnectionString aNames[MAX_POTENTIAL_DEVICES]; HDEVINFO hDevInfo = NULL; ULONG nDevices = 0; XnUInt32 nFoundDevices = 0; SP_DEVICE_INTERFACE_DATA devInterfaceData; XnBool bReachedEnd = FALSE; // Validate xnUSB XN_VALIDATE_USB_INIT(); LPCGUID pInterfaceGuid = &GUID_CLASS_PSDRV_USB; // See if the driver is installed hDevInfo = SetupDiGetClassDevs (pInterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (hDevInfo == INVALID_HANDLE_VALUE) { // No devices are present... return (XN_STATUS_USB_DRIVER_NOT_FOUND); } // Scan the hardware for any devices that are attached to our driver. devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); while (nDevices < MAX_POTENTIAL_DEVICES) { // Get information about the device if (SetupDiEnumDeviceInterfaces(hDevInfo, 0, pInterfaceGuid, nDevices, &devInterfaceData)) { PSP_DEVICE_INTERFACE_DETAIL_DATA pDevInterfaceDetailData = NULL; ULONG nPredictedLength = 0; ULONG nRequiredLength = 0; // Probe how much memory is needed to read the device info SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, NULL, 0, &nRequiredLength, NULL); // Allocate memory for the device info nPredictedLength = nRequiredLength; pDevInterfaceDetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(nPredictedLength); if(pDevInterfaceDetailData == NULL) { // Not enough memory... return XN_STATUS_ALLOC_FAILED; } // Read the device info pDevInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); if (!SetupDiGetDeviceInterfaceDetail(hDevInfo, &devInterfaceData, pDevInterfaceDetailData, nPredictedLength, &nRequiredLength, NULL)) { // Something bad has happened... free(pDevInterfaceDetailData); return XN_STATUS_ERROR; } // Make sure we have the right VID/PID cpUSBID[0] = 0; sprintf_s (cpUSBID, "vid_%04x&pid_%04x", nVendorID, nProductID); cpUSBPathCmp[0] = 0; StringCchCopy(cpUSBPathCmp, MAX_DEVICE_STR_LENGTH, pDevInterfaceDetailData->DevicePath); if (strstr(_strlwr(cpUSBPathCmp), cpUSBID) != 0) { StringCchCopy(aNames[nFoundDevices], MAX_DEVICE_STR_LENGTH, pDevInterfaceDetailData->DevicePath); ++nFoundDevices; } ++nDevices; } else if (ERROR_NO_MORE_ITEMS == GetLastError()) { // no more devices bReachedEnd = TRUE; break; } } SetupDiDestroyDeviceInfoList(hDevInfo); if (!bReachedEnd) { // we probably passed our limit XN_LOG_ERROR_RETURN(XN_STATUS_ERROR, XN_MASK_USB, "Found more than %d devices! This is not supported.", MAX_POTENTIAL_DEVICES); } XnUSBConnectionString* pNames; XN_VALIDATE_CALLOC(pNames, XnUSBConnectionString, nFoundDevices); xnOSMemCopy(pNames, aNames, sizeof(XnUSBConnectionString) * nFoundDevices); *pastrDevicePaths = pNames; *pnCount = nFoundDevices; // All is good... return (XN_STATUS_OK); }
XN_C_API XnStatus xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr) { // validate parameters XN_VALIDATE_USB_INIT(); XN_VALIDATE_DEVICE_HANDLE(pDevHandle); XN_VALIDATE_OUTPUT_PTR(pEPHandlePtr); // get the device from the handle libusb_device* pDevice = libusb_get_device(pDevHandle->hDevice); // get the configuration descriptor libusb_config_descriptor* pConfig; int rc = libusb_get_active_config_descriptor(pDevice, &pConfig); if (rc != 0) { return (XN_STATUS_USB_CONFIG_QUERY_FAILED); } // make sure configuration contains the interface we need if (pConfig->bNumInterfaces <= pDevHandle->nInterface) { libusb_free_config_descriptor(pConfig); return (XN_STATUS_USB_INTERFACE_QUERY_FAILED); } // take that interface const libusb_interface* pInterface = &pConfig->interface[pDevHandle->nInterface]; // make sure interface contains the alternate setting we work with if (pInterface->num_altsetting <= pDevHandle->nAltSetting) { libusb_free_config_descriptor(pConfig); return (XN_STATUS_USB_INTERFACE_QUERY_FAILED); } // take that setting const libusb_interface_descriptor* pInterfaceDesc = &pInterface->altsetting[pDevHandle->nAltSetting]; // search for the requested endpoint const libusb_endpoint_descriptor* pEndpointDesc = NULL; for (uint8_t i = 0; i < pInterfaceDesc->bNumEndpoints; ++i) { if (pInterfaceDesc->endpoint[i].bEndpointAddress == nEndPointID) { pEndpointDesc = &pInterfaceDesc->endpoint[i]; break; } } if (pEndpointDesc == NULL) { libusb_free_config_descriptor(pConfig); return (XN_STATUS_USB_ENDPOINT_NOT_FOUND); } libusb_transfer_type transfer_type = (libusb_transfer_type)(pEndpointDesc->bmAttributes & 0x3); // lower 2-bits // calculate max packet size // NOTE: we do not use libusb functions (libusb_get_max_packet_size/libusb_get_max_iso_packet_size) because // they hace a bug and does not consider alternative interface XnUInt32 nMaxPacketSize = 0; if (transfer_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { XnUInt32 wMaxPacketSize = pEndpointDesc->wMaxPacketSize; // bits 11 and 12 mark the number of additional transactions, bits 0-10 mark the size XnUInt32 nAdditionalTransactions = wMaxPacketSize >> 11; XnUInt32 nPacketSize = wMaxPacketSize & 0x7FF; nMaxPacketSize = (nAdditionalTransactions + 1) * (nPacketSize); }
XnStatus xnUSBOpenDeviceImpl(const XnChar* strDevicePath, XN_USB_DEV_HANDLE* pDevHandlePtr) { // Local variables XnStatus nRetVal = XN_STATUS_OK; LPCGUID pInterfaceGuid = NULL; XN_USB_DEV_HANDLE pDevHandle = NULL; HDEVINFO hDevInfo = NULL; SP_DEVICE_INTERFACE_DATA devInterfaceData; HANDLE hSelectedDevice = INVALID_HANDLE_VALUE; PSUSBDRV_DRIVER_VERSION UsbDriverVersion; PSUSBDRV_INTERFACE_PROPERTY pInterfaceProp; // Validate xnUSB XN_VALIDATE_USB_INIT(); // Validate the input/output pointers XN_VALIDATE_OUTPUT_PTR(pDevHandlePtr); // Allocate a new xnUSB Device handle XN_VALIDATE_ALIGNED_CALLOC(*pDevHandlePtr, XnUSBDeviceHandle, 1, XN_DEFAULT_MEM_ALIGN); pDevHandle = *pDevHandlePtr; // Get Device Path pInterfaceGuid = &GUID_CLASS_PSDRV_USB; // See if the driver is installed hDevInfo = SetupDiGetClassDevs (pInterfaceGuid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE)); if (hDevInfo == INVALID_HANDLE_VALUE) { // No devices are present... XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (XN_STATUS_USB_DRIVER_NOT_FOUND); } // Scan the hardware for any devices that are attached to our driver. Stop only after we have successfully opened a device. devInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); bool bDone = FALSE; ULONG nIdx = 0; // Scan all the devices that are attached to the driver. Stop when one of them open successfully. while (!bDone) { // Get information about the device if (SetupDiEnumDeviceInterfaces (hDevInfo, 0, pInterfaceGuid, nIdx, &devInterfaceData)) { // Try to open this device hSelectedDevice = xnUSBOpenOneDevice(hDevInfo, &devInterfaceData, pDevHandle->cpDeviceName, strDevicePath); if (hSelectedDevice != INVALID_HANDLE_VALUE) { // Success! We have a valid device handle. bDone = TRUE; break; } } else { // Did we reach the end? if (ERROR_NO_MORE_ITEMS == GetLastError()) { // Yup... and we didn't find any devices... bDone = TRUE; break; } } ++nIdx; } // Cleanup memory SetupDiDestroyDeviceInfoList (hDevInfo); // Do we have a valid device? if (hSelectedDevice == INVALID_HANDLE_VALUE) { // Nope... XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (XN_STATUS_USB_DEVICE_NOT_FOUND); } // Save the device handle pDevHandle->hUSBDevHandle = hSelectedDevice; // Get the device speed nRetVal = xnUSBGetDeviceSpeedInternal(pDevHandle, &pDevHandle->nDevSpeed); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } // Get the driver version nRetVal = xnUSBGetDriverVersion(pDevHandle, &UsbDriverVersion); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } xnLogVerbose(XN_MASK_USB, "USB Driver Version is: %d.%d.%d.%d", UsbDriverVersion.nMajor, UsbDriverVersion.nMinor, UsbDriverVersion.nMaintenance, UsbDriverVersion.nBuild); // Mark the device handle as valid pDevHandle->bValid = TRUE; // Read the current alt-if settings nRetVal = xnUSBGetInterface(pDevHandle, &pInterfaceProp.nIF, &pInterfaceProp.nAltIF); if (nRetVal != XN_STATUS_OK) { XN_ALIGNED_FREE_AND_NULL(pDevHandle); return (nRetVal); } pDevHandle->nAltInterface = pInterfaceProp.nAltIF; xnLogVerbose(XN_MASK_USB, "USB Driver Current Alt Setting is: %d", pDevHandle->nAltInterface); // All is good... return (XN_STATUS_OK); }