Class representing a Libusb-1.0 session session handle. Session handled are wrapped in a System.Runtime.ConstrainedExecution.CriticalFinalizerObject.

The concept of individual Libusb-1.0 sessions allows for your program to use two libraries (or dynamically load two modules) which both independently use libusb. This will prevent interference between the individual libusb users - for example MonoUsbApi.SetDebug will not affect the other user of the library, and SafeHandle.Close will not destroy resources that the other user is still using.

Sessions are created when a new MonoUsbSessionHandle instance is created and destroyed through SafeHandle.Close.

A MonoUsbSessionHandle instance must be created before calling any other Libusb-1.0 API function.

Session handles are equivalent to a libusb_context.

Inheritance: LibUsbDotNet.Main.SafeContextHandle
        /// <summary>
        /// Stops the handle events thread and closes the session handle.
        /// </summary>
        public static void Exit()
        {
            Stop(true);
            if (mSessionHandle == null) return;

            if (mSessionHandle.IsInvalid) return;
            mSessionHandle.Close();
            mSessionHandle = null;
        }
Example #2
0
        /// <summary>
        /// Convenience function for finding a device with a particular idVendor/idProduct combination.
        /// </summary>
        /// <remarks>
        /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="dev"/></note>
        /// </remarks>
        /// <param name="sessionHandle">A valid <see cref="MonoUsbSessionHandle"/>.</param>
        /// <param name="vendorID">The idVendor value to search for.</param>
        /// <param name="productID">The idProduct value to search for.</param>
        /// <returns>Null if the device was not opened or not found, otherwise an opened device handle.</returns>
        public static MonoUsbDeviceHandle OpenDeviceWithVidPid([In] MonoUsbSessionHandle sessionHandle, short vendorID, short productID)
        {
            IntPtr pHandle = OpenDeviceWithVidPidInternal(sessionHandle, vendorID, productID);

            if (pHandle == IntPtr.Zero)
            {
                return(null);
            }
            return(new MonoUsbDeviceHandle(pHandle));
        }
        private static void HandleEventFn(object oHandle)
        {
            MonoUsbSessionHandle sessionHandle = oHandle as MonoUsbSessionHandle;

            mIsStoppedEvent.Reset();

            while (mRunning)
            {
                MonoUsbApi.HandleEventsTimeout(sessionHandle, ref mWaitUnixNativeTimeval);
            }

            mIsStoppedEvent.Set();
        }
 private static void Init(UnixNativeTimeval unixNativeTimeval)
 {
     if (IsStopped && !mRunning && mSessionHandle == null)
     {
         mWaitUnixNativeTimeval = unixNativeTimeval;
         mSessionHandle         = new MonoUsbSessionHandle();
         if (mSessionHandle.IsInvalid)
         {
             mSessionHandle = null;
             throw new UsbException(typeof(MonoUsbApi), String.Format("Init:libusb_init Failed:Invalid Session Handle"));
         }
     }
 }
        /// <summary>
        /// Stops the handle events thread and closes the session handle.
        /// </summary>
        public static void Exit()
        {
            Stop(true);
            if (mSessionHandle == null)
            {
                return;
            }

            if (mSessionHandle.IsInvalid)
            {
                return;
            }
            mSessionHandle.Dispose();
            mSessionHandle = null;
        }
        /// <summary>
        /// 	Creates a new ProgrammingConnection; if the Unified Lab Kit can't be found, 
        /// 	it throws a DeviceNotConnected excpetion.
        /// </summary>	
        /// <param name="Timeout">
        /// 	The amount of time to wait before the system decides the device isn't connected.
        /// </param>
        public ProgrammingConnection(short timeout)
        {
            int retries = 5;

            //store the timeout field from the constructor
            this.timeout = timeout;

            //create a new local USB session
            session = new MonoUsbSessionHandle();

            while (retries-- > 0)
            {
                try
                {
                    //find the device by its descriptor
                    device = MonoUsbApi.OpenDeviceWithVidPid(session, VID, PID);
                }
                catch (ObjectDisposedException ex)
                {
                    if (retries == 0)
                    {
                        //DEBUG
                        DebugConsole.WriteLine("Windows could not create the USB connection... try again in a few seconds?");
                        throw ex;
                    }

                    //DEBUG
                    DebugConsole.WriteLine("Too soon! Retrying in 15s.");
                    System.Threading.Thread.Sleep(15000);

                    continue;
                }

                //break on success
                break;
            }

            if (device == null)
                throw new DeviceNotFoundException();

            //if the kernel has a driver operating on our interface, ask it to detach
            if (MonoUsbApi.KernelDriverActive(device, 0) >= 0)
                if (MonoUsbApi.DetachKernelDriver(device, 0) < 0)
                    throw new DeviceInUseException();

            //claim our interface for exclusive access
            MonoUsbApi.ClaimInterface(device, 0);
        }
        /// <summary>
        /// 	Creates a new ProgrammingConnection; if the Unified Lab Kit can't be found, 
        /// 	it throws a DeviceNotConnected excpetion.
        /// </summary>	
        /// <param name="Timeout">
        /// 	The amount of time to wait before the system decides the device isn't connected.
        /// </param>
        public MonoProgrammingConnection()
        {
            //create a new local USB session
            session = new MonoUsbSessionHandle();

            //find the device by its descriptor
            device = MonoUsbApi.OpenDeviceWithVidPid(session, VID, PID);

            if(device==null)
                throw new DeviceNotFoundException();

            //if the kernel has a driver operating on our interface, ask it to detach
            if(MonoUsbApi.KernelDriverActive(device, 0) >=0 )
                if(MonoUsbApi.DetachKernelDriver(device, 0) < 0)
                    throw new DeviceInUseException();

            //claim our interface for exclusive access
            MonoUsbApi.ClaimInterface(device, 0);
        }
