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); }
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); }