private void allocTransfer(UsbEndpointBase endpointBase, bool ownsTransfer, int isoPacketSize, int count)
        {
            int numIsoPackets = 0;
            if (isoPacketSize > 0)
                numIsoPackets = count/isoPacketSize;
            freeTransfer();
            mTransfer = MonoUsbTransfer.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);


        }
Пример #2
0
        /// <summary>
        /// Perform a USB control transfer for multi-threaded applications using the <see cref="MonoUsbEventHandler"/> 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="MonoUsbError.ErrorTimeout"/> if the transfer timed out</item>
        /// <item><see cref="MonoUsbError.ErrorPipe"/> if the control request was not supported by the device.</item>
        /// <item><see cref="MonoUsbError.ErrorNoDevice"/> if the device has been disconnected</item>
        /// <item>another <see cref="MonoUsbError"/> code on other failures</item>
        /// </list>
        /// </returns>
        public static int ControlTransferAsync([In] MonoUsbDeviceHandle deviceHandle,
                                                 byte requestType,
                                                 byte request,
                                                 short value,
                                                 short index,
                                                 IntPtr pData,
                                                 short dataLength,
                                                 int timeout)
        {
            MonoUsbControlSetupHandle setupHandle = new MonoUsbControlSetupHandle(requestType, request, value, index, pData, dataLength);
            MonoUsbTransfer transfer = new MonoUsbTransfer(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;
            MonoUsbSessionHandle sessionHandle = MonoUsbEventHandler.SessionHandle;
            if (sessionHandle == null) 
                pSessionHandle = IntPtr.Zero;
            else
                pSessionHandle = sessionHandle.DangerousGetHandle();

            if (MonoUsbEventHandler.IsStopped)
            {
                while (!completeEvent.WaitOne(0, false))
                {
                    r = HandleEvents(pSessionHandle);
                    if (r < 0)
                    {
                        if (r == (int)MonoUsbError.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 == MonoUsbTansferStatus.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;
        }
Пример #3
0
 private static void DefaultAsyncCB(MonoUsbTransfer transfer)
 {
     ManualResetEvent completeEvent = GCHandle.FromIntPtr(transfer.PtrUserData).Target as ManualResetEvent;
     completeEvent.Set();
 }
        // This function originated from do_sync_bulk_transfer()
        // in sync.c of the Libusb-1.0 source code.
        private static MonoUsbError doBulkAsyncTransfer(MonoUsbDeviceHandle dev_handle,
                                                          byte endpoint,
                                                          byte[] buffer,
                                                          int length,
                                                          out int transferred,
                                                          int timeout)
        {
            transferred = 0;
            MonoUsbTransfer transfer = new MonoUsbTransfer(0);
            if (transfer.IsInvalid) return MonoUsbError.ErrorNoMem;

            MonoUsbTransferDelegate monoUsbTransferCallbackDelegate = bulkTransferCB;
            int[] userCompleted = new int[] {0};
            GCHandle gcUserCompleted = GCHandle.Alloc(userCompleted, GCHandleType.Pinned);

            MonoUsbError e;
            GCHandle gcBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned);
            transfer.FillBulk(
                dev_handle,
                endpoint,
                gcBuffer.AddrOfPinnedObject(),
                length,
                monoUsbTransferCallbackDelegate,
                gcUserCompleted.AddrOfPinnedObject(),
                timeout);

            e = transfer.Submit();
            if ((int) e < 0)
            {
                transfer.Free();
                gcUserCompleted.Free();
                return e;
            }
            int r;
            Console.WriteLine("Transfer Submitted..");
            while (userCompleted[0] == 0)
            {
                e = (MonoUsbError) (r = Usb.HandleEvents(sessionHandle));
                if (r < 0)
                {
                    if (e == MonoUsbError.ErrorInterrupted)
                        continue;
                    transfer.Cancel();
                    while (userCompleted[0] == 0)
                        if (Usb.HandleEvents(sessionHandle) < 0)
                            break;
                    transfer.Free();
                    gcUserCompleted.Free();
                    return e;
                }
            }

            transferred = transfer.ActualLength;
            e = MonoUsbApi.MonoLibUsbErrorFromTransferStatus(transfer.Status);
            transfer.Free();
            gcUserCompleted.Free();
            return e;
        }
 // This function originated from bulk_transfer_cb()
 // in sync.c of the Libusb-1.0 source code.
 private static void bulkTransferCB(MonoUsbTransfer transfer)
 {
     Marshal.WriteInt32(transfer.PtrUserData, 1);
     /* caller interprets results and frees transfer */
 }
 private static void TransferCallback(MonoUsbTransfer pTransfer)
 {
     ManualResetEvent completeEvent = GCHandle.FromIntPtr(pTransfer.PtrUserData).Target as ManualResetEvent;
     completeEvent.Set();
 }
        private void allocTransfer(UsbEndpointBase endpointBase, bool ownsTransfer, int isoPacketSize, int count)
        {
            int numIsoPackets = 0;

            // Patch for using libusb-1.0 on windows with libusbwK.sys
            EndpointType endpointType = endpointBase.Type;
            if (UsbDevice.IsLinux)
            {

                if (isoPacketSize > 0)
                    numIsoPackets = count/isoPacketSize;
            }
            else
            {
                if (endpointType == EndpointType.Isochronous)
                    endpointType = EndpointType.Bulk;
            }
            ///////////////////////////////////////////////////////////////

            freeTransfer();
            mTransfer = MonoUsbTransfer.Alloc(numIsoPackets);
            mOwnsTransfer = ownsTransfer;
            mTransfer.Type = endpointType;
            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);
        }