Example #8
0
        /// <summary>
        /// Retrieve a list of file descriptors that should be polled by your main loop as libusb event sources.
        /// </summary>
        /// <remarks>
        /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="poll"/></note>
        /// </remarks>
        /// <param name="sessionHandle">A valid <see cref="MonoUsbSessionHandle"/>.</param>
        /// <returns>A list of PollfdItem structures, or null on error.</returns>
        public static List <PollfdItem> GetPollfds(MonoUsbSessionHandle sessionHandle)
        {
            List <PollfdItem> rtnList = new List <PollfdItem>();
            IntPtr            pList   = GetPollfdsInternal(sessionHandle);

            if (pList == IntPtr.Zero)
            {
                return(null);
            }

            IntPtr pNext = pList;
            IntPtr pPollfd;

            while ((((pNext != IntPtr.Zero))) && (pPollfd = Marshal.ReadIntPtr(pNext)) != IntPtr.Zero)
            {
                PollfdItem pollfdItem = new PollfdItem(pPollfd);
                rtnList.Add(pollfdItem);
                pNext = new IntPtr(pNext.ToInt64() + IntPtr.Size);
            }
            Marshal.FreeHGlobal(pList);

            return(rtnList);
        }
Example #9
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))
                {
                    r = HandleEvents(pSessionHandle);
                    if (r < 0)
                    {
                        if (r == (int)MonoUsbError.ErrorInterrupted)
                        {
                            continue;
                        }
                        transfer.Cancel();
                        while (!completeEvent.WaitOne(0))
                        {
                            if (HandleEvents(pSessionHandle) < 0)
                            {
                                break;
                            }
                        }
                        transfer.Free();
                        gcCompleteEvent.Free();
                        return(r);
                    }
                }
            }
            else
            {
                completeEvent.WaitOne(Timeout.Infinite);
            }

            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);
        }
