/// <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 override bool GetDescriptor(byte descriptorType, byte index, short langId, IntPtr buffer, int bufferLength, out int transferLength) { transferLength = 0; bool bSuccess = false; bool wasOpen = IsOpen; if (!wasOpen) { Open(); } if (!IsOpen) { return(false); } int ret = MonoUsbApi.GetDescriptor((MonoUsbDeviceHandle)mUsbHandle, descriptorType, index, buffer, (ushort)bufferLength); if (ret < 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "GetDescriptor Failed", this); } else { bSuccess = true; transferLength = ret; } if (!wasOpen && IsOpen) { Close(); } return(bSuccess); }
/// <summary> /// Submits the transfer. /// </summary> /// <remarks> /// This functions submits the USB transfer and return immediately. /// </remarks> /// <returns> /// <see cref="ErrorCode.Success"/> if the submit succeeds, /// otherwise one of the other <see cref="ErrorCode"/> codes. /// </returns> public override ErrorCode Submit() { if (mTransferCancelEvent.WaitOne(0)) { return(ErrorCode.IoCancelled); } if (!mTransferCompleteEvent.WaitOne(0)) { return(ErrorCode.ResourceBusy); } mTransfer.PtrBuffer = NextBufPtr; mTransfer.Length = RequestCount; mTransferCompleteEvent.Reset(); int ret = (int)mTransfer.Submit(); if (ret < 0) { mTransferCompleteEvent.Set(); UsbError usbErr = MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "SubmitTransfer", EndpointBase); return(usbErr.ErrorCode); } return(ErrorCode.Success); }
/// <summary> /// Refreshes the <see cref="MonoUsbProfile"/> list. /// </summary> /// <remarks> /// <para>This is your entry point into finding a USB device to operate.</para> /// <para>This return value of this function indicates the number of devices in the resultant list.</para> /// <para>The <see cref="MonoUsbProfileList"/> has a crude form of built-in device notification that works on all platforms. By adding an event handler to the <see cref="AddRemoveEvent"/> changes in the device profile list are reported when <see cref="Refresh"/> is called.</para> /// </remarks> /// <param name="sessionHandle">A valid <see cref="MonoUsbSessionHandle"/>.</param> /// <returns>The number of devices in the outputted list, or <see cref="MonoUsbError.ErrorNoMem"/> on memory allocation failure.</returns> /// <example> /// <code source="..\MonoLibUsb\MonoUsb.ShowInfo\ShowInfo.cs" lang="cs"/> /// </example> public int Refresh(MonoUsbSessionHandle sessionHandle) { lock (LockProfileList) { MonoUsbProfileList newList = new MonoUsbProfileList(); MonoUsbProfileListHandle monoUSBProfileListHandle; int ret = MonoUsbApi.GetDeviceList(sessionHandle, out monoUSBProfileListHandle); if (ret < 0 || monoUSBProfileListHandle.IsInvalid) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "Refresh:GetDeviceList Failed", this); return(ret); } int stopCount = ret; foreach (MonoUsbProfileHandle deviceProfileHandle in monoUSBProfileListHandle) { newList.mList.Add(new MonoUsbProfile(deviceProfileHandle)); stopCount--; if (stopCount <= 0) { break; } } syncWith(newList); monoUSBProfileListHandle.Dispose(); return(ret); } }
/// <summary> /// Sets an alternate interface for the most recent claimed interface. /// </summary> /// <param name="alternateID">The alternate interface to select for the most recent claimed interface See <see cref="ClaimInterface"/>.</param> /// <returns>True on success.</returns> public bool SetAltInterface(int interfaceID, int alternateID) { int ret = MonoUsbApi.SetInterfaceAltSetting((MonoUsbDeviceHandle)mUsbHandle, interfaceID, alternateID); if (ret != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "SetAltInterface Failed", this); return(false); } UsbAltInterfaceSettings[interfaceID & (UsbConstants.MAX_DEVICES - 1)] = (byte)alternateID; return(true); }
/// <summary> /// Sets the USB devices active configuration value. /// </summary> /// <param name="config">The active configuration value. A zero value means the device is not configured and a non-zero value indicates the device is configured.</param> /// <returns>True on success.</returns> /// <remarks> /// A USB device can have several different configurations, but only one active configuration. /// </remarks> public bool SetConfiguration(byte config) { int ret = MonoUsbApi.SetConfiguration((MonoUsbDeviceHandle)mUsbHandle, config); if (ret != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "SetConfiguration Failed", this); return(false); } mCurrentConfigValue = config; return(true); }
private Error GetDeviceDescriptor(out MonoUsbDeviceDescriptor monoUsbDeviceDescriptor) { Error ec = Error.Success; monoUsbDeviceDescriptor = new MonoUsbDeviceDescriptor(); //Console.WriteLine("MonoUsbProfile:GetDeviceDescriptor"); ec = (Error)MonoUsbApi.GetDeviceDescriptor(mMonoUSBProfileHandle, monoUsbDeviceDescriptor); if (ec != Error.Success) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, (int)ec, "GetDeviceDescriptor Failed", this); monoUsbDeviceDescriptor = null; } return(ec); }
/// <summary> /// Cancels pending transfers and clears the halt condition on an enpoint. /// </summary> /// <returns>True on success.</returns> public override bool Reset() { if (IsDisposed) { throw new ObjectDisposedException(GetType().Name); } Abort(); int ret = MonoUsbApi.ClearHalt((MonoUsbDeviceHandle)Device.Handle, EpNum); if (ret < 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "Endpoint Reset Failed", this); return(false); } return(true); }
/// <summary> /// Releases an interface that was previously claimed with <see cref="ClaimInterface"/>. /// </summary> /// <param name="interfaceID">The interface to release.</param> /// <returns>True on success.</returns> public bool ReleaseInterface(int interfaceID) { int ret = MonoUsbApi.ReleaseInterface((MonoUsbDeviceHandle)mUsbHandle, interfaceID); if (!mClaimedInterfaces.Remove(interfaceID)) { return(true); } if (ret != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "ReleaseInterface Failed", this); return(false); } return(true); }
/// <summary> /// Gets the USB devices active configuration value. /// </summary> /// <param name="config">The active configuration value. A zero value means the device is not configured and a non-zero value indicates the device is configured.</param> /// <returns>True on success.</returns> public override bool GetConfiguration(out byte config) { config = 0; int iconfig = 0; int ret = MonoUsbApi.GetConfiguration((MonoUsbDeviceHandle)mUsbHandle, ref iconfig); if (ret != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "GetConfiguration Failed", this); return(false); } config = (byte)iconfig; mCurrentConfigValue = config; return(true); }
/// <summary> /// Wait for the transfer to complete, timeout, or get cancelled. /// </summary> /// <param name="transferredCount">The number of bytes transferred on <see cref="ErrorCode.Success"/>.</param> /// <param name="cancel">Not used for libusb-1.0. Transfers are always cancelled on timeout or error.</param> /// <returns><see cref="ErrorCode.Success"/> if the transfer completes successfully, otherwise one of the other <see cref="ErrorCode"/> codes.</returns> public override ErrorCode Wait(out int transferredCount, bool cancel) { transferredCount = 0; int ret = 0; Error monoError; ErrorCode ec; int iWait = WaitHandle.WaitAny(new WaitHandle[] { mTransferCompleteEvent, mTransferCancelEvent }, Timeout.Infinite); switch (iWait) { case 0: // TransferCompleteEvent if (mTransfer.Status == TransferStatus.Completed) { transferredCount = mTransfer.ActualLength; return(ErrorCode.Success); } string s; monoError = MonoUsbApi.MonoLibUsbErrorFromTransferStatus(mTransfer.Status); ec = MonoUsbApi.ErrorCodeFromLibUsbError((int)monoError, out s); MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, (int)monoError, "Wait:" + s, EndpointBase); return(ec); case 1: // TransferCancelEvent ret = (int)mTransfer.Cancel(); bool bTransferComplete = mTransferCompleteEvent.WaitOne(100); mTransferCompleteEvent.Set(); if (ret != 0 || !bTransferComplete) { ec = ret == 0 ? ErrorCode.CancelIoFailed : ErrorCode.MonoApiError; MonoUsbErrorMessage.Error(ec, ret, String.Format("Wait:Unable to cancel transfer or the transfer did not return after it was cancelled. Cancelled:{0} TransferCompleted:{1}", (Error)ret, bTransferComplete), EndpointBase); return(ec); } return(ErrorCode.IoCancelled); default: // Critical failure timeout mTransfer.Cancel(); ec = ((EndpointBase.EpNum & (byte)UsbCtrlFlags.Direction_In) > 0) ? ErrorCode.ReadFailed : ErrorCode.WriteFailed; mTransferCompleteEvent.Set(); MonoUsbErrorMessage.Error(ec, ret, String.Format("Wait:Critical timeout failure! The transfer callback function was not called within the allotted time."), EndpointBase); return(ec); } }
/// <summary> /// Claims the specified interface of the device. /// </summary> /// <param name="interfaceID">The interface to claim.</param> /// <returns>True on success.</returns> public bool ClaimInterface(int interfaceID) { if (mClaimedInterfaces.Contains(interfaceID)) { return(true); } int ret = MonoUsbApi.ClaimInterface((MonoUsbDeviceHandle)mUsbHandle, interfaceID); if (ret != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "ClaimInterface Failed", this); return(false); } mClaimedInterfaces.Add(interfaceID); return(true); }
private static ErrorCode GetConfigs(MonoUsbDevice usbDevice, out List <UsbConfigInfo> configInfoListRtn) { configInfoListRtn = new List <UsbConfigInfo>(); UsbError usbError = null; List <MonoUsbConfigDescriptor> configList = new List <MonoUsbConfigDescriptor>(); int iConfigs = usbDevice.Info.Descriptor.ConfigurationCount; for (int iConfig = 0; iConfig < iConfigs; iConfig++) { MonoUsbConfigHandle nextConfigHandle; int ret = MonoUsbApi.GetConfigDescriptor(usbDevice.mMonoUSBProfile.ProfileHandle, (byte)iConfig, out nextConfigHandle); Debug.WriteLine(string.Format("GetConfigDescriptor:{0}", ret)); if (ret != 0 || nextConfigHandle.IsInvalid) { usbError = MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, String.Format("GetConfigDescriptor Failed at index:{0}", iConfig), usbDevice); return(usbError.ErrorCode); } try { MonoUsbConfigDescriptor nextConfig = new MonoUsbConfigDescriptor(); Marshal.PtrToStructure(nextConfigHandle.DangerousGetHandle(), nextConfig); UsbConfigInfo nextConfigInfo = nextConfig.ToUsbConfigInfo(usbDevice); configInfoListRtn.Add(nextConfigInfo); } catch (Exception ex) { MonoUsbErrorMessage.Error(ErrorCode.InvalidConfig, Marshal.GetLastWin32Error(), ex.ToString(), usbDevice); } finally { if (!nextConfigHandle.IsInvalid) { nextConfigHandle.Dispose(); } } } return(ErrorCode.Success); }
/// <summary> /// Sends a usb device reset command. /// </summary> /// <remarks> /// After calling <see cref="ResetDevice"/>, the <see cref="MonoUsbDevice"/> instance is disposed and /// no longer usable. A new <see cref="MonoUsbDevice"/> instance must be obtained from the device list. /// </remarks> /// <returns>True on success.</returns> public bool ResetDevice() { int ret; if (!IsOpen) { throw new UsbException(this, "Device is not opened."); } ActiveEndpoints.Clear(); if ((ret = MonoUsbApi.ResetDevice((MonoUsbDeviceHandle)mUsbHandle)) != 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "ResetDevice Failed", this); } else { Close(); } return(ret == 0); }
/// <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 override bool ControlTransfer(ref UsbSetupPacket setupPacket, IntPtr buffer, int bufferLength, out int lengthTransferred) { Debug.WriteLine(GetType().Name + ".ControlTransfer() Before", "Libusb-1.0"); int ret = MonoUsbApi.ControlTransferAsync((MonoUsbDeviceHandle)mUsbHandle, setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, (short)bufferLength, UsbConstants.DEFAULT_TIMEOUT); Debug.WriteLine(GetType().Name + ".ControlTransfer() Error:" + ((Error)ret).ToString(), "Libusb-1.0"); if (ret < 0) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, ret, "ControlTransfer Failed", this); lengthTransferred = 0; return(false); } lengthTransferred = ret; return(true); }
///<summary> /// Opens the USB device handle. ///</summary> ///<returns> ///True if the device is already opened or was opened successfully. ///False if the device does not exists or is no longer valid. ///</returns> public override bool Open() { if (IsOpen) { return(true); } MonoUsbDeviceHandle handle = new MonoUsbDeviceHandle(mMonoUSBProfile.ProfileHandle); if (handle.IsInvalid) { MonoUsbErrorMessage.Error(ErrorCode.MonoApiError, (int)MonoUsbDeviceHandle.LastErrorCode, "MonoUsbDevice.Open Failed", this); mUsbHandle = null; return(false); } mUsbHandle = handle; if (IsOpen) { return(true); } mUsbHandle.Dispose(); return(false); }