Beispiel #1
0
        private void OnHotPlugInvoked(KHOT_HANDLE hotHandle, KLST_DEVINFO_HANDLE deviceInfo, KLST_SYNC_FLAG plugType)
        {
            string symbolicLink = deviceInfo.SymbolicLink;

            switch (plugType)
            {
            case KLST_SYNC_FLAG.ADDED:
                int iRow = dgvDevices.Rows.Add(new object[] { symbolicLink, deviceInfo.DeviceDesc, deviceInfo.DeviceID });
                dgvDevices.Rows[iRow].Cells[1].ToolTipText = deviceInfo.ToString();
                dgvDevices.Rows[iRow].Cells[2].ToolTipText = deviceInfo.Common.ToString();
                break;

            case KLST_SYNC_FLAG.REMOVED:
                foreach (DataGridViewRow row in dgvDevices.Rows)
                {
                    if (row.Cells[0].Value as string != symbolicLink)
                    {
                        continue;
                    }
                    dgvDevices.Rows.Remove(row);
                    break;
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("plugType");
            }
        }
Beispiel #2
0
 private void InitDevice(KLST_DEVINFO_HANDLE deviceInfo,
                         byte readPipeId = 0xff, byte writePipeId = 0xff)
 {
     ReadPipeId         = (byte)(readPipeId | 0x80);
     WritePipeId        = (byte)(writePipeId & 0x7f);
     TransferBufferSize = -1;
     AltInterfaceId     = 0;
     //MaxTransfersTotal = 1024;
     //MaxPendingIO = 4;
     //MaxPendingTransfers = 64;
     try {
         Id = deviceInfo.SerialNumber;
     } catch (Exception) {
         Id = "Unknown";
     }
     try {
         DevPid = deviceInfo.Common.Pid;
     } catch (Exception) {
         DevPid = 0xffff;
     }
     try {
         DevVid = deviceInfo.Common.Vid;
     } catch (Exception) {
         DevVid = 0xffff;
     }
 }
Beispiel #3
0
 public static string GetDevIdFromHandle(KLST_DEVINFO_HANDLE d)
 {
     try {
         return(d.SerialNumber);
     } catch (Exception) {
     }
     return("Unknown");
 }
Beispiel #4
0
        private static void OnHotPlug(KHOT_HANDLE hotHandle,
                                      KLST_DEVINFO_HANDLE deviceInfo,
                                      KLST_SYNC_FLAG plugType)
        {
            LinkDevice d;
            int        totalPluggedDeviceCount = (int)hotHandle.GetContext().ToInt64();

            if (totalPluggedDeviceCount == int.MaxValue)
            {
                // OnHotPlug is being called for the first time on handle: hotHandle.Pointer.
                totalPluggedDeviceCount = 0;
            }
            switch (plugType)
            {
            case KLST_SYNC_FLAG.ADDED:     // Arrival.
                totalPluggedDeviceCount++;
                lock (Manager.UsbConnectionLock) {
                    if (Settings.DebugLevel > 4)
                    {
                        Log.d(TAG, "OnHotPlug.Added: " + UsbLinkDevice.DeviceInfoToString(deviceInfo));
                    }
                    if (UsbPermissionValidator.CheckAllowed(deviceInfo.Common.Vid, deviceInfo.Common.Pid))
                    {
                        UsbLinkDevice.TryOpeningDevice(deviceInfo);
                    }
                    else
                    {
                        if (Settings.DebugLevel > 4)
                        {
                            Log.d(TAG, "OnHotPlug.Added: Not allowed: " + UsbLinkDevice.DeviceInfoToString(deviceInfo));
                        }
                    }
                }
                break;

            case KLST_SYNC_FLAG.REMOVED:     // Removal.
                totalPluggedDeviceCount--;
                lock (Manager.UsbConnectionLock) {
                    if (Settings.DebugLevel > 4)
                    {
                        Log.d(TAG, "OnHotPlug.Removed: " + UsbLinkDevice.DeviceInfoToString(deviceInfo));
                    }
                    d = LinkManager.Manager.FindDevice(UsbLinkDevice.GetDevIdFromHandle(deviceInfo));
                    UsbLinkDevice u = d as UsbLinkDevice;
                    if (u != null)
                    {
                        u.Disconnect(deviceInfo);                // Disconnect device but keep in Active list.
                    }
                }
                break;

            default:
                return;
            }
            hotHandle.SetContext(new IntPtr(totalPluggedDeviceCount));
        }
Beispiel #5
0
 public void Disconnect(KLST_DEVINFO_HANDLE deviceInfo)
 {
     if (Settings.DebugLevel > 4)
     {
         Log.d(TAG, "Disconnect: u=" + this.ToString());
         Log.d(TAG, "Disconnect: " + DeviceInfoToString(deviceInfo));
     }
     if (CompareVidPid(this, deviceInfo))
     {
         if (Settings.DebugLevel > 4)
         {
             Log.d(TAG, "Disconnect: suspend.");
         }
         Suspend();
         DriverClose();
     }
 }
Beispiel #6
0
        protected override void WndProc(ref Message m)
        {
            /* When using the HotK UserHwnd and UserMsg, the add/remove events are seperated into to different messages.
             * Removal = UserMsg + 0
             * Arrival = UserMsg + 1
             */
            if (m.Msg == WM_USER_HOT_REMOVAL || m.Msg == WM_USER_HOT_ARRIVAL)
            {
                KHOT_HANDLE         hotHandle  = new KHOT_HANDLE(m.WParam);
                KLST_DEVINFO_HANDLE deviceInfo = new KLST_DEVINFO_HANDLE(m.LParam);
                KLST_SYNC_FLAG      plugType   = (m.Msg == WM_USER_HOT_REMOVAL) ? KLST_SYNC_FLAG.REMOVED : KLST_SYNC_FLAG.ADDED;

                OnHotPlugInvoked(hotHandle, deviceInfo, plugType);
                return;
            }
            base.WndProc(ref m);
        }
Beispiel #7
0
 // Note: set pipeId's to 0xff to pick default bulk endpoints.
 private UsbLinkDevice(KLST_DEVINFO_HANDLE deviceInfo,
                       byte readPipeId = 0xff, byte writePipeId = 0xff)
 {
     AllocId           = ++AllocCounter;
     UsbLock           = new Object();
     DriverAPI         = null;
     IsFTDI            = false;
     TempWriteBuffer   = new byte[UsbMaxBufferSize];
     TempReadBuffer    = new byte[UsbMaxBufferSize];
     TempControlBuffer = new byte[UsbMaxBufferSize];
     // SUPER IMPORTANT:
     // IO buffers MUST be pinned to stop GC moving them,
     // Otherwise read/writes will be corrupted!
     gcHndWrite   = GCHandle.Alloc(TempWriteBuffer, GCHandleType.Pinned);
     gcHndRead    = GCHandle.Alloc(TempReadBuffer, GCHandleType.Pinned);
     gcHndControl = GCHandle.Alloc(TempControlBuffer, GCHandleType.Pinned);
     InitDevice(deviceInfo, readPipeId, writePipeId);
 }
Beispiel #8
0
        private static void OnHotPlug(KHOT_HANDLE hotHandle,
                                      KLST_DEVINFO_HANDLE deviceInfo,
                                      KLST_SYNC_FLAG plugType)
        {
            string plugText;

            int totalPluggedDeviceCount = (int)hotHandle.GetContext().ToInt64();

            if (totalPluggedDeviceCount == int.MaxValue)
            {
                Console.WriteLine("OnHotPlug is being called for the first time on handle:{0}", hotHandle.Pointer);
                totalPluggedDeviceCount = 0;
            }

            switch (plugType)
            {
            case KLST_SYNC_FLAG.ADDED:
                plugText = "Arrival";
                totalPluggedDeviceCount++;
                break;

            case KLST_SYNC_FLAG.REMOVED:
                plugText = "Removal";
                totalPluggedDeviceCount--;
                break;

            default:
                throw new ArgumentOutOfRangeException("plugType");
            }

            hotHandle.SetContext(new IntPtr(totalPluggedDeviceCount));

            Console.WriteLine("\n[OnHotPlug] Device {0}:{1} \n",
                              plugText,
                              deviceInfo);
            Console.WriteLine("Total Plugged Device Count: {0}",
                              totalPluggedDeviceCount);
        }
Beispiel #9
0
        // Check that LinkDevice and DEVINFO refer to same device by comparing Vid & Pid.
        // Returns truee if they do.
        public static bool CompareVidPid(LinkDevice d, KLST_DEVINFO_HANDLE h)
        {
            UsbLinkDevice u = d as UsbLinkDevice;

            return(u != null && u.DevPid == h.Common.Pid && u.DevVid == h.Common.Vid);
        }
Beispiel #10
0
        // When device is (re)connected, enumerate endpoints and set policy.
        // Returns null on success or error message.
        private string ConfigureDevice(KLST_DEVINFO_HANDLE deviceInfo, bool checkForAccessory = false)
        {
            IsWriting = false;
            IsReading = false;
            if (State != ComponentState.Unresponsive || checkForAccessory || DriverAPI == null)
            {
                // libusbK class contructors can throw exceptions; For instance, if the device is
                // using the WinUsb driver and already in-use by another application.
                // This could happen if this App was previsouly aborted.
                try {
                    if (DriverAPI != null)
                    {
                        DriverClose();
                    }
                    DriverAPI = new UsbK(deviceInfo);
                } catch (Exception e) {
                    DriverAPI = null;
                    return("Unable to initialize device:" + e.Message);
                }
            }
            try {
                DriverAPI.ResetDevice();
            } catch (Exception e) {
                return("Unable to reset device:" + e.Message);
            }

            // Find Pipe And Interface.
            byte interfaceIndex = 0; bool hasRead = false, hasWrite = false;
            USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
            WINUSB_PIPE_INFORMATION  PipeInfo;

            while (DriverAPI.SelectInterface(interfaceIndex, true))
            {
                byte altSettingNumber = 0;
                while (DriverAPI.QueryInterfaceSettings(altSettingNumber, out InterfaceDescriptor))
                {
                    if (AltInterfaceId == -1 || AltInterfaceId == altSettingNumber)
                    {
                        byte pipeIndex = 0;
                        while (DriverAPI.QueryPipe(altSettingNumber, pipeIndex++, out PipeInfo))
                        {
                            if (PipeInfo.MaximumPacketSize > 0)
                            {
                                if (!hasRead &&
                                    ((PipeInfo.PipeId == ReadPipeId) ||
                                     ((((ReadPipeId & 0xF) == 0) || (ReadPipeId == 0xff)) &&
                                      ((ReadPipeId & 0x80) == (PipeInfo.PipeId & 0x80))))
                                    )
                                {
                                    ReadPipeId = PipeInfo.PipeId;
                                    hasRead    = true;
                                }
                                if (!hasWrite &&
                                    ((PipeInfo.PipeId == WritePipeId) ||
                                     ((((WritePipeId & 0xF) == 0) || (WritePipeId == 0x7f)) &&
                                      ((WritePipeId & 0x80) == (PipeInfo.PipeId & 0x80))))
                                    )
                                {
                                    WritePipeId = PipeInfo.PipeId;
                                    hasWrite    = true;
                                    if (TransferBufferSize == -1)
                                    {
                                        TransferBufferSize = PipeInfo.MaximumPacketSize;
                                    }
                                }
                                if (hasRead && hasWrite)
                                {
                                    goto FindInterfaceDone;
                                }
                            }
                            PipeInfo.PipeId = 0;
                        }
                    }
                    altSettingNumber++;
                }
                interfaceIndex++;
            }
FindInterfaceDone:
            if (!hasRead && !hasWrite)
            {
                return("Unable to open i/o pipes:R=" + hasRead + ",W=" + hasWrite + ".");
            }

            ReadPipeId  |= 0x80;
            WritePipeId &= 0x7f;
            if (TransferBufferSize == -1)
            {
                TransferBufferSize = 64;
            }
#if false // TODO: should test this.
            // Set interface alt setting.
            if (!DriverAPI.SetAltInterface(InterfaceDescriptor.bInterfaceNumber, false,
                                           InterfaceDescriptor.bAlternateSetting))
            {
                return("Unable to set Alt Interface");
            }
#endif
            bool isAccessory = UsbLinkAccessory.IsAccessory(deviceInfo.Common.Vid, deviceInfo.Common.Pid);

            // Set configuration for accessory.
            if (isAccessory)
            {
                int configNum = 0;
                if (GetConfiguration(out configNum))
                {
                    if (configNum != 1)
                    {
                        if (!SetConfiguration(1))
                        {
                            return("Unable to set configuration");
                        }
                    }
                }
            }

            // In most cases, the pipe timeout policy should be set before using synchronous I/O.
            // By default, sync transfers wait infinitely for a transfer to complete.
            // Set the pipe timeout policy to 0 for infinite timeout.
            int[] pipeTimeoutMS  = new[] { 0 };
            int[] autoClearStall = new[] { 1 };
            DriverAPI.SetPipePolicy(ReadPipeId, (int)PipePolicyType.PIPE_TRANSFER_TIMEOUT,
                                    Marshal.SizeOf(typeof(int)), pipeTimeoutMS);
            DriverAPI.SetPipePolicy(ReadPipeId, (int)PipePolicyType.AUTO_CLEAR_STALL,
                                    Marshal.SizeOf(typeof(int)), autoClearStall);
            DriverAPI.SetPipePolicy(WritePipeId, (int)PipePolicyType.PIPE_TRANSFER_TIMEOUT,
                                    Marshal.SizeOf(typeof(int)), pipeTimeoutMS);
            DriverAPI.SetPipePolicy(WritePipeId, (int)PipePolicyType.AUTO_CLEAR_STALL,
                                    Marshal.SizeOf(typeof(int)), autoClearStall);

            /*
             * int[] useRawIO = new[] { 1 };
             * mUsb.SetPipePolicy(mReadPipeId, (int)PipePolicyType.RAW_IO,
             *                  Marshal.SizeOf(typeof(int)), useRawIO);
             */

            // Next, check if it's an accessory.
            if (checkForAccessory &&
                !isAccessory &&
                UsbLinkAccessory.TryOpeningAccessory(this))
            {
                return("Switching to accessory mode.");
            }

            // Finally, check if it's an FTDI device.
            IsFTDI = FTDIHandler.IsFtdiDevice(this);
            if (IsFTDI)
            {
                if (!FTDIHandler.ConfigureFTDI(this))
                {
                    return("Unable to configure FTDI device.");
                }
            }
            return(null);
        }
Beispiel #11
0
        // As well as opening the device:
        // Try putting it into accessory mode as necessary.
        // Returns null if unable to open or it was switched into accessory mode.
        // The steps for determining whether to connect to a usb device are:
        // 1) Consult vid/pid include & exclude lists.
        // 2) Open device.
        public static void TryOpeningDevice(KLST_DEVINFO_HANDLE deviceInfo)
        {
            bool          isNewDev, checkForAccessory;
            string        devId = GetDevIdFromHandle(deviceInfo);
            LinkDevice    d     = LinkManager.Manager.FindDevice(devId);
            UsbLinkDevice u     = d as UsbLinkDevice;

            if (u != null)
            {
                if (u.State == ComponentState.Working || u.State == ComponentState.Unresponsive)
                {
                    if (Settings.DebugLevel > 4)
                    {
                        Log.d(TAG, "TryOpeningDevice: already open:" + DeviceInfoToString(deviceInfo));
                    }
                    return;
                }
                // Check if d is a suspended Acc with same SN but different V/P.
                checkForAccessory = true; // !CompareVidPid(d, deviceInfo);
                u.CloseDevice();          //FIX: should already be closed?
                u.InitDevice(deviceInfo);
                isNewDev = false;
            }
            else
            {
                checkForAccessory = true;
                u        = new UsbLinkDevice(deviceInfo);
                isNewDev = true;
            }
            string result = null;

            lock (u.UsbLock) {
                result = u.ConfigureDevice(deviceInfo, checkForAccessory);
            }
            if (result == null)
            {
                u.SetSessionId();
                if (isNewDev)
                {
                    LinkManager.Manager.AddDevice(u.Id, u);
                    u.InitThreads();
                    u.NotifyStateChange(ComponentState.Working);
                }
                else
                {
                    u.Resume();
                }
            }
            else
            {
                u.DriverClose();
                if (Settings.DebugLevel > 4)
                {
                    Log.d(TAG, "ConfigureDevice: " + result);
                }
                if (!isNewDev)
                {
                    u.NotifyStateChange(ComponentState.Problem);
                }
                else             // Gets here if device was switched to acc mode.
                {
                    u.Id = null; // Prevents LinkManager.DeleteDevice being called on Close.
                }
            }
        }
Beispiel #12
0
 public static String DeviceInfoToString(KLST_DEVINFO_HANDLE deviceInfo)
 {
     return("deviceInfo.(Pid=" + deviceInfo.Common.Pid.ToString("X4") + ",Vid=" + deviceInfo.Common.Vid.ToString("X4") + ")");
 }
Beispiel #13
0
        private void OnHotPlug(KHOT_HANDLE hotHandle,
                               KLST_DEVINFO_HANDLE deviceInfo,
                               KLST_SYNC_FLAG plugType)
        {
            string plugText;

            int totalPluggedDeviceCount = (int)hotHandle.GetContext().ToInt64();

            if (totalPluggedDeviceCount == int.MaxValue)
            {
                Console.WriteLine("OnHotPlug is being called for the first time on handle:{0}", hotHandle.Pointer);
                totalPluggedDeviceCount = 0;
            }

            switch (plugType)
            {
            case KLST_SYNC_FLAG.ADDED:
                plugText = "Arrival";
                totalPluggedDeviceCount++;
                if (deviceInfo.DeviceID.Contains("VID_2DC4&PID_0200"))
                {
                    bool deviceFound = false;
                    setUI(HUD_STATE.Application);
                    DarwinDevice = new StmTestParameters(SIX15_VID, SIX15_PID, 0, 0x02, 512, null, -1, 4, 0);

                    if (DarwinDevice != null)
                    {
                        // Find and configure the device.
                        if (!DarwinDevice.ConfigureDevice(out pipeInfo, out usb, out interfaceDescriptor))
                        {
                            DarwinDevice = new StmTestParameters(SIX15_VID, SIX15_PID, 0, 0x06, 128, null, -1, 4, 0);

                            if (!DarwinDevice.ConfigureDevice(out pipeInfo, out usb, out interfaceDescriptor))
                            {
                                Console.WriteLine("Device not connected");
                                setUI(HUD_STATE.NotDetected);
                            }
                            else
                            {
                                Console.WriteLine("IS NEXT GEN FIRMWARE");
                                isNextGen   = true;
                                deviceFound = true;
                            }
                        }
                        else
                        {
                            deviceFound = true;
                        }

                        if (deviceFound)
                        {
                            if (DarwinDevice.TransferBufferSize == -1)
                            {
                                DarwinDevice.TransferBufferSize = pipeInfo.MaximumPacketSize * 512;
                            }

                            Console.WriteLine("Darwin Device Connected");

                            int[] pipeTimeoutMS = new[] { 0 };
                            usb.SetPipePolicy((byte)DarwinDevice.PipeId,
                                              (int)PipePolicyType.PIPE_TRANSFER_TIMEOUT,
                                              Marshal.SizeOf(typeof(int)),
                                              pipeTimeoutMS);
                        }
                    }
                }
                else if (deviceInfo.DeviceID.Contains("VID_0483&PID_5740"))
                {
                    setUI(HUD_STATE.Bootloader);
                    DarwinDevice = new StmTestParameters(STM_VID, STM_PID, 0, 0x01, 512, null, -1, 4, 0);

                    if (DarwinDevice != null)
                    {
                        // Find and configure the device.
                        if (!DarwinDevice.ConfigureDevice(out pipeInfo, out usb, out interfaceDescriptor))
                        {
                            Console.WriteLine("Device not connected");
                            setUI(HUD_STATE.NotDetected);
                        }
                        else
                        {
                            if (DarwinDevice.TransferBufferSize == -1)
                            {
                                DarwinDevice.TransferBufferSize = pipeInfo.MaximumPacketSize * 512;
                            }

                            Console.WriteLine("Darwin Device Connected");

                            int[] pipeTimeoutMS = new[] { 0 };
                            usb.SetPipePolicy((byte)DarwinDevice.PipeId,
                                              (int)PipePolicyType.PIPE_TRANSFER_TIMEOUT,
                                              Marshal.SizeOf(typeof(int)),
                                              pipeTimeoutMS);
                        }
                    }
                }
                break;

            case KLST_SYNC_FLAG.REMOVED:
                plugText = "Removal";
                totalPluggedDeviceCount--;
                if (deviceInfo.DeviceID.Contains("VID_2DC4&PID_0200"))
                {
                    if (DarwinDevice != null)
                    {
                        if (isNextGen)
                        {
                            usb.FlushPipe(EP_DISP);
                        }
                        else
                        {
                            usb.FlushPipe(EP_CDC);
                        }

                        DarwinDevice.Free();
                        usb.Free();
                        DarwinDevice = null;
                        setUI(HUD_STATE.NotDetected);
                    }
                    else if (deviceInfo.DeviceID.Contains("VID_0483&PID_5740"))
                    {
                        usb.FlushPipe(EP_CDC_BL);
                        DarwinDevice.Free();
                        usb.Free();
                        DarwinDevice = null;
                        setUI(HUD_STATE.NotDetected);
                    }
                }
                break;

            default:
                throw new ArgumentOutOfRangeException("plugType");
            }

            hotHandle.SetContext(new IntPtr(totalPluggedDeviceCount));

            Console.WriteLine("\n[OnHotPlug] Device {0}:{1} \n",
                              plugText,
                              deviceInfo);
            Console.WriteLine("Total Plugged Device Count: {0}",
                              totalPluggedDeviceCount);
        }