Example #10
0
        /// <summary>
        /// Retrieve a list of file descriptors that should be polled by your main loop as libusb event sources. 
        /// </summary>
        /// <remarks>
        /// <note type="tip" title="Libusb-1.0 API:"><seelibusb10 group="poll"/></note>
        /// </remarks>
        /// <param name="sessionHandle">A valid <see cref="MonoUsbSessionHandle"/>.</param>
        /// <returns>A list of PollfdItem structures, or null on error.</returns>
        public static List<PollfdItem> GetPollfds(MonoUsbSessionHandle sessionHandle)
        {
            List<PollfdItem> rtnList = new List<PollfdItem>();
            IntPtr pList = GetPollfdsInternal(sessionHandle);
            if (pList == IntPtr.Zero) return null;

            IntPtr pNext = pList;
            IntPtr pPollfd;
            while ((((pNext != IntPtr.Zero))) && (pPollfd = Marshal.ReadIntPtr(pNext)) != IntPtr.Zero)
            {
                PollfdItem pollfdItem = new PollfdItem(pPollfd);
                rtnList.Add(pollfdItem);
                pNext = new IntPtr(pNext.ToInt64() + IntPtr.Size);
            }
            Marshal.FreeHGlobal(pList);

            return rtnList;
        }
Example #11
0
        private static void Main(string[] args)
        {
            // Assign the control transfer delegate to the callback function.
            controlTransferDelegate = ControlTransferCB;

            // Initialize the context.
            sessionHandle = new MonoUsbSessionHandle();
            if (sessionHandle.IsInvalid)
                throw new Exception(String.Format("Failed intializing libusb context.\n{0}:{1}",
                                                  MonoUsbSessionHandle.LastErrorCode,
                                                  MonoUsbSessionHandle.LastErrorString));

            MonoUsbProfileList profileList = new MonoUsbProfileList();
            MonoUsbDeviceHandle myDeviceHandle = null;

            try
            {
                // The list is initially empty.
                // Each time refresh is called the list contents are updated.
                profileList.Refresh(sessionHandle);

                // Use the GetList() method to get a generic List of MonoUsbProfiles
                // Find the first profile that matches in MyVidPidPredicate.
                MonoUsbProfile myProfile = profileList.GetList().Find(MyVidPidPredicate);
                if (myProfile == null)
                {
                    Console.WriteLine("Device not connected.");
                    return;
                }

                // Open the device handle to perform I/O
                myDeviceHandle = myProfile.OpenDeviceHandle();
                if (myDeviceHandle.IsInvalid)
                    throw new Exception(String.Format("Failed opening device handle.\n{0}:{1}",
                                                      MonoUsbDeviceHandle.LastErrorCode,
                                                      MonoUsbDeviceHandle.LastErrorString));
                int ret;
                MonoUsbError e;

                // Set Configuration
                e = (MonoUsbError) (ret = MonoUsbApi.SetConfiguration(myDeviceHandle, 1));
                if (ret < 0) throw new Exception(String.Format("Failed SetConfiguration.\n{0}:{1}", e, MonoUsbApi.StrError(e)));

                // Claim Interface
                e = (MonoUsbError) (ret = MonoUsbApi.ClaimInterface(myDeviceHandle, 0));
                if (ret < 0) throw new Exception(String.Format("Failed ClaimInterface.\n{0}:{1}", e, MonoUsbApi.StrError(e)));

                // Create a vendor specific control setup, allocate 1 byte for return control data.
                byte requestType = (byte)(UsbCtrlFlags.Direction_In | UsbCtrlFlags.Recipient_Device | UsbCtrlFlags.RequestType_Vendor);
                byte request = 0x0F;
                MonoUsbControlSetupHandle controlSetupHandle = new MonoUsbControlSetupHandle(requestType, request, 0, 0, 1);

                // Transfer the control setup packet
                ret = libusb_control_transfer(myDeviceHandle, controlSetupHandle, 1000);
                if (ret > 0)
                {
                    Console.WriteLine("\nSuccess!\n");
                    byte[] ctrlDataBytes = controlSetupHandle.ControlSetup.GetData(ret);
                    string ctrlDataString = Helper.HexString(ctrlDataBytes, String.Empty, "h ");
                    Console.WriteLine("Return Length: {0}", ret);
                    Console.WriteLine("DATA (hex)   : [ {0} ]\n", ctrlDataString.Trim());
                }
                MonoUsbApi.ReleaseInterface(myDeviceHandle, 0);
            }
            finally
            {
                profileList.Close();
                if (myDeviceHandle != null) myDeviceHandle.Close();
                sessionHandle.Close();
            }
        }
