Exemplo n.º 1
0
qint32 QUsbDevice::open()
{
    if (mConnected)
        return -1;

    if (!guidFromString(mFilter.guid, &mGuid))
        return -1;

    if (!getDeviceHandle(mGuid, &mDevHandle)) return -1;
    else if (!getWinUSBHandle(mDevHandle, &mUsbHandle)) return -2;
    else if (!getUSBDeviceSpeed(mUsbHandle, &mDevSpeed)) return -3;
    else if (!queryDeviceEndpoints(mUsbHandle, &mPipeId)) return -4;

    ulong timeout = mTimeout; /* SetPipePolicy requires an unsigned long */
    if (!WinUsb_SetPipePolicy(mUsbHandle, mConfig.readEp, PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout)) {
        qWarning("Error WinUsb_SetPipePolicy: %d.\n", GetLastError()); return -5; }
    if (!WinUsb_SetPipePolicy(mUsbHandle, mConfig.writeEp, PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout)) {
        qWarning("Error WinUsb_SetPipePolicy: %d.\n", GetLastError()); return -6; }

    bool enable = true;
    if (!WinUsb_SetPipePolicy(mUsbHandle, mConfig.readEp, IGNORE_SHORT_PACKETS, sizeof(enable), &enable)) {
        qWarning("Error WinUsb_SetPipePolicy: %d.\n", GetLastError()); return -7; }

    mConnected = true;

    return 0;
}
Exemplo n.º 2
0
void QUsbDevice::setTimeout(quint16 timeout)
{
    UsbPrintFuncName();
    if (mUsbHandle==INVALID_HANDLE_VALUE
            || !mConfig.writeEp
            || !mConfig.readEp)
    {
        return;
    }

    mTimeout = timeout;
    ulong _timeout = mTimeout; /* SetPipePolicy requires an unsigned long */

    if (!WinUsb_SetPipePolicy(mUsbHandle, mConfig.readEp, PIPE_TRANSFER_TIMEOUT, sizeof(_timeout), &_timeout)) {
        qWarning("Error WinUsb_SetPipePolicy: %d.\n", GetLastError()); return; }
    if (!WinUsb_SetPipePolicy(mUsbHandle, mConfig.writeEp, PIPE_TRANSFER_TIMEOUT, sizeof(_timeout), &_timeout)) {
        qWarning("Error WinUsb_SetPipePolicy: %d.\n", GetLastError()); return; }
}
Exemplo n.º 3
0
/*! \brief Set the default timeout value to use in blocking operations.
	\details This function sets the value of m_timeout. There is no infinity value. The value 0
	means that the default value is used.
	\param ms The desired timeout in milliseconds
	\returns XRV_OK if the timeout value was successfully updated
*/
XsResultValue UsbInterface::setTimeout(uint32_t ms)
{
#ifdef USE_WINUSB
	JLDEBUG(gJournal, "Request to set timeout to " << ms << " ms overridden, setting to 0 ms instead");
	ms = 0;		// no timeout ever
	UCHAR enable = FALSE;

	WinUsb_SetPipePolicy(d->m_usbHandle[1], d->m_bulkInPipe, IGNORE_SHORT_PACKETS, sizeof(UCHAR), &enable);	//lint !e534
	WinUsb_SetPipePolicy(d->m_usbHandle[1], d->m_bulkInPipe, PIPE_TRANSFER_TIMEOUT, sizeof(ULONG), &ms);	//lint !e534

	d->m_timeout = ms;
#else
	JLDEBUG(gJournal, "Setting timeout to " << ms);
	if (ms == 0)
		d->m_timeout = 1;
	else
		d->m_timeout = ms;
#endif
	return (d->m_lastResult = XRV_OK);
}
Exemplo n.º 4
0
/*! \brief Sets the RAWIO mode of the USB interface
	\note Only applies to WinUSB implementations
	\param enable : If true will enable RAW IO mode
*/
void UsbInterface::setRawIo(bool enable)
{
	JLDEBUG(gJournal, "Setting RAWIO mode to " << enable);

#ifdef USE_WINUSB
	enable = false;	// never use raw IO
	UCHAR rawIo = (UCHAR)enable;
	WinUsb_SetPipePolicy(d->m_usbHandle[1], d->m_bulkInPipe, RAW_IO, sizeof(UCHAR), &rawIo);	//lint !e534
#else
	(void)enable;
#endif
	d->m_lastResult = XRV_OK;
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
		}
	}
}