/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceSelector">The AQS used to find this device</param> private async void AddDeviceToList(DeviceInformation deviceInformation, String deviceSelector) { // search the device list for a device with a matching interface ID var usbMatch = FindDevice(deviceInformation.Id); OnLogMessageAvailable(NanoDevicesEventSource.Log.CandidateDevice(deviceInformation.Id)); // Add the device if it's new if (usbMatch == null) { UsbDevices.Add(new UsbDeviceInformation(deviceInformation, deviceSelector)); // search the NanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceInformation.Id); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device interface, and queue up the query of its // device information var newNanoFrameworkDevice = new NanoDevice <NanoUsbDevice>(); //newMFDevice.DeviceInformation = new UsbDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Device.DeviceInformation = new UsbDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Parent = this; newNanoFrameworkDevice.Transport = TransportType.Usb; // Add the new element to the end of the list of devices NanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); // now fill in the description // try opening the device to read the descriptor if (await ConnectUsbDeviceAsync(newNanoFrameworkDevice.Device.DeviceInformation)) { // the device description format is kept to maintain backwards compatibility newNanoFrameworkDevice.Description = EventHandlerForUsbDevice.Current.DeviceInformation.Name + "_" + await GetDeviceDescriptor(5); NanoDevicesEventSource.Log.ValidDevice(newNanoFrameworkDevice.Description + " @ " + newNanoFrameworkDevice.Device.DeviceInformation.DeviceSelector); // done here, close device EventHandlerForUsbDevice.Current.CloseDevice(); } else { // couldn't open device, better remove it from the lists NanoFrameworkDevices.Remove(newNanoFrameworkDevice as NanoDeviceBase); UsbDevices.Remove(newNanoFrameworkDevice.Device.DeviceInformation); NanoDevicesEventSource.Log.QuitDevice(deviceInformation.Id); // can't do anything with this one, better dispose it newNanoFrameworkDevice.Dispose(); } } else { // this NanoFramework device is already on the list } } }
private void OnPortNanoFrameworkDevicesOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { switch (e.Action) { case NotifyCollectionChangedAction.Reset: NanoFrameworkDevices.Clear(); break; case NotifyCollectionChangedAction.Add: e.NewItems.Cast <NanoDeviceBase>().ToList().ForEach(d => NanoFrameworkDevices.Add(d)); break; case NotifyCollectionChangedAction.Remove: e.OldItems.Cast <NanoDeviceBase>().ToList().ForEach(d => NanoFrameworkDevices.Remove(d)); break; } }
private void OnDeviceEnumerationComplete(DeviceWatcher sender, object args) { // add another device watcher completed _deviceWatchersCompletedCount++; if (_deviceWatchersCompletedCount == _mapDeviceWatchersToDeviceSelector.Count) { Task.Factory.StartNew(async() => { // prepare a list of devices that are to be removed if they are deemed as not valid nanoFramework devices var devicesToRemove = new List <NanoDeviceBase>(); foreach (NanoDeviceBase device in _tentativeNanoFrameworkDevices) { var nFDeviceIsValid = await CheckValidNanoFrameworkSerialDeviceAsync(((NanoDevice <NanoSerialDevice>)device).Device.DeviceInformation).ConfigureAwait(true); if (nFDeviceIsValid) { OnLogMessageAvailable(NanoDevicesEventSource.Log.ValidDevice($"{device.Description} {(((NanoDevice<NanoSerialDevice>)device).Device.DeviceInformation.DeviceInformation.Id)}")); NanoFrameworkDevices.Add(device); } else { OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(((NanoDevice <NanoSerialDevice>)device).Device.DeviceInformation.DeviceInformation.Id)); } } // all watchers have completed enumeration IsDevicesEnumerationComplete = true; // clean list of tentative nanoFramework Devices _tentativeNanoFrameworkDevices.Clear(); OnLogMessageAvailable(NanoDevicesEventSource.Log.SerialDeviceEnumerationCompleted(NanoFrameworkDevices.Count)); // fire event that Serial enumeration is complete OnDeviceEnumerationCompleted(); }).FireAndForget(); } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceSelector">The AQS used to find this device</param> private async void AddDeviceToList(DeviceInformation deviceInformation, String deviceSelector) { // search the device list for a device with a matching interface ID var usbMatch = FindDevice(deviceInformation.Id); Debug.WriteLine("New USB device: " + deviceInformation.Id); // Add the device if it's new if (usbMatch == null) { UsbDevices.Add(new UsbDeviceInformation(deviceInformation, deviceSelector)); // search the NanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceInformation.Id); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device interface, and queue up the query of its // device information var newNanoFrameworkDevice = new NanoDevice <NanoUsbDevice>(); //newMFDevice.DeviceInformation = new UsbDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Device.DeviceInformation = new UsbDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Parent = this; newNanoFrameworkDevice.DebugEngine = new Engine(this, newNanoFrameworkDevice); newNanoFrameworkDevice.Transport = TransportType.Usb; // Add the new element to the end of the list of devices NanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); // now fill in the description // try opening the device to read the descriptor if (await ConnectUsbDeviceAsync(newNanoFrameworkDevice.Device.DeviceInformation).ConfigureAwait(false)) { // the device description format is kept to maintain backwards compatibility newNanoFrameworkDevice.Description = EventHandlerForUsbDevice.Current.DeviceInformation.Name + "_" + await GetDeviceDescriptor(5).ConfigureAwait(false); Debug.WriteLine("Add new nanoFramework device to list: " + newNanoFrameworkDevice.Description + " @ " + newNanoFrameworkDevice.Device.DeviceInformation.DeviceSelector); // done here, close device EventHandlerForUsbDevice.Current.CloseDevice(); } else { // couldn't open device, better remove it from the lists NanoFrameworkDevices.Remove(newNanoFrameworkDevice as NanoDeviceBase); UsbDevices.Remove(newNanoFrameworkDevice.Device.DeviceInformation); } } else { // this NanoFramework device is already on the list // stop the dispose countdown! nanoFrameworkDeviceMatch.StopCountdownForDispose(); // set port parent //(mfDeviceMatch as MFDevice<MFUsbDevice>).Device.Parent = this; //// instantiate a debug engine //(mfDeviceMatch as MFDevice<MFUsbDevice>).Device.DebugEngine = new Engine(this, (mfDeviceMatch as MFDevice<MFUsbDevice>)); } } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceSelector">The AQS used to find this device</param> private async void AddDeviceToList(DeviceInformation deviceInformation, String deviceSelector) { // search the device list for a device with a matching interface ID var serialMatch = FindDevice(deviceInformation.Id); // Add the device if it's new if (serialMatch == null) { SerialDevices.Add(new SerialDeviceInformation(deviceInformation, deviceSelector)); // search the NanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceInformation.Id); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device interface, and queue up the query of its // device information var newNanoFrameworkDevice = new NanoDevice <NanoSerialDevice>(); newNanoFrameworkDevice.Device.DeviceInformation = new SerialDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Parent = this; newNanoFrameworkDevice.DebugEngine = new Engine(this, newNanoFrameworkDevice); newNanoFrameworkDevice.Transport = TransportType.Serial; // Add the new element to the end of the list of devices NanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); // perform check for valid nanoFramework device is this is not the initial enumeration if (isAllDevicesEnumerated) { // try opening the device to check for a valid nanoFramework device if (await ConnectSerialDeviceAsync(newNanoFrameworkDevice.Device.DeviceInformation).ConfigureAwait(false)) { Debug.WriteLine("New Serial device: " + deviceInformation.Id); var name = EventHandlerForSerialDevice.Current.DeviceInformation?.Properties["System.ItemNameDisplay"] as string; // acceptable names if (name == "STM32 STLink") { // now fill in the description newNanoFrameworkDevice.Description = name + " @ " + EventHandlerForSerialDevice.Current.Device.PortName; Debug.WriteLine("Add new nanoFramework device to list: " + newNanoFrameworkDevice.Description + " @ " + newNanoFrameworkDevice.Device.DeviceInformation.DeviceSelector); } // done here, close the device EventHandlerForSerialDevice.Current.CloseDevice(); return; } // couldn't open device better remove it from the collection right away NanoFrameworkDevices.Remove(newNanoFrameworkDevice as NanoDeviceBase); } } else { // this NanoFramework device is already on the list // stop the dispose countdown! nanoFrameworkDeviceMatch.StopCountdownForDispose(); } } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> private void AddDeviceToListAsync(NetworkDeviceInformation networkDevice) { // search the device list for a device with a matching interface ID var networkMatch = FindDevice(networkDevice.DeviceId); // Add the device if it's new if (networkMatch != null) { return; } OnLogMessageAvailable(NanoDevicesEventSource.Log.CandidateDevice(networkDevice.DeviceId)); // search the nanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(networkDevice.DeviceId); if (nanoFrameworkDeviceMatch != null) { return; } // Create a new element for this device and... var newNanoFrameworkDevice = new NanoDevice <NanoNetworkDevice>(); newNanoFrameworkDevice.DeviceId = networkDevice.DeviceId; newNanoFrameworkDevice.ConnectionPort = new PortTcpIp(this, newNanoFrameworkDevice, networkDevice); newNanoFrameworkDevice.Transport = TransportType.TcpIp; var connectResult = newNanoFrameworkDevice.ConnectionPort.ConnectDevice(); if (connectResult == ConnectPortResult.Unauthorized) { OnLogMessageAvailable( NanoDevicesEventSource.Log.UnauthorizedAccessToDevice(networkDevice.DeviceId)); } else if (connectResult == ConnectPortResult.Connected) { if (CheckValidNanoFrameworkNetworkDevice(newNanoFrameworkDevice)) { //add device to the collection NanoFrameworkDevices.Add(newNanoFrameworkDevice); _networkDevices.Add(networkDevice); OnLogMessageAvailable( NanoDevicesEventSource.Log.ValidDevice($"{newNanoFrameworkDevice.Description}")); } else { // disconnect newNanoFrameworkDevice.Disconnect(); } } else { OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(networkDevice.DeviceId)); } // subtract devices count _newDevicesCount--; // check if we are done processing arriving devices if (_newDevicesCount == 0) { ProcessDeviceEnumerationComplete(); } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceId">The AQS used to find this device</param> private void AddDeviceToListAsync(String deviceId) { // search the device list for a device with a matching interface ID var serialMatch = FindDevice(deviceId); // Add the device if it's new if (serialMatch == null) { var serialDevice = new SerialDeviceInformation(deviceId); OnLogMessageAvailable(NanoDevicesEventSource.Log.CandidateDevice(deviceId)); // search the nanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceId); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device and... var newNanoFrameworkDevice = new NanoDevice <NanoSerialDevice>(); newNanoFrameworkDevice.DeviceId = deviceId; newNanoFrameworkDevice.ConnectionPort = new PortSerial(this, newNanoFrameworkDevice); newNanoFrameworkDevice.Transport = TransportType.Serial; var connectResult = newNanoFrameworkDevice.ConnectionPort.ConnectDevice(); if (connectResult == ConnectPortResult.Unauthorized) { OnLogMessageAvailable(NanoDevicesEventSource.Log.UnauthorizedAccessToDevice(deviceId)); } else if (connectResult == ConnectPortResult.Connected) { if (CheckValidNanoFrameworkSerialDevice(newNanoFrameworkDevice)) { //add device to the collection NanoFrameworkDevices.Add(newNanoFrameworkDevice); _serialDevices.Add(serialDevice); OnLogMessageAvailable(NanoDevicesEventSource.Log.ValidDevice($"{newNanoFrameworkDevice.Description}")); } else { // disconnect newNanoFrameworkDevice.Disconnect(); // devices powered by the USB cable and that feature a serial converter (like an FTDI chip) // are still booting when the USB enumeration event raises // so need to give them enough time for the boot sequence to complete before trying to communicate with them // Failing to connect to debugger engine on first attempt occurs frequently on dual USB devices like ESP32 WROVER KIT. // Seems to be something related with both devices using the same USB endpoint // Another reason is that an ESP32 takes around 3 seconds to complete the boot sequence and launch the CLR. // Until then the device will look non responsive or invalid to the detection mechanism that we're using. // A nice workaround for this seems to be adding an extra random wait so the comms are not simultaneous. int delay; lock (_delay) { delay = _delay.Next(200, 600); } Thread.Sleep(BootTime + delay); OnLogMessageAvailable(NanoDevicesEventSource.Log.CheckingValidDevice($" {newNanoFrameworkDevice.DeviceId} *** 2nd attempt ***")); connectResult = newNanoFrameworkDevice.ConnectionPort.ConnectDevice(); if (connectResult == ConnectPortResult.Unauthorized) { OnLogMessageAvailable(NanoDevicesEventSource.Log.UnauthorizedAccessToDevice(deviceId)); } else if (connectResult == ConnectPortResult.Connected) { if (CheckValidNanoFrameworkSerialDevice(newNanoFrameworkDevice, true)) { //add device to the collection NanoFrameworkDevices.Add(newNanoFrameworkDevice); _serialDevices.Add(serialDevice); OnLogMessageAvailable(NanoDevicesEventSource.Log.ValidDevice($"{newNanoFrameworkDevice.Description}")); } else { OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(deviceId)); } } else { OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(deviceId)); } } } else { OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(deviceId)); } // subtract devices count lock (_newDevicesCountLock) { _newDevicesCount--; } // check if we are done processing arriving devices if (_newDevicesCount == 0) { ProcessDeviceEnumerationComplete(); } } } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceSelector">The AQS used to find this device</param> private async void AddDeviceToList(DeviceInformation deviceInformation, String deviceSelector) { // search the device list for a device with a matching interface ID var serialMatch = FindDevice(deviceInformation.Id); // Add the device if it's new if (serialMatch == null) { SerialDevices.Add(new SerialDeviceInformation(deviceInformation, deviceSelector)); // search the NanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceInformation.Id); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device interface, and queue up the query of its // device information var newNanoFrameworkDevice = new NanoDevice <NanoSerialDevice>(); newNanoFrameworkDevice.Device.DeviceInformation = new SerialDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Parent = this; newNanoFrameworkDevice.DebugEngine = new Engine(this, newNanoFrameworkDevice); newNanoFrameworkDevice.Transport = TransportType.Serial; // Add the new element to the end of the list of devices NanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); // perform check for valid nanoFramework device is this is not the initial enumeration if (isAllDevicesEnumerated) { // try opening the device to check for a valid nanoFramework device if (await ConnectSerialDeviceAsync(newNanoFrameworkDevice.Device.DeviceInformation)) { Debug.WriteLine("New Serial device: " + deviceInformation.Id); if (await CheckValidNanoFrameworkSerialDeviceAsync()) { // done here, close the device EventHandlerForSerialDevice.Current.CloseDevice(); // remove it from collection... NanoFrameworkDevices.Remove(newNanoFrameworkDevice as NanoDeviceBase); //... and add it again, otherwise the bindings might fail NanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); Debug.WriteLine("Add new nanoFramework device to list: " + newNanoFrameworkDevice.Description + " @ " + newNanoFrameworkDevice.Device.DeviceInformation.DeviceSelector); return; } } Debug.WriteLine($"Removing { deviceInformation.Id } from collection..."); // couldn't open device better remove it from the collection right away NanoFrameworkDevices.Remove(newNanoFrameworkDevice as NanoDeviceBase); // can't do anything with this one, better dispose it newNanoFrameworkDevice.Dispose(); } } else { // this NanoFramework device is already on the list // stop the dispose countdown! nanoFrameworkDeviceMatch.StopCountdownForDispose(); } } }
/// <summary> /// Creates a DeviceListEntry for a device and adds it to the list of devices /// </summary> /// <param name="deviceInformation">DeviceInformation on the device to be added to the list</param> /// <param name="deviceSelector">The AQS used to find this device</param> private async void AddDeviceToList(DeviceInformation deviceInformation, String deviceSelector) { // device black listed // discard known system and unusable devices // if ( deviceInformation.Id.StartsWith(@"\\?\ACPI") || // reported in https://github.com/nanoframework/Home/issues/332 // COM ports from Broadcom 20702 Bluetooth adapter deviceInformation.Id.Contains(@"VID_0A5C+PID_21E1") || // reported in https://nanoframework.slack.com/archives/C4MGGBH1P/p1531660736000055?thread_ts=1531659631.000021&cid=C4MGGBH1P // COM ports from Broadcom 20702 Bluetooth adapter deviceInformation.Id.Contains(@"VID&00010057_PID&0023") ) { OnLogMessageAvailable(NanoDevicesEventSource.Log.DroppingBlackListedDevice(deviceInformation.Id)); // don't even bother with these return; } OnLogMessageAvailable(NanoDevicesEventSource.Log.DeviceArrival(deviceInformation.Id)); // search the device list for a device with a matching interface ID var serialMatch = FindDevice(deviceInformation.Id); // Add the device if it's new if (serialMatch == null) { var serialDevice = new SerialDeviceInformation(deviceInformation, deviceSelector); _serialDevices.Add(serialDevice); OnLogMessageAvailable(NanoDevicesEventSource.Log.CandidateDevice(deviceInformation.Id)); // search the nanoFramework device list for a device with a matching interface ID var nanoFrameworkDeviceMatch = FindNanoFrameworkDevice(deviceInformation.Id); if (nanoFrameworkDeviceMatch == null) { // Create a new element for this device and... var newNanoFrameworkDevice = new NanoDevice <NanoSerialDevice>(); newNanoFrameworkDevice.Device.DeviceInformation = new SerialDeviceInformation(deviceInformation, deviceSelector); newNanoFrameworkDevice.Parent = this; newNanoFrameworkDevice.Transport = TransportType.Serial; // ... add it to the collection of tentative devices _tentativeNanoFrameworkDevices.Add(newNanoFrameworkDevice as NanoDeviceBase); // perform check for valid nanoFramework device is this is not the initial enumeration if (IsDevicesEnumerationComplete) { if (await CheckValidNanoFrameworkSerialDeviceAsync(newNanoFrameworkDevice.Device.DeviceInformation)) { // the device info was updated above, need to get it from the tentative devices collection //add device to the collection NanoFrameworkDevices.Add(FindNanoFrameworkDevice(newNanoFrameworkDevice.Device.DeviceInformation.DeviceInformation.Id)); OnLogMessageAvailable(NanoDevicesEventSource.Log.ValidDevice($"{newNanoFrameworkDevice.Description} {newNanoFrameworkDevice.Device.DeviceInformation.DeviceInformation.Id}")); // done here, clear tentative list _tentativeNanoFrameworkDevices.Clear(); // done here return; } // clear tentative list _tentativeNanoFrameworkDevices.Clear(); OnLogMessageAvailable(NanoDevicesEventSource.Log.QuitDevice(deviceInformation.Id)); _serialDevices.Remove(serialDevice); } } } }