internal int reapAsyncNoCancel(TransferContext transferContext) { int ret = -1; lock (oLockTransferContext) { if (transferContext.mbAsyncCancelled) { return((int)ErrorCodes.ETHREADABORT); } } ret = LibUsbAPI.usb_reap_async_nocancel(transferContext.mContext, transferContext.mTimeout); lock (oLockTransferContext) { if (ret < 0 && ret != (int)ErrorCodes.ETIMEDOUT) { transferContext.mbAsyncCancelled = true; UsbGlobals.Error(this, UsbGlobals.LastError, "reapAsyncNoCancel", ret); } else if (ret >= 0) { transferContext.mbAsyncCancelled = true; transferContext.IncrementTransfer(ret); } return(ret); } }
internal int setupAsync(TransferContext transferContext) { int ret = -1; lock (oLockTransferContext) { transferContext.Reset(); switch (mEpType) { case EndpointTypes.Bulk: ret = LibUsbAPI.usb_bulk_setup_async(mUsbDevice.Handle, ref transferContext.mContext, EpNum); break; case EndpointTypes.Interrupt: ret = LibUsbAPI.usb_interrupt_setup_async(mUsbDevice.Handle, ref transferContext.mContext, EpNum); break; case EndpointTypes.Isochronous: ret = LibUsbAPI.usb_isochronous_setup_async(mUsbDevice.Handle, ref transferContext.mContext, EpNum, mPacketSize); break; } if (ret < 0 || !transferContext.mContext.IsValid) { UsbGlobals.Error(this, UsbGlobals.LastError, "setupAsync", ret); } return(ret); } }
/// <summary> /// Reads or Writes data (depending on the <see cref="EpNum"/>) to/from the current <see cref="UsbEndpointReader"/>. /// </summary> /// <param name="buffer">The buffer for the tranfer.</param> /// <param name="offset">The position in buffer to start storing the data.</param> /// <param name="count">The number of bytes to send or the maximum number of bytes to receive.</param> /// <param name="timeout">Maximum time to wait for the transfer to complete. If the transfer times out, the IO operation will be cancelled.</param> /// <returns> /// Number of bytes transmitted or less than zero if an error occured. /// </returns> public int Transfer(byte[] buffer, int offset, int count, int timeout) { if (mbDisposed) { return((int)ErrorCodes.ENODEV); } if (!TransferLock.WaitOne(0, false)) { return((int)ErrorCodes.EBUSY); } int ret = -1; try { lock (oLockTransferContext) Context.Setup(buffer, offset, count, timeout, true); ret = transferSync(Context); } catch (Exception ex) { ret = (int)ErrorCodes.EEXCEPTION; UsbGlobals.Error(this, ex.ToString(), "Transfer", ret); } finally { freeAsync(Context); TransferLock.Release(); } return(ret); }
private void startStopReadThread() { if (IsDisposed) { return; } if (mDataReceivedEnabled) { mEventCancelReadThread.Set(); int iLoopCount = 0; while (mthReadThread.IsAlive) { iLoopCount++; if ((iLoopCount) > 1000) { mthReadThread.Abort(); UsbGlobals.Error(this, "Thread could not be gracefully stopped.", "startStopReadThread", (int)ErrorCodes.ETHREADABORT); break; } Application.DoEvents(); Thread.Sleep(1); if (Context.mContext.IsValid) { cancelAsync(Context); } } iLoopCount = 0; while (mDataReceivedEnabled) { iLoopCount++; Application.DoEvents(); Thread.Sleep(1); if ((iLoopCount) > 1000) { throw new LibUsbException(this, "startStopReadThread: The read thread is stalled."); } } mthReadThread = null; } else { if (!TransferLock.WaitOne(0, false)) { UsbGlobals.Error(this, "Read thread could not be started because a transfer is allready pending.", "startStopReadThread", (int)ErrorCodes.EBUSY); return; } mEventCancelReadThread.Reset(); lock (oLockTransferContext) Context.Setup(new byte[mReadBufferSize], 0, mReadBufferSize, Timeout.Infinite, false); mthReadThread = new Thread(ReadData); mthReadThread.Start(Context); Application.DoEvents(); } }
/// <summary>Opens this <see cref="UsbDevice"/> for communication.</summary> /// <returns>True if the device was opened successfully.</returns> public bool Open() { if (!mHandle.IsValid) { mHandle.Open(mDev); if (!mHandle.IsValid) { UsbGlobals.Error(this, UsbGlobals.LastError, "Open", (int)ErrorCodes.EFAULT); } } return(mHandle.IsValid); }
/// <summary>Closes the device.</summary> /// <remarks><dl class="cBList"><dt>The <see cref="Close" /> function performs the following actions:</dt> /// <dd>Attempts to safely stop read threads on all <see cref="ActiveEndpoints" />.</dd> /// <dd>Aborts read threads on all <see cref="ActiveEndpoints" /> if they fail to stop gracefully.</dd> /// <dd>Closes and releases the internal device handle.</dd></dl></remarks> public bool Close() { if (mHandle.IsValid) { ActiveEndpoints.Clear(); if (!mHandle.Close()) { UsbGlobals.Error(this, UsbGlobals.LastError, "Close", (int)ErrorCodes.EFAULT); return(false); } } return(true); }
/// <summary> /// Sends/receives a control message to/from the current <see cref="UsbDevice"/>. /// </summary> /// <param name="requestType">USB request type.</param> /// <param name="request">USB request.</param> /// <param name="value">USB value.</param> /// <param name="index">USB index.</param> /// <param name="bytes">Buffer to send/recv from device.</param> /// <param name="timeout">Maximum amount of time to wait for the function to complete.</param> /// <returns>On Success, the number of bytes transmitted. Less than zero on failure.</returns> public int IOControlMessage(int requestType, int request, int value, int index, Byte[] bytes, int timeout) { if (!Open()) { return((int)ErrorCodes.EFAULT); } int ret = LibUsbAPI.usb_control_msg(mHandle, requestType, request, value, index, bytes, bytes == null ? 0 : bytes.Length, timeout); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "IOControlMessage", ret); } return(ret); }
/// <summary>Sets the active configuration of the opened device.</summary> /// <remarks>The <paramref name="iConfig" /> parameter is the value as specified in the descriptor field <see cref="InfoConfig.ConfigurationValue" /></remarks> /// <returns>0 on success or less than 0 on error.</returns> public int SetConfiguration(int iConfig) { if (!Open()) { return((int)ErrorCodes.EFAULT); } int ret = LibUsbAPI.usb_set_configuration(mHandle, iConfig); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "SetConfiguration", ret); } return(ret); }
///<summary>Sets the alternate interface to use for the claimed interface.</summary> ///<remarks>The <paramref name="iAltInterface"/> parameter is the value as specified in the descriptor field <see cref="InfoInterface.AlternateSetting"/>.</remarks> ///<returns>0 on success or less than 0 on error.</returns> public int SetAltInterface(int iAltInterface) { if (!Open()) { return((int)ErrorCodes.EFAULT); } int ret = LibUsbAPI.usb_set_altinterface(mHandle, iAltInterface); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "SetAltInterface", ret); } return(ret); }
///<summary>Releases a claimed interface. See <see cref="ClaimInterface"/>.</summary> ///<returns>0 on success or less than 0 on error.</returns> public int ReleaseInterface(int iInterface) { if (!Open()) { return((int)ErrorCodes.EFAULT); } int ret = LibUsbAPI.usb_release_interface(mHandle, iInterface); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "ReleaseInterface", ret); } return(ret); }
/// <summary> /// All functions that call this function must first lock the <see cref="oLockTransferContext"/> object to be thread safe. /// </summary> /// <param name="transferContext"></param> /// <returns></returns> private int cancelAsync_NL(TransferContext transferContext) { int ret = 0; if (transferContext.mbAsyncCancelled) { return(ret); } transferContext.mbAsyncCancelled = true; ret = LibUsbAPI.usb_cancel_async(transferContext.mContext); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "cancelAsync", ret); } return(ret); }
internal int submitAsync(TransferContext transferContext) { int ret = -1; lock (oLockTransferContext) ret = LibUsbAPI.usb_submit_async(transferContext.mContext, transferContext.PtrBuf, transferContext.RequestCount); if (ret < 0) { UsbGlobals.Error(this, UsbGlobals.LastError, "submitAsync", ret); } else { lock (oLockTransferContext) transferContext.mbAsyncCancelled = false; } return(ret); }
internal int reapAsync(TransferContext transferContext) { int ret = -1; ret = LibUsbAPI.usb_reap_async(transferContext.mContext, transferContext.mTimeout); lock (oLockTransferContext) transferContext.mbAsyncCancelled = true; if (ret < 0 && ret != (int)ErrorCodes.ETIMEDOUT) { UsbGlobals.Error(this, UsbGlobals.LastError, "reapAsync", ret); } else if (ret >= 0) { lock (oLockTransferContext) transferContext.IncrementTransfer(ret); } return(ret); }
internal int freeAsync(TransferContext transferContext) { lock (oLockTransferContext) { int ret = 0; if (!transferContext.mContext.IsValid) { return(ret); } cancelAsync_NL(transferContext); ret = LibUsbAPI.usb_free_async(ref transferContext.mContext); if (ret < 0 || transferContext.mContext.IsValid) { UsbGlobals.Error(this, UsbGlobals.LastError, "freeAsync", ret); } return(ret); } }