wxThread::ExitCode ReceiveFromDevice::Entry() { bool error = false;//Indicates last state while(!TestDestroy()) { DWORD read = 0; UCHAR buff[256]= {0}; if(device->WinUSBHandle == INVALID_HANDLE_VALUE || !device->GetState()) { Reset(); if(error) Sleep(errSleep); error = true; continue; } OVERLAPPED overlapped; ZeroMemory(&overlapped, sizeof(overlapped)); overlapped.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL);//(NULL, TRUE, FALSE, NULL); if(!WinUsb_ReadPipe(device->WinUSBHandle, IN_EP, data + received, IN_EP_PACKET, &read, &overlapped)) { if(GetLastError() != ERROR_IO_PENDING) { Reset(); if(error) Sleep(errSleep); error = true; continue; } } while(WaitForSingleObject(overlapped.hEvent, 100) == WAIT_TIMEOUT) { if(TestDestroy())//Check whether the thread should be destroyed { CloseHandle(overlapped.hEvent); return 0; } } //Complete transfer - get received bytes WinUsb_GetOverlappedResult(device->WinUSBHandle, &overlapped, &read, FALSE); CloseHandle(overlapped.hEvent);//Clear event //Process data if(read == 0) { //Error occur, reset state Reset(); if(error) Sleep(errSleep); error = true; continue; } error = false; //Increase counters received += read; receivedPackets++; //Check if we read entire message if(data[0] == receivedPackets) { ProcessMessage(); Reset(); } } return 0; }
void NiashLibUsbWriteBulk(const int iHandle, SANE_Byte* const pabData, const int iSize) { assert(iHandle==1); assert(s_hWinUSB); assert(s_Pipes.BulkOut); //Send setup packet SANE_Byte abSetup[8] = { 0x01, 0x01, 0x00, 0x00, (iSize) & 0xFF, (iSize >> 8) & 0xFF, 0x00, 0x00 }; WINUSB_SETUP_PACKET Packet; Packet.RequestType = BMREQUEST_HOST_TO_DEVICE<<7|BMREQUEST_VENDOR<<5; //Vendor type request, PC to device Packet.Request = 0x04; //Send multiple bytes Packet.Value = static_cast<USHORT>(USB_SETUP); Packet.Index = 0x00; Packet.Length = 0x08; SendControlTransfer(Packet,abSetup); ULONG LengthTransferred; if(!WinUsb_WritePipe(s_hWinUSB, s_Pipes.BulkOut, pabData, iSize, &LengthTransferred, nullptr)) { wprintf_s(L"WinUsb_WritePipe: %s\n", _com_error(GetLastError()).ErrorMessage()); return; } } void NiashLibUsbReadBulk (const int iHandle, SANE_Byte* const pabData, const int iSize) { assert(iHandle==1); assert(s_hWinUSB); assert(s_Pipes.BulkIn); //Send setup packet SANE_Byte abSetup[8] = { 0x00, 0x00, 0x00, 0x00, (iSize) & 0xFF, (iSize >> 8) & 0xFF, 0x00, 0x00 }; WINUSB_SETUP_PACKET Packet; Packet.RequestType = BMREQUEST_HOST_TO_DEVICE<<7|BMREQUEST_VENDOR<<5; //Vendor type request, PC to device Packet.Request = 0x04; //Send multiple bytes Packet.Value = static_cast<USHORT>(USB_SETUP); Packet.Index = 0x00; Packet.Length = 0x08; SendControlTransfer(Packet,abSetup); ULONG LengthTransferred; if(!WinUsb_ReadPipe(s_hWinUSB, s_Pipes.BulkIn, pabData, iSize, &LengthTransferred, nullptr)) { wprintf_s(L"WinUsb_WritePipe: %s\n", _com_error(GetLastError()).ErrorMessage()); return; } } void NiashLibUsbWaitForInterrupt() { assert(s_hWinUSB); assert(s_Pipes.Interrupt); BYTE buf[1]; ULONG LengthTransferred; if(!WinUsb_ReadPipe(s_hWinUSB,s_Pipes.Interrupt,buf,_countof(buf),&LengthTransferred,nullptr)) { wprintf_s(L"WinUsb_ReadPipe: %s\n", _com_error(GetLastError()).ErrorMessage()); return; } }
BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, ULONG cbSize, BYTE *pbyData, DWORD dwNumBytesCount) { if ( 0 == dwNumBytesCount ) { return TRUE; } if ( NULL == pbyData ) { return FALSE; } if (hDeviceHandle==INVALID_HANDLE_VALUE) { return FALSE; } BOOL bResult = TRUE; ULONG cbRead = 0; bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, pbyData, dwNumBytesCount, &cbRead, 0); if(!bResult) { goto done; } PTRACE("Read from pipe %d: %d bytes\nActual data read: %d.\n", *pID, dwNumBytesCount, cbRead); done: return bResult; }
BOOL ReadFromBulkEndpoint(WINUSB_INTERFACE_HANDLE hDeviceHandle, UCHAR* pID, UCHAR* szBuffer, ULONG cbSize) { if (hDeviceHandle==INVALID_HANDLE_VALUE) { return FALSE; } BOOL bResult = TRUE; // UCHAR* szBuffer = (UCHAR*)LocalAlloc(LPTR, sizeof(UCHAR)*cbSize); ULONG cbRead = 0; bResult = WinUsb_ReadPipe(hDeviceHandle, *pID, szBuffer, cbSize, &cbRead, 0); if (!bResult) { goto done; } //=== printf("Read from pipe %d: %s \nActual data read: %d.\n", *pID, szBuffer, cbRead); done: //LocalFree(szBuffer); return bResult; } // End of ReadFromBulkEndpoint()
void ChinavisionAPI::threadProc() { //======================== OVERLAPPED overlappedRead; HANDLE events[2]; DWORD result; UCHAR buffer[4]; ULONG length; //======================== memset(&overlappedRead,0,sizeof(OVERLAPPED)); overlappedRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL); m_exitEvent = CreateEvent(NULL,TRUE,FALSE,NULL); events[0] = overlappedRead.hEvent; events[1] = m_exitEvent; while(1) { memset(buffer,0,sizeof(buffer)); //sometiemes only reads 3 bytes WinUsb_ReadPipe(m_usbHandle, m_inPipeId, buffer, sizeof(buffer), &length, &overlappedRead); result = WaitForMultipleObjects(2,events,FALSE,INFINITE); if(result==WAIT_OBJECT_0) { //============= DWORD tempCode; //============= tempCode = *(DWORD*)buffer; printf("irCode %x\n",tempCode>>8); printf("length %i\n",length); for(DWORD i=0; i<length; i++) { printf("buffer[%i]",(int)buffer[i]); } printf("\n"); tempCode = tempCode >> 8; if(tempCode) { m_irCode = *(DWORD*)buffer; SetEvent(m_dataReadyEvent); } } else { break;
int USBRead(void *deviceHandle, unsigned char endpoint, char * data, int numberOfBytes) { /* Local variables */ long transferred = 0; __usb_interface_t *usb; if(0 == deviceHandle) { return WRITE_FAILED; } usb = (__usb_interface_t *)deviceHandle; WinUsb_ReadPipe(usb->winUSBHandle, endpoint, data, numberOfBytes, &transferred, NULL); return (int)transferred; }
qint32 QUsbDevice::read(QByteArray* buf, quint32 maxSize) { UsbPrintFuncName(); Q_CHECK_PTR(buf); if (mUsbHandle == INVALID_HANDLE_VALUE || !mConfig.readEp || !mConnected) { return -1; } bool bResult = true; ulong cbRead = 0; uchar* data = new uchar[maxSize]; if (mDebug) qDebug("Reading %d bytes from endpoint 0x%02x", maxSize, (uint)mConfig.readEp); bResult = WinUsb_ReadPipe(mUsbHandle, mConfig.readEp, data, maxSize, &cbRead, NULL); if (!bResult) { printUsbError("WinUsb_ReadPipe"); return -1; } else if (cbRead > 0){ if (mDebug) { QString datastr, s; for (quint32 i = 0; i < cbRead; i++) { datastr.append(s.sprintf("%02X:", data[i])); } datastr.remove(datastr.size()-1, 1); //remove last colon qDebug() << "Received" << cbRead << "of" << maxSize << "Bytes:" << datastr; } } *buf->append((char*)data, cbRead); delete [] data; return cbRead; }
void QUsbDevice::flush() { UsbPrintFuncName(); if (mUsbHandle == INVALID_HANDLE_VALUE || !mConfig.readEp || !mConnected) { return; } ulong cbRead; uchar* data = new uchar[4096]; ulong timeout = 25; WinUsb_SetPipePolicy(mUsbHandle, mConfig.readEp, PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout); WinUsb_ReadPipe(mUsbHandle, mConfig.readEp, data, 4096, &cbRead, NULL); timeout = mTimeout; WinUsb_SetPipePolicy(mUsbHandle, mConfig.readEp, PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout); if (mDebug) qDebug("Flushed %d bytes from endpoint 0x%x", cbRead, (uint)mConfig.readEp); delete [] data; }
int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout) { // Set timeout on endpoint // It might be more efficient to use async i/o here, but MS docs imply that // you have to create a new sync object for every call, which doesn't seem // efficient at all. So just set the pipe timeout and use sync i/o. ULONG tmp = timeout; if (!WinUsb_SetPipePolicy(dev->fd, ep, PIPE_TRANSFER_TIMEOUT, sizeof(tmp), &tmp)) return -EINVAL; // Perform transfer tmp = 0; if (!WinUsb_ReadPipe(dev->fd, ep, (unsigned char*)bytes, size, &tmp, NULL)) { tmp = GetLastError(); if (tmp == ERROR_SEM_TIMEOUT) return -LIBUSB_ETIMEDOUT; else return -EINVAL; } return tmp; }
void UsbInterfacePrivate::threadFunc() { HANDLE handles[1+m_oCount]; handles[0] = m_quitEvent; handles[m_oCount] = m_waitEvents[m_oCount-1]; //= { m_quitEvent, m_waitEvents[0], m_waitEvents[1] }; // start first read operation for (m_readIdx = 0 ; m_readIdx < (m_oCount-1); ++m_readIdx) { handles[m_readIdx+1] = m_waitEvents[m_readIdx]; //m_readIdx = 0; m_overlapped[m_readIdx] = OVERLAPPED(); ::ResetEvent(m_waitEvents[m_readIdx]); //lint !e534 m_overlapped[m_readIdx].hEvent = m_waitEvents[m_readIdx]; WinUsb_ReadPipe(m_usbHandle[1], m_bulkInPipe, m_fixedBuffer[m_readIdx], (ULONG)m_fixedBufferSize, 0, &m_overlapped[m_readIdx]); //lint !e534 } int fastCount = 0; //m_readIdx = 1; bool policyFast = false; bool run = true; while (run) { // start follow-up read operation m_overlapped[m_readIdx] = OVERLAPPED(); ::ResetEvent(m_waitEvents[m_readIdx]); //lint !e534 m_overlapped[m_readIdx].hEvent = m_waitEvents[m_readIdx]; WinUsb_ReadPipe(m_usbHandle[1], m_bulkInPipe, m_fixedBuffer[m_readIdx], (ULONG)m_fixedBufferSize, 0, &m_overlapped[m_readIdx]); //lint !e534 m_readIdx = (m_readIdx + 1) % m_oCount; int64_t tBegin = XsTime_timeStampNow(0); DWORD waitResult = ::WaitForMultipleObjects(1+m_oCount, handles, FALSE, INFINITE); #if 1 // not sure if this causes problems, but it should help in catching up int64_t tEnd = XsTime_timeStampNow(0); switch (tEnd - tBegin) { case 0: if (++fastCount > 3 && !policyFast) { policyFast = true; // set fast policy UCHAR enable = TRUE; WinUsb_SetPipePolicy(m_usbHandle[1], m_bulkInPipe, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &enable); //lint !e534 } break; case 1: if (fastCount) --fastCount; if (policyFast && fastCount <= 3) { // reset policy policyFast = false; UCHAR enable = FALSE; WinUsb_SetPipePolicy(m_usbHandle[1], m_bulkInPipe, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &enable); //lint !e534 } break; default: fastCount = 0; if (policyFast) { // reset policy policyFast = false; UCHAR enable = FALSE; WinUsb_SetPipePolicy(m_usbHandle[1], m_bulkInPipe, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &enable); //lint !e534 } break; } #endif // handle data switch (waitResult) { case WAIT_TIMEOUT: case WAIT_FAILED: case WAIT_OBJECT_0: run = false; break; default: if (waitResult >= WAIT_ABANDONED_0) { JLDEBUG(gJournal, "WFMO abandoned: " << (waitResult - WAIT_OBJECT_0)); break; } #ifndef XSENS_RELEASE JLDEBUG(gJournal, "WFMO trigger: " << (waitResult - WAIT_OBJECT_0)); #endif { // put data into buffer int idx = m_readIdx; DWORD dataRead = 0; if (!WinUsb_GetOverlappedResult(m_usbHandle[0], &m_overlapped[idx], &dataRead, FALSE)) { // error DWORD err = ::GetLastError(); switch (err) { case ERROR_SEM_TIMEOUT: case ERROR_IO_INCOMPLETE: //JLDEBUG(gJournal, "WinUsb_GetOverlappedResult resulted in acceptable windows error " << err); break; default: JLALERT(gJournal, "WinUsb_GetOverlappedResult resulted in windows error " << err); run = false; break; } //assert (err == ERROR_IO_INCOMPLETE); } else { // append unread data to var buffer JLTRACE(gJournal, "WinUsb_GetOverlappedResult resulted in " << dataRead << " bytes being read"); XsByteArray ref(&m_fixedBuffer[idx][0], dataRead, XSDF_None); ::EnterCriticalSection(&m_mutex); m_varBuffer.append(ref); ::LeaveCriticalSection(&m_mutex); } } break; } } }
int USBDriver_Impl_WinUSB::BulkRead( int iEndpoint, char *pData, int iSize, int iTimeout ) { int iRet = -1; WinUsb_ReadPipe( m_hDevice, iEndpoint, pData, iSize ); return iRet; }