Exemplo n.º 1
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.º 2
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);
        }