Example #12
0
        public static void Main(string[] args)
        {
            // Initialize the context.
            sessionHandle = new MonoUsbSessionHandle();
            if (sessionHandle.IsInvalid)
                throw new Exception(String.Format("Failed intialized libusb context.\n{0}:{1}",
                                                  MonoUsbSessionHandle.LastErrorCode,
                                                  MonoUsbSessionHandle.LastErrorString));

            MonoUsbProfileList profileList = new MonoUsbProfileList();

            // The list is initially empty.
            // Each time refresh is called the list contents are updated.
            int ret = profileList.Refresh(sessionHandle);
            if (ret < 0) throw new Exception("Failed to retrieve device list.");
            Console.WriteLine("{0} device(s) found.", ret);

            // Use the GetList() method to get a generic List of MonoUsbProfiles
            // Find all profiles that match in the MyVidPidPredicate.
            List<MonoUsbProfile> myVidPidList = profileList.GetList().FindAll(MyVidPidPredicate);

            // myVidPidList reresents a list of connected USB devices that matched
            // in MyVidPidPredicate.
            foreach (MonoUsbProfile profile in myVidPidList)
            {
                // Write the VendorID and ProductID to console output.
                Console.WriteLine("[Device] Vid:{0:X4} Pid:{1:X4}", profile.DeviceDescriptor.VendorID, profile.DeviceDescriptor.ProductID);

                // Loop through all of the devices configurations.
                for (byte i = 0; i < profile.DeviceDescriptor.ConfigurationCount; i++)
                {
                    // Get a handle to the configuration.
                    MonoUsbConfigHandle configHandle;
                    if (MonoUsbApi.GetConfigDescriptor(profile.ProfileHandle, i, out configHandle) < 0) continue;
                    if (configHandle.IsInvalid) continue;

                    // Create a MonoUsbConfigDescriptor instance for this config handle.
                    MonoUsbConfigDescriptor configDescriptor = new MonoUsbConfigDescriptor(configHandle);

                    // Write the bConfigurationValue to console output.
                    Console.WriteLine("  [Config] bConfigurationValue:{0}", configDescriptor.bConfigurationValue);

                    // Interate through the InterfaceList
                    foreach (MonoUsbInterface usbInterface in configDescriptor.InterfaceList)
                    {
                        // Interate through the AltInterfaceList
                        foreach (MonoUsbAltInterfaceDescriptor usbAltInterface in usbInterface.AltInterfaceList)
                        {
                            // Write the bInterfaceNumber and bAlternateSetting to console output.
                            Console.WriteLine("    [Interface] bInterfaceNumber:{0} bAlternateSetting:{1}",
                                              usbAltInterface.bInterfaceNumber,
                                              usbAltInterface.bAlternateSetting);

                            // Interate through the EndpointList
                            foreach (MonoUsbEndpointDescriptor endpoint in usbAltInterface.EndpointList)
                            {
                                // Write the bEndpointAddress, EndpointType, and wMaxPacketSize to console output.
                                Console.WriteLine("      [Endpoint] bEndpointAddress:{0:X2} EndpointType:{1} wMaxPacketSize:{2}",
                                                  endpoint.bEndpointAddress,
                                                  (EndpointType) (endpoint.bmAttributes & 0x3),
                                                  endpoint.wMaxPacketSize);
                            }
                        }
                    }
                    // Not neccessary, but good programming practice.
                    configHandle.Close();
                }
            }
            // Not neccessary, but good programming practice.
            profileList.Close();
            // Not neccessary, but good programming practice.
            sessionHandle.Close();
        }
 private static void Init(UnixNativeTimeval unixNativeTimeval)
 {
     if (IsStopped && !mRunning && mSessionHandle==null)
     {
         mWaitUnixNativeTimeval = unixNativeTimeval;
         mSessionHandle=new MonoUsbSessionHandle();
         if (mSessionHandle.IsInvalid)
         {
             mSessionHandle = null;
             throw new UsbException(typeof (MonoUsbApi), String.Format("Init:libusb_init Failed:Invalid Session Handle"));
         }
     }
 }