Beispiel #1
0
        /// <summary>
        /// Stops all device watchers.
        /// </summary>
        private void StopDeviceWatchersInternal()
        {
            if (_deviceWatcher.Status == DeviceWatcherStatus.Started)
            {
                _deviceWatcher.Stop();

                while (_deviceWatcher.Status != DeviceWatcherStatus.Stopped)
                {
                    Thread.Sleep(100);
                }
            }

            // Clear the list of devices so we don't have potentially disconnected devices around
            ClearDeviceEntries();

            // also clear nanoFramework devices list
            var devicesToRemove = _networkNanoFrameworkDevices.Select(nanoDevice => nanoDevice.DeviceId).ToList();

            foreach (var deviceId in devicesToRemove)
            {
                // get device...
                var device = FindNanoFrameworkDevice(deviceId);

                // ... and remove it from collection
                NanoFrameworkDevices.Remove(device);

                device?.DebugEngine?.StopProcessing();
                device?.DebugEngine?.Stop(true);
            }

            _watchersStarted = false;
        }
Beispiel #2
0
        /// <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
                }
            }
        }
Beispiel #3
0
        private NanoDeviceBase FindNanoFrameworkDevice(string deviceId)
        {
            if (deviceId != null)
            {
                // SerialMatch.Device.DeviceInformation
                return(NanoFrameworkDevices.FirstOrDefault(d => ((d as NanoDevice <NanoSerialDevice>).DeviceId) == deviceId));
            }

            return(null);
        }
Beispiel #4
0
        private NanoDeviceBase FindNanoFrameworkDevice(string deviceId)
        {
            if (deviceId != null)
            {
                // usbMatch.Device.DeviceInformation
                return(NanoFrameworkDevices.FirstOrDefault(d => ((d as NanoDevice <NanoUsbDevice>).Device.DeviceInformation as UsbDeviceInformation).DeviceInformation.Id == deviceId));
            }

            return(null);
        }
Beispiel #5
0
        private void OnDeviceEnumerationComplete(DeviceWatcher sender, object args)
        {
            // add another device watcher completed
            deviceWatchersCompletedCount++;

            if (deviceWatchersCompletedCount == mapDeviceWatchersToDeviceSelector.Count)
            {
                // 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 NanoFrameworkDevices)
                {
                    // connect to the device (as Task to get rid of the await)
                    var connectTask = ConnectDeviceAsync(device);

                    if (connectTask.Result)
                    {
                        var checkValidNFDeviceTask = CheckValidNanoFrameworkSerialDeviceAsync();

                        if (!checkValidNFDeviceTask.Result)
                        {
                            // mark this device for removal
                            devicesToRemove.Add(device);
                            device.StartCountdownForDispose();
                        }
                        else
                        {
                            Debug.WriteLine($"New Serial device: {device.Description} {(((NanoDevice<NanoSerialDevice>)device).Device.DeviceInformation.DeviceInformation.Id)}");
                        }

                        // done here, disconnect from the device now
                        ((NanoDevice <NanoSerialDevice>)device).Disconnect();
                    }
                    else
                    {
                        // couldn't open device
                        // mark this device for removal
                        devicesToRemove.Add(device);
                    }
                }

                // remove device form nanoFramework device collection (force Linq to execute with call to Count())
                devicesToRemove.Select(d => NanoFrameworkDevices.Remove(d)).Count();

                // all watchers have completed enumeration
                isAllDevicesEnumerated = true;

                Debug.WriteLine($"Serial device enumeration completed. Found {NanoFrameworkDevices.Count} devices");

                // fire event that Serial enumeration is complete
                OnDeviceEnumerationCompleted();
            }
        }
Beispiel #6
0
        public override void DisposeDevice(string instanceId)
        {
            var deviceToDispose = NanoFrameworkDevices.FirstOrDefault(nanoDevice => ((NanoDevice <NanoSerialDevice>)nanoDevice).DeviceId == instanceId);

            if (deviceToDispose != null)
            {
                Task.Run(() =>
                {
                    ((NanoDevice <NanoSerialDevice>)deviceToDispose).Dispose();
                });
            }
        }
Beispiel #7
0
        private void RemoveDeviceFromList(string deviceId)
        {
            // Removes the device entry from the internal list; therefore the UI
            var deviceEntry = FindDevice(deviceId);

            NanoDevicesEventSource.Log.DeviceDeparture(deviceId);

            UsbDevices.Remove(deviceEntry);
            // get device
            var device = FindNanoFrameworkDevice(deviceId);

            // yes, remove it from collection
            NanoFrameworkDevices.Remove(device);
            device = null;
        }
Beispiel #8
0
        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;
            }
        }
Beispiel #9
0
        private void RemoveDeviceFromList(NetworkDeviceInformation networkDevice)
        {
            // Removes the device entry from the internal list; therefore the UI
            var deviceEntry = FindDevice(networkDevice.DeviceId);

            OnLogMessageAvailable(NanoDevicesEventSource.Log.DeviceDeparture(networkDevice.DeviceId));

            _networkDevices.Remove(deviceEntry);

            // get device...
            var device = FindNanoFrameworkDevice(networkDevice.DeviceId);

            // ... and remove it from collection
            NanoFrameworkDevices.Remove(device);

            device?.DebugEngine?.StopProcessing();
            device?.DebugEngine?.Dispose();
        }
Beispiel #10
0
        private NanoDeviceBase FindNanoFrameworkDevice(string deviceId)
        {
            if (deviceId != null)
            {
                // SerialMatch.Device.DeviceInformation
                var device = NanoFrameworkDevices.FirstOrDefault(d => ((d as NanoDevice <NanoSerialDevice>).Device.DeviceInformation as SerialDeviceInformation).DeviceInformation.Id == deviceId);

                if (device == null)
                {
                    // try now in tentative list
                    return(_tentativeNanoFrameworkDevices.FirstOrDefault(d => ((d as NanoDevice <NanoSerialDevice>).Device.DeviceInformation as SerialDeviceInformation).DeviceInformation.Id == deviceId));
                }
                else
                {
                    return(device);
                }
            }

            return(null);
        }
Beispiel #11
0
        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();
            }
        }
Beispiel #12
0
        private void RemoveDeviceFromList(string deviceId)
        {
            // Removes the device entry from the internal list; therefore the UI
            var deviceEntry = FindDevice(deviceId);

            Debug.WriteLine("USB device removed: " + deviceId);

            UsbDevices.Remove(deviceEntry);

            // start thread to dispose and remove device from collection if it doesn't enumerate again in 2 seconds
            Task.Factory.StartNew(() =>
            {
                // get device
                var device = FindNanoFrameworkDevice(deviceId);

                if (device != null)
                {
                    // set device to dispose if it doesn't come back in 2 seconds
                    device.StartCountdownForDispose();

                    // hold here for the same time as the default timer of the dispose timer
                    new ManualResetEvent(false).WaitOne(TimeSpan.FromSeconds(2.5));

                    // check is object was disposed
                    if ((device as NanoDevice <NanoUsbDevice>).KillFlag)
                    {
                        // yes, remove it from collection
                        NanoFrameworkDevices.Remove(device);

                        Debug.WriteLine("Removing device " + device.Description);

                        device = null;
                    }
                }
            });
        }
Beispiel #13
0
        /// <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>));
                }
            }
        }
Beispiel #14
0
        /// <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();
                }
            }
        }
Beispiel #15
0
        /// <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();
            }
        }
Beispiel #16
0
        /// <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);
                    }
                }
            }
        }
Beispiel #17
0
        /// <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();
                    }
                }
            }
        }
Beispiel #18
0
        /// <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();
                }
            }
        }