/// <summary> /// Cancels any pending transfer and frees resources. /// </summary> protected virtual void Dispose(bool disposing) { if (!mbDisposed) { mbDisposed = true; try { if (!IsCancelled) { Cancel(); } int dummy; if (!mHasWaitBeenCalled) { Wait(out dummy); } if (disposing) { // Dispose managed resources. if (mPinnedHandle != null) { mPinnedHandle.Dispose(); } } mPinnedHandle = null; } catch (Exception ex) { Debug.Print(ex.Message); } } }
/// <summary> /// Perform a USB bulk transfer. /// </summary> /// <remarks> /// <para>The direction of the transfer is inferred from the direction bits of the endpoint address.</para> /// <para> /// For bulk reads, the length field indicates the maximum length of data you are expecting to receive. /// If less data arrives than expected, this function will return that data, so be sure to check the /// transferred output parameter. /// </para> /// <para> /// You should also check the transferred parameter for bulk writes. Not all of the data may have been /// written. Also check transferred when dealing with a timeout error code. libusb may have to split /// your transfer into a number of chunks to satisfy underlying O/S requirements, meaning that the /// timeout may expire after the first few chunks have completed. libusb is careful not to lose any /// data that may have been transferred; do not assume that timeout conditions indicate a complete lack /// of I/O. /// </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="endpoint">The address of a valid endpoint to communicate with.</param> /// <param name="data"> /// <para>A suitably-sized data buffer for either input or output (depending on endpoint).</para> /// This value can be: /// <list type="bullet"> /// <item>An <see cref="Array"/> of bytes or other <a href="http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx">blittable</a> types.</item> /// <item>An already allocated, pinned <see cref="GCHandle"/>. In this case <see cref="GCHandle.AddrOfPinnedObject"/> is used for the buffer address.</item> /// <item>An <see cref="IntPtr"/>.</item> /// </list> /// </param> /// <param name="length">For bulk writes, the number of bytes from data to be sent. for bulk reads, the maximum number of bytes to receive into the data buffer.</param> /// <param name="actualLength">Output location for the number of bytes actually transferred.</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>0 on success (and populates <paramref name="actualLength"/>)</item> /// <item><see cref="MonoUsbError.ErrorTimeout"/> if the transfer timed out</item> /// <item><see cref="MonoUsbError.ErrorPipe"/> if the endpoint halted</item> /// <item><see cref="MonoUsbError.ErrorOverflow"/>if the device offered more data, see <a href="http://libusb.sourceforge.net/api-1.0/packetoverflow.html">Packets and overflows</a></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 BulkTransfer([In] MonoUsbDeviceHandle deviceHandle, byte endpoint, object data, int length, out int actualLength, int timeout) { PinnedHandle p = new PinnedHandle(data); int ret = BulkTransfer(deviceHandle, endpoint, p.Handle, length, out actualLength, timeout); p.Dispose(); return ret; }
/// <summary> /// Synchronous bulk/interrupt transfer function. /// </summary> /// <param name="buffer">A caller-allocated buffer for the transfer data. This object is pinned using <see cref="PinnedHandle"/>.</param> /// <param name="offset">Position in buffer that transferring begins.</param> /// <param name="length">Number of bytes, starting from thr offset parameter to transfer.</param> /// <param name="timeout">Maximum time to wait for the transfer to complete.</param> /// <param name="transferLength">Number of bytes actually transferred.</param> /// <returns>True on success.</returns> public ErrorCode Transfer(object buffer, int offset, int length, int timeout, out int transferLength) { PinnedHandle pinned = new PinnedHandle(buffer); ErrorCode eReturn = Transfer(pinned.Handle, offset, length, timeout, out transferLength); pinned.Dispose(); return(eReturn); }
/// <summary> /// Cancels any pending transfer and frees resources. /// </summary> public virtual void Dispose() { if (!IsCancelled) { Cancel(); } int dummy; if (!mHasWaitBeenCalled) { Wait(out dummy); } if (mPinnedHandle != null) { mPinnedHandle.Dispose(); } mPinnedHandle = null; }
/// <summary> /// Cancels any pending transfer and frees resources. /// </summary> public virtual void Dispose() { if (!IsCancelled) { Cancel(); } try { int dummy; if (!mHasWaitBeenCalled) { Wait(out dummy); } if (mPinnedHandle != null) { mPinnedHandle.Dispose(); } mPinnedHandle = null; } catch (System.ObjectDisposedException) { } }
/// <summary> /// Perform a USB control transfer. /// </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="data"> /// <para>A suitably-sized data buffer for either input or output (depending on direction bits within bmRequestType).</para> /// This value can be: /// <list type="bullet"> /// <item>An <see cref="Array"/> of bytes or other <a href="http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx">blittable</a> types.</item> /// <item>An already allocated, pinned <see cref="GCHandle"/>. In this case <see cref="GCHandle.AddrOfPinnedObject"/> is used for the buffer address.</item> /// <item>An <see cref="IntPtr"/>.</item> /// </list> /// </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 ControlTransfer([In] MonoUsbDeviceHandle deviceHandle, byte requestType, byte request, short value, short index, object data, short dataLength, int timeout) { PinnedHandle p = new PinnedHandle(data); int ret = ControlTransfer(deviceHandle, requestType, request, value, index, p.Handle, dataLength, timeout); p.Dispose(); return ret; }
/// <summary> /// Synchronous bulk/interrupt transfer function. /// </summary> /// <param name="buffer">A caller-allocated buffer for the transfer data. This object is pinned using <see cref="PinnedHandle"/>.</param> /// <param name="offset">Position in buffer that transferring begins.</param> /// <param name="length">Number of bytes, starting from thr offset parameter to transfer.</param> /// <param name="timeout">Maximum time to wait for the transfer to complete.</param> /// <param name="transferLength">Number of bytes actually transferred.</param> /// <returns>True on success.</returns> public ErrorCode Transfer(object buffer, int offset, int length, int timeout, out int transferLength) { PinnedHandle pinned = new PinnedHandle(buffer); ErrorCode eReturn = Transfer(pinned.Handle, offset, length, timeout, out transferLength); pinned.Dispose(); return eReturn; }
/// <summary> /// Gets a descriptor from the device. See <see cref="DescriptorType"/> for more information. /// </summary> /// <param name="descriptorType">The descriptor type ID to retrieve; this is usually one of the <see cref="DescriptorType"/> enumerations.</param> /// <param name="index">Descriptor index.</param> /// <param name="langId">Descriptor language id.</param> /// <param name="buffer">Memory to store the returned descriptor in.</param> /// <param name="bufferLength">Length of the buffer parameter in bytes.</param> /// <param name="transferLength">The number of bytes transferred to buffer upon success.</param> /// <returns>True on success.</returns> public bool GetDescriptor(byte descriptorType, byte index, short langId, object buffer, int bufferLength, out int transferLength) { PinnedHandle pinned = new PinnedHandle(buffer); bool bSuccess = GetDescriptor(descriptorType, index, langId, pinned.Handle, bufferLength, out transferLength); pinned.Dispose(); return bSuccess; }
/// <summary> /// Transmits control data over a default control endpoint. /// </summary> /// <param name="setupPacket">An 8-byte setup packet which contains parameters for the control request. /// See section 9.3 USB Device Requests of the Universal Serial Bus Specification Revision 2.0 for more information. </param> /// <param name="buffer">Data to be sent/received from the device.</param> /// <param name="bufferLength">Length of the buffer param.</param> /// <param name="lengthTransferred">Number of bytes sent or received (depends on the direction of the control transfer).</param> /// <returns>True on success.</returns> public virtual bool ControlTransfer(ref UsbSetupPacket setupPacket, object buffer, int bufferLength, out int lengthTransferred) { PinnedHandle pinned = new PinnedHandle(buffer); bool bSuccess = ControlTransfer(ref setupPacket, pinned.Handle, bufferLength, out lengthTransferred); pinned.Dispose(); return bSuccess; }
/// <summary> /// Copies data into <see cref="PtrData"/>. /// </summary> /// <param name="data"> /// <para>Data buffer to copy into <see cref="PtrData"/>for an output control transfer.</para> /// This value can be: /// <list type="bullet"> /// <item>An <see cref="Array"/> of bytes or other <a href="http://msdn.microsoft.com/en-us/library/75dwhxf7.aspx">blittable</a> types.</item> /// <item>An already allocated, pinned <see cref="GCHandle"/>. In this case <see cref="GCHandle.AddrOfPinnedObject"/> is used for the buffer address.</item> /// <item>An <see cref="IntPtr"/>.</item> /// </list> /// </param> /// <param name="offset">The offset in <paramref name="data"/> to begin copying.</param> /// <param name="length">Number of to copy.</param> public void SetData(object data, int offset, int length) { PinnedHandle p = new PinnedHandle(data); Byte[] temp = new byte[length]; Marshal.Copy(p.Handle, temp, offset, length); p.Dispose(); Marshal.Copy(temp, 0, PtrData, length); }