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)); }
// Scan the current usb devices to check all connected. private void CheckConnections() { lock (UsbConnectionLock) { KLST_DEVINFO_HANDLE deviceInfo; LstK lst = new LstK(KLST_FLAG.NONE); int deviceCount = 0; lst.Count(ref deviceCount); while (lst.MoveNext(out deviceInfo)) { LinkDevice d = LinkManager.Manager.FindDevice(UsbLinkDevice.GetDevIdFromHandle(deviceInfo)); // Check if d is a suspended Acc with same SN but different V/P. if (d == null || ((d.State != ComponentState.Working) /*&& !UsbLinkDevice.CompareVidPid(d, deviceInfo)*/)) { if (UsbPermissionValidator.CheckAllowed(deviceInfo.Common.Vid, deviceInfo.Common.Pid)) { UsbLinkDevice.TryOpeningDevice(deviceInfo); } } } lst.Free(); } }
// 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); }
// 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. } } }
/// <summary> /// Configure for FT230XS. /// </summary> /// <param name="dev">The usb device to try to configure.</param> /// <returns>Returns true on success.</returns> public static bool ConfigureFTDI(UsbLinkDevice dev) { byte request; ushort value; ushort index; // Reset command. request = 0x00; value = 0x0000; // Purge RX & TX. index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set modem control reg. request = 0x01; value = 0x0000; //0x0000 = DTR & RTS off. index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set flow control. request = 0x02; value = 0x0000; // No Xon & Xoff. index = 0x01; // Port A + no flow control. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set baud rate. request = 0x03; value = 0x0034; // 57600 => div=0x34, subdiv = 0x03 => 0xC000. index = 0x0; // Index used for Baud High, set bit 0 to zero. Not used for Port number. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set data. request = 0x04; value = 0x0008; // 8 bit data, no parity, 1 stop bit, no break. index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set event char. request = 0x06; value = 0x0000; // None. index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set error char. request = 0x07; value = 0x0000; // None. index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set latency timer. request = 0x09; value = 0x002; // Or 2 ms! index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } // Set bit mode. request = 0x0B; value = 0x0000; // 0x0000 = Off. Or should it be 0x4000? index = 0x1; // Port A. if (!dev.ControlTransfer(UsbCh9.USB_TYPE_VENDOR, request, value, index)) { return(false); } return(true); }
public static bool IsFtdiDevice(UsbLinkDevice dev) { return(IsFtdiDevice(dev.DevVid, dev.DevPid)); }
// Returns true if device was switched into Android accessory mode. // Note: only use u for ControlTransfer since vid/pid may be stale. public static bool TryOpeningAccessory(UsbLinkDevice u) { byte[] ioBuffer = new byte[2]; int outLen = 0; bool response; string serialNumber = ACCSerialNumber; if (String.IsNullOrWhiteSpace(serialNumber) || (serialNumber.Length < 2)) { serialNumber = Settings.SerialNumberFormatter(Lima.GetComputerCode(), 'B', 'X'); } // response = u.mUsb.ResetDevice(); // if(!response) { ShowLastError(); return null; } // Note: this clears strings on device too. response = u.ControlTransfer(UsbRqstInVendor, ACCESSORY_GET_PROTOCOL, 0, 0, ioBuffer, 2, 0, out outLen); if (!response) { return(false); } TmpDevVersion = ioBuffer[1] << 8 | ioBuffer[0]; //This should be >0 if Accessory mode supported. if (TmpDevVersion == 0) { return(false); } Thread.Sleep(1000); // Allow space after In cmd otherwise sometimes hangs on the next transfer. ioBuffer = Encoding.UTF8.GetBytes(Settings.AppManufacturer); // Strings must be in UTF8 encoding. response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_MANUFACTURER, ioBuffer, ioBuffer.Length); if (!response) { return(false); } ioBuffer = Encoding.UTF8.GetBytes(Settings.AppModelName); response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_MODEL, ioBuffer, ioBuffer.Length); if (!response) { return(false); } ioBuffer = Encoding.UTF8.GetBytes(Settings.AppDescription); response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_DESCRIPTION, ioBuffer, ioBuffer.Length); if (!response) { return(false); } ioBuffer = Encoding.UTF8.GetBytes(Settings.AppVersion); response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_VERSION, ioBuffer, ioBuffer.Length); if (!response) { return(false); } ioBuffer = Encoding.UTF8.GetBytes(Settings.AppURI); response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_URI, ioBuffer, ioBuffer.Length); if (!response) { return(false); } ioBuffer = Encoding.UTF8.GetBytes(serialNumber); response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_SEND_STRING, 0, ACCESSORY_STRING_SERIAL, ioBuffer, ioBuffer.Length); if (!response) { return(false); } // Control request for starting device in accessory mode. // The host sends this after setting all its strings to the device. response = u.ControlTransfer(UsbRqstOutVendor, ACCESSORY_START, 0, 0); Thread.Sleep(2000); // Allow time to switch. return(response); }