Example #1
0
        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.");
        }
Example #2
0
        /// <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);
            }
        }