private void allocTransfer(UsbEndpointBase endpointBase, bool ownsTransfer, int isoPacketSize, int count) { int numIsoPackets = 0; if (isoPacketSize > 0) numIsoPackets = count/isoPacketSize; freeTransfer(); mTransfer = LibUsbTransfer.Alloc(numIsoPackets); mOwnsTransfer = ownsTransfer; mTransfer.Type = endpointBase.Type; mTransfer.Endpoint = endpointBase.EpNum; mTransfer.NumIsoPackets = numIsoPackets; if (!mCompleteEventHandle.IsAllocated) mCompleteEventHandle = GCHandle.Alloc(mTransferCompleteEvent); mTransfer.PtrUserData = GCHandle.ToIntPtr(mCompleteEventHandle); if (numIsoPackets > 0) mTransfer.SetIsoPacketLengths(isoPacketSize); }
/// <summary> /// Perform a USB control transfer for multi-threaded applications using the <see cref="LibUsbEventHandler"/> class. /// </summary> /// <remarks> /// <para>The direction of the transfer is inferred from the bmRequestType field of the setup packet.</para> /// <para>The wValue, wIndex and wLength fields values should be given in host-endian byte order.</para> /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="syncio"/></note> /// </remarks> /// <param name="deviceHandle">A handle for the device to communicate with.</param> /// <param name="requestType">The request type field for the setup packet.</param> /// <param name="request">The request field for the setup packet.</param> /// <param name="value">The value field for the setup packet</param> /// <param name="index">The index field for the setup packet.</param> /// <param name="pData">A suitably-sized data buffer for either input or output (depending on direction bits within bmRequestType).</param> /// <param name="dataLength">The length field for the setup packet. The data buffer should be at least this size.</param> /// <param name="timeout">timeout (in milliseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0.</param> /// <returns> /// <list type="bullet"> /// <item>on success, the number of bytes actually transferred</item> /// <item><see cref="LibUsbError.ErrorTimeout"/> if the transfer timed out</item> /// <item><see cref="LibUsbError.ErrorPipe"/> if the control request was not supported by the device.</item> /// <item><see cref="LibUsbError.ErrorNoDevice"/> if the device has been disconnected</item> /// <item>another <see cref="LibUsbError"/> code on other failures</item> /// </list> /// </returns> public static int ControlTransferAsync([In] LibUsbDeviceHandle deviceHandle, byte requestType, byte request, short value, short index, IntPtr pData, short dataLength, int timeout) { LibUsbControlSetupHandle setupHandle = new LibUsbControlSetupHandle(requestType, request, value, index, pData, dataLength); LibUsbTransfer transfer = new LibUsbTransfer(0); ManualResetEvent completeEvent = new ManualResetEvent(false); GCHandle gcCompleteEvent = GCHandle.Alloc(completeEvent); transfer.FillControl(deviceHandle, setupHandle, DefaultAsyncDelegate, GCHandle.ToIntPtr(gcCompleteEvent), timeout); int r = (int)transfer.Submit(); if (r < 0) { transfer.Free(); gcCompleteEvent.Free(); return r; } IntPtr pSessionHandle; LibUsbSessionHandle sessionHandle = LibUsbEventHandler.SessionHandle; if (sessionHandle == null) pSessionHandle = IntPtr.Zero; else pSessionHandle = sessionHandle.DangerousGetHandle(); if (LibUsbEventHandler.IsStopped) { while (!completeEvent.WaitOne(0, false)) { r = HandleEvents(pSessionHandle); if (r < 0) { if (r == (int)LibUsbError.ErrorInterrupted) continue; transfer.Cancel(); while (!completeEvent.WaitOne(0, false)) if (HandleEvents(pSessionHandle) < 0) break; transfer.Free(); gcCompleteEvent.Free(); return r; } } } else { completeEvent.WaitOne(Timeout.Infinite, UsbConstants.EXIT_CONTEXT); } if (transfer.Status == LibUsbTansferStatus.TransferCompleted) { r = transfer.ActualLength; if (r > 0) { byte[] ctrlDataBytes = setupHandle.ControlSetup.GetData(r); Marshal.Copy(ctrlDataBytes, 0, pData, Math.Min(ctrlDataBytes.Length, dataLength)); } } else r = (int)MonoLibUsbErrorFromTransferStatus(transfer.Status); transfer.Free(); gcCompleteEvent.Free(); return r; }
private static void TransferCallback(LibUsbTransfer pTransfer) { ManualResetEvent completeEvent = GCHandle.FromIntPtr(pTransfer.PtrUserData).Target as ManualResetEvent; completeEvent.Set(); }
private static void DefaultAsyncCB(LibUsbTransfer transfer) { ManualResetEvent completeEvent = GCHandle.FromIntPtr(transfer.PtrUserData).Target as ManualResetEvent; completeEvent.Set(); }