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"); } }
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; } }
public static string GetDevIdFromHandle(KLST_DEVINFO_HANDLE d) { try { return(d.SerialNumber); } catch (Exception) { } return("Unknown"); }
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)); }
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(); } }
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); }
// 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); }
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); }
// 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); }
// 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); }
// 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. } } }
public static String DeviceInfoToString(KLST_DEVINFO_HANDLE deviceInfo) { return("deviceInfo.(Pid=" + deviceInfo.Common.Pid.ToString("X4") + ",Vid=" + deviceInfo.Common.Vid.ToString("X4") + ")"); }
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); }