Exemplo n.º 1
0
        private void TryGetMonitorTargetInfo(NanoDevice <NanoNetworkDevice> device)
        {
            // set retry policies
            var targetInfoPolicy = Policy.Handle <NullReferenceException>()
                                   .OrResult <TargetInfo>(r => r.TargetName == null)
                                   .WaitAndRetry(2,
                                                 retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));
            var targetReleaseInfoPolicy = Policy.Handle <NullReferenceException>()
                                          .OrResult <ReleaseInfo>(r => r == null)
                                          .WaitAndRetry(2,
                                                        retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));

            // try first with new command
            var targetInfo =
                targetInfoPolicy.Execute(() => device.DebugEngine.GetMonitorTargetInfo());

            if (targetInfo != null)
            {
                device.TargetName = targetInfo.TargetName;
                device.Platform   = targetInfo.PlatformName;
            }
            else
            {
                // try again with deprecated command
                var deviceInfo = targetReleaseInfoPolicy.Execute(() =>
                                                                 device.DebugEngine.GetMonitorOemInfo());

                if (deviceInfo != null)
                {
                    device.TargetName = deviceInfo.TargetName;
                    device.Platform   = deviceInfo.PlatformName;
                }
            }
        }
Exemplo n.º 2
0
        private static void TryGetTargetInfo(NanoDevice <NanoNetworkDevice> device)
        {
            // set retry policies
            var targetInfoPropertiesPolicy = Policy.Handle <NullReferenceException>()
                                             .OrResult <CLRCapabilities.TargetInfoProperties>(r => r.TargetName == null)
                                             .WaitAndRetry(2,
                                                           retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));

            var deviceInfo = targetInfoPropertiesPolicy.Execute(() =>
            {
                if (device.DebugEngine != null)
                {
                    return(device.DebugEngine.GetTargetInfo());
                }
                else
                {
                    return(new CLRCapabilities.TargetInfoProperties());
                }
            });

            if (!string.IsNullOrEmpty(deviceInfo.TargetName))
            {
                device.TargetName = deviceInfo.TargetName;
                device.Platform   = deviceInfo.Platform;
            }
        }
Exemplo n.º 3
0
        private bool ValidateDevice(NanoDevice <NanoNetworkDevice> device, string deviceId)
        {
            bool validDevice = false;

            if (device.Device != null)
            {
                // check if this device is on cache
                var isKnownDevice = _devicesCache.TryGetValue(deviceId, out var cachedDevice);

                OnLogMessageAvailable(NanoDevicesEventSource.Log.CheckingValidDevice($" {deviceId}"));

                if (device.DebugEngine == null)
                {
                    device.CreateDebugEngine();
                }

                // try to "just" connect to the device meaning...
                // ... don't request capabilities or force anything except the absolute minimum required, plus...
                // ... it's OK to use a very short timeout as we'll be exchanging really short packets with the device
                if (!device.DebugEngine.Connect(NanoNetworkDevice.SafeDefaultTimeout))
                {
                    return(false);
                }

                if (isKnownDevice)
                {
                    // skip getting properties from device
                    device.TargetName = cachedDevice.TargetName;
                    device.Platform   = cachedDevice.PlatformName;

                    return(true);
                }

                if (device.DebugEngine.IsConnectedTonanoBooter)
                {
                    TryGetMonitorTargetInfo(device);
                }
                else
                {
                    TryGetTargetInfo(device);
                }

                if (string.IsNullOrEmpty(device.TargetName) ||
                    string.IsNullOrEmpty(device.Platform))
                {
                    OnLogMessageAvailable(
                        NanoDevicesEventSource.Log.CriticalError(
                            $"ERROR: {device.DeviceId} failed to get target information"));

                    validDevice = false;
                }
                else
                {
                    validDevice = true;
                }
            }

            return(validDevice);
        }
Exemplo n.º 4
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
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Creates an Serial debug client
        /// </summary>
        /// <param name="deviceInfo">Device information of the device to be opened</param>
        /// <param name="deviceSelector">The AQS used to find this device</param>
        public PortSerial(PortSerialManager portManager, NanoDevice <NanoSerialDevice> serialDevice)
        {
            _portManager = portManager ?? throw new ArgumentNullException(nameof(portManager));
            NanoDevice   = serialDevice ?? throw new ArgumentNullException(nameof(serialDevice));

            // init default baud rate with 1st value
            BaudRate = ValidBaudRates[0];
        }
Exemplo n.º 6
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>));
                }
            }
        }
Exemplo n.º 7
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();
                }
            }
        }
Exemplo n.º 8
0
        private bool CheckValidNanoFrameworkNetworkDevice(
            NanoDevice <NanoNetworkDevice> device)
        {
            bool validDevice = false;

            // store device ID
            string deviceId = device.DeviceId;

            try
            {
                // sanity check for invalid or null device
                validDevice = ValidateDevice(device, deviceId);

                if (validDevice)
                {
                    // there should be a valid nanoFramework device at the other end

                    // store connection ID
                    device.ConnectionId = deviceId;

                    // store device in cache
                    var cachedDevice = new CachedDeviceInfo(
                        device.TargetName,
                        device.Platform);

                    _devicesCache.TryAdd(
                        deviceId,
                        cachedDevice);

                    // disconnect device
                    device.DebugEngine.Stop(true);
                }
                else
                {
                    // remove from cache
                    _devicesCache.TryRemove(deviceId, out var dummy);

                    device.DebugEngine?.Stop();
                    device.DebugEngine?.Dispose();
                    device.DebugEngine = null;
                    device.Device?.Dispose();
                }
            }
            catch (Exception /* ex */
                   )         // we could eat simple programming errors here - like a bad cast or other problem when changing code
            {
                // "catch all" required because the device open & check calls might fail for a number of reasons
                // if there is a deviceID, remove it from cache, just in case
                if (deviceId != null)
                {
                    _devicesCache.TryRemove(deviceId, out var dummy);
                }

                try
                {
                    device.DebugEngine?.Stop();
                    device.DebugEngine?.Dispose();
                    device.DebugEngine = null;
                    device.Device?.Dispose();
                }
                catch
                {
                    // catch all trying to get rid of the device
                }
            }

            return(validDevice);
        }
Exemplo n.º 9
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();
            }
        }
Exemplo n.º 10
0
 public PortTcpIp(PortTcpIpManager portManager, NanoDevice <NanoNetworkDevice> networkDevice, NetworkDeviceInformation deviceInformation)
 {
     _portManager = portManager ?? throw new ArgumentNullException(nameof(portManager));
     NanoDevice   = networkDevice ?? throw new ArgumentNullException(nameof(networkDevice));
     NanoDevice.Device.NetworkDeviceInformation = deviceInformation;
 }
Exemplo n.º 11
0
        private bool CheckValidNanoFrameworkSerialDevice(
            NanoDevice <NanoSerialDevice> device,
            bool longDelay = false)
        {
            bool validDevice   = false;
            bool isKnownDevice = false;

            // store device ID
            string deviceId = device.DeviceId;

            try
            {
                // sanity check for invalid or null device base
                if ((SerialPort)device.DeviceBase != null)
                {
                    // check if this device is on cache
                    isKnownDevice = _devicesCache.TryGetValue(deviceId, out var cachedDevice);

                    // need to go through all the valid baud rates: 921600, 460800 and 115200.
                    foreach (int baudRate in PortSerial.ValidBaudRates)
                    {
                        if (device.DebugEngine == null)
                        {
                            device.CreateDebugEngine();
                        }

                        if (isKnownDevice)
                        {
                            // OK to go with stored cache
                            ((SerialPort)device.DeviceBase).BaudRate = cachedDevice.BaudRate;
                        }
                        else
                        {
                            ((SerialPort)device.DeviceBase).BaudRate = baudRate;
                        }

                        // better flush the UART FIFOs
                        ((SerialPort)device.DeviceBase).DiscardInBuffer();
                        ((SerialPort)device.DeviceBase).DiscardOutBuffer();

                        OnLogMessageAvailable(NanoDevicesEventSource.Log.CheckingValidDevice($" {deviceId} @ { baudRate }"));

                        // try to "just" connect to the device meaning...
                        // ... don't request capabilities or force anything except the absolute minimum required, plus...
                        // ... it's OK to use a very short timeout as we'll be exchanging really short packets with the device
                        if (device.DebugEngine.Connect(
                                longDelay ? 2 * NanoSerialDevice.SafeDefaultTimeout : NanoSerialDevice.SafeDefaultTimeout))
                        {
                            if (isKnownDevice)
                            {
                                // skip getting properties from device
                                device.TargetName = cachedDevice.TargetName;
                                device.Platform   = cachedDevice.PlatformName;

                                validDevice = true;
                                break;
                            }

                            // set retry policies
                            var targetInfoPropertiesPolicy = Policy.Handle <NullReferenceException>().OrResult <CLRCapabilities.TargetInfoProperties>(r => r.TargetName == null)
                                                             .WaitAndRetry(2, retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));
                            var targetInfoPolicy = Policy.Handle <NullReferenceException>().OrResult <TargetInfo>(r => r.TargetName == null)
                                                   .WaitAndRetry(2, retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));
                            var targetReleaseInfoPolicy = Policy.Handle <NullReferenceException>().OrResult <ReleaseInfo>(r => r == null)
                                                          .WaitAndRetry(2, retryAttempt => TimeSpan.FromMilliseconds((retryAttempt + 1) * 200));

                            if (device.DebugEngine.IsConnectedTonanoBooter)
                            {
                                // try first with new command
                                var targetInfo = targetInfoPolicy.Execute(() => device.DebugEngine.GetMonitorTargetInfo());

                                if (targetInfo != null)
                                {
                                    device.TargetName = targetInfo.TargetName;
                                    device.Platform   = targetInfo.PlatformName;
                                }
                                else
                                {
                                    // try again with deprecated command
                                    var deviceInfo = targetReleaseInfoPolicy.Execute(() => device.DebugEngine.GetMonitorOemInfo());

                                    if (deviceInfo != null)
                                    {
                                        device.TargetName = deviceInfo.TargetName;
                                        device.Platform   = deviceInfo.PlatformName;
                                    }
                                }
                            }
                            else
                            {
                                var deviceInfo = targetInfoPropertiesPolicy.Execute(() =>
                                {
                                    if (device.DebugEngine != null)
                                    {
                                        return(device.DebugEngine.GetTargetInfo());
                                    }
                                    else
                                    {
                                        return(new CLRCapabilities.TargetInfoProperties());
                                    }
                                });

                                if (!string.IsNullOrEmpty(deviceInfo.TargetName))
                                {
                                    device.TargetName = deviceInfo.TargetName;
                                    device.Platform   = deviceInfo.Platform;
                                }
                            }

                            if (string.IsNullOrEmpty(device.TargetName) ||
                                string.IsNullOrEmpty(device.Platform))
                            {
                                OnLogMessageAvailable(NanoDevicesEventSource.Log.CriticalError($"ERROR: {device.DeviceId} failed to get target information"));

                                validDevice = false;
                                break;
                            }
                            else
                            {
                                validDevice = true;
                                break;
                            }
                        }
                    }
                }

                if (validDevice)
                {
                    // there should be a valid nanoFramework device at the other end

                    device.SerialNumber = GetSerialNumber(deviceId);

                    // store valid baud rate from device detection
                    ((PortSerial)device.ConnectionPort).BaudRate = ((SerialPort)device.DeviceBase).BaudRate;

                    // store connection ID
                    device.ConnectionId = deviceId;

                    // store device in cache
                    var cachedDevice = new CachedDeviceInfo(
                        device.TargetName,
                        device.Platform,
                        ((SerialPort)device.DeviceBase).BaudRate);

                    _devicesCache.TryAdd(
                        deviceId,
                        cachedDevice);

                    // disconnect device
                    device.DebugEngine.Stop(true);
                }
                else
                {
                    // remove from cache
                    _devicesCache.TryRemove(deviceId, out var dummy);

                    device.DebugEngine?.Stop();
                    device.DebugEngine?.Dispose();
                    device.DebugEngine = null;

                    if (device.DeviceBase != null)
                    {
                        ((SerialPort)device.DeviceBase).Close();
                        ((SerialPort)device.DeviceBase).Dispose();

                        device.DeviceBase = null;
                    }
                }
            }
            catch (Exception /* ex */)   // we could eat simple programming errors here - like a bad cast or other problem when changing code
            {
                // "catch all" required because the device open & check calls might fail for a number of reasons
                // if there is a deviceID, remove it from cache, just in case
                if (deviceId != null)
                {
                    _devicesCache.TryRemove(deviceId, out var dummy);
                }

                try
                {
                    device.DebugEngine?.Stop();
                    device.DebugEngine?.Dispose();
                    device.DebugEngine = null;

                    if (device.DeviceBase != null)
                    {
                        ((SerialPort)device.DeviceBase).Close();
                        ((SerialPort)device.DeviceBase).Dispose();

                        device.DeviceBase = null;
                    }
                }
                catch
                {
                    // catch all trying to get rid of the device
                }
            }

            return(validDevice);
        }
Exemplo n.º 12
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();
                    }
                }
            }
        }
Exemplo n.º 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 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();
                }
            }
        }
Exemplo n.º 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)
        {
            // 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);
                    }
                }
            }
        }