public IEECommDevice TryGetDevice(IScanConfiguration config, ushort busAddr) { if (config is ScanConfigurationUART scanConfigurationUART) { if (busAddr == 0) { throw new ArgumentException("Device bus address must not be 0", "busAddr"); } IEECommDevice device = null; // Search in already existing devices before starting a new scan lock (_foundDevices) { device = _foundDevices.FirstOrDefault(x => x.InterfaceType == InterfaceType.UART && x.InterfaceId == busAddr.ToString()); } if (device != null) { // Try to revitalize device IEECommProtocol protEE31 = EECommProtocolFactory.GetEE31Protocol(device); IEECommandResult result = null; // Force silence Thread.Sleep(50); // For non-EE31 devices (Modbus, etc.): Send protocol switch command to make them speak EE31 (again) ushort discoveryId = DiscoveryCmdParams.BuildNewDiscoveryId(); try { result = protEE31.ExecuteCommand(EE31Command.Discovery, new DiscoveryCmdParams(discoveryId, busAddr, 0, 100)); } catch { } try { result = protEE31.ExecuteCommand(EE31Command.Discovery, new DiscoveryCmdParams(discoveryId, busAddr, 0, 50)); } catch { } if (result != null && result.Code == EECmdResultCode.Success) { return(device); } } return(device); } else if (config is ScanConfigurationEmulation scanConfigurationEmulation) { IEECommDevice emulatedDevice = new EECommDeviceEmulation(0, scanConfigurationEmulation.EmulationDevicesSettings.ElementAt(0)); var existing = _foundDevices.FirstOrDefault(x => x.InterfaceType == InterfaceType.Emulation && x.InterfaceId == emulatedDevice.InterfaceId); if (existing == null) { existing = emulatedDevice; } return(existing); } throw new NotImplementedException("Currently it is only possible to get UART or emulated devices."); }
/// <summary> /// Ensures connection status. Connects device if necessary. /// </summary> public override void EnsureConnection() { // Stop scan if device gets connected EEDeviceManagerFactory.DeviceManager.StopScan(); if (_bleDevice != null && !_bleDevice.IsConnected()) { bool success = Task.Run(async() => { _bleDevice.Connect(new ConnectionConfig { AutoConnect = true, AndroidConnectionPriority = ConnectionPriority.High }); // Change MTU size to at least 256 bytes otherwise protocol might not work int mtu = await _bleDevice.RequestMtu(256); if (mtu < 256) { Diagnostic.Msg(1, "EnsureConnection", "Unable to set MTU size to 256. Communication might not work correctly."); } else { Diagnostic.Msg(1, "EnsureConnection", "Set MTU size to " + mtu); } int loopCnt = 0; while (loopCnt < 100 && !_bleDevice.IsConnected()) { loopCnt++; await Task.Delay(100); } if (!_bleDevice.IsConnected()) { // Could not connect to device return(false); } await _bleDevice.DiscoverServices(); // Check rx Characteristic for notification or indication IGattCharacteristic rxCharacteristic = await _bleDevice.GetCharacteristicsForService(ServiceUuid) .FirstOrDefaultAsync(x => x.Uuid == RxCharacteristicUuid); if (!rxCharacteristic.CanNotifyOrIndicate()) { return(false); } // Enable notification/indication on device await rxCharacteristic.EnableNotifications(true); rxCharacteristic.WhenNotificationReceived().Subscribe(result => { _stopWatch.Stop(); lock (_lockDebugInfo) { if (_responseTimeMs.Count >= 1000) { _responseTimeMs.RemoveAt(0); } _responseTimeMs.Add(_stopWatch.ElapsedMilliseconds); } foreach (byte b in result.Data) { _queueRx.Enqueue(b); } }); return(_bleDevice.IsConnected()); }).Result; Connected = success; if (!success) { // Could not connect to device Diagnostic.Msg(1, "EnsureConnection", "Could not connect to device"); return; } else { // Need to send DIAS to keep connection open var ee31 = new Protocol.EE31Protocol(this); IEECommandResult result = ee31.ExecuteCommand(EE31Command.Discovery, new DiscoveryCmdParams(DiscoveryCmdParams.BuildNewDiscoveryId(), 0, 20, 500, 0xAF)); if (result.Code != EECmdResultCode.Success) { Diagnostic.Msg(1, "EnsureConnection", "Failed to send DIAS command (" + result.Code.ToString() + ")"); } } } _cmdTx = 0x0; while (!_queueRx.IsEmpty) { _queueRx.TryDequeue(out byte dummy); } }