예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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);
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
        /// <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);
            }
        }
예제 #11
0
        /// <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);
        }
예제 #12
0
        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);
        }
예제 #13
0
        /// <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);
        }
예제 #14
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);
        }
예제 #15
0
        ///<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);
        }