Beispiel #1
0
        async Task DoFallbackReconnect(GattConnectionConfig config, CancellationToken ct)
        {
            if (this.Status == ConnectionStatus.Connected)
            {
                Log.Debug("Reconnect", "Reconnection successful");
            }
            else
            {
                this.context.Close(); // kill current gatt

                if (ct.IsCancellationRequested)
                {
                    Log.Debug("Reconnect", "Reconnection loop cancelled");
                }
                else
                {
                    Log.Debug("Reconnect", "Reconnection failed - handing off to android autoReconnect");
                    try
                    {
                        await this.context.Connect(config.Priority, true);
                    }
                    catch (Exception ex)
                    {
                        Log.Error("Reconnect", "Reconnection failed to hand off - " + ex);
                    }
                }
            }
        }
Beispiel #2
0
        async Task DoReconnect(GattConnectionConfig config, CancellationToken ct)
        {
            Log.Debug("Reconnect", "Starting reconnection loop");
            this.connSubject.OnNext(ConnectionStatus.Connecting);
            var attempts = 1;

            while (!ct.IsCancellationRequested &&
                   this.Status != ConnectionStatus.Connected &&
                   attempts <= CrossBleAdapter.AndroidMaxAutoReconnectAttempts)
            {
                Log.Write("Reconnect", "Reconnection Attempt " + attempts);

                // breathe before attempting (again)
                await Task.Delay(
                    CrossBleAdapter.AndroidPauseBetweenAutoReconnectAttempts,
                    ct
                    );

                try
                {
                    await this.context.Reconnect(config.Priority);
                }
                catch (Exception ex)
                {
                    Log.Warn("Reconnect", "Error reconnecting " + ex);
                }
                attempts++;
            }
            if (this.Status != ConnectionStatus.Connected)
            {
                await this.DoFallbackReconnect(config, ct);
            }
        }
Beispiel #3
0
 // TODO: do I need to watch for connection errors here?
 IDisposable CreateAutoReconnectSubscription(GattConnectionConfig config) => this
 .WhenStatusChanged()
 .Skip(1)     // skip the initial "Disconnected"
 .Where(x => x == ConnectionStatus.Disconnected)
 .Select(_ => Observable.FromAsync(ct1 => this.DoReconnect(config, ct1)))
 .Merge()
 .Subscribe();
Beispiel #4
0
        protected virtual void SetupAutoReconnect(GattConnectionConfig config)
        {
            if (this.ReconnectSubscription != null)
            {
                return;
            }

            if (!config.IsPersistent)
            {
                return;
            }

            this.cancelReconnect       = false;
            this.ReconnectSubscription = this.WhenStatusChanged()
                                         .Skip(1) // skip the initial registration
                                         .Where(x => x == ConnectionStatus.Disconnected)
                                         .Subscribe(async x =>
            {
                while (!this.cancelReconnect && this.Status != ConnectionStatus.Connected)
                {
                    try
                    {
                        await Task.Delay(300);
                        if (!this.cancelReconnect)
                        {
                            await this.Connect(config);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Out("Failed to reconnect to device - " + ex);
                    }
                }
            });
        }
Beispiel #5
0
 public IObservable <object> Connect(GattConnectionConfig config)
 {
     // TODO: configurable "connection" type - RSSI check, timed read on first characteristic, device watcher
     // TODO: monitor devicewatcher - if removed d/c, if added AND paired - connected
     this.connSubject.OnNext(ConnectionStatus.Connected);
     this.status = ConnectionStatus.Connected;
     return(Observable.Return(new object()));
 }
Beispiel #6
0
        public override IObservable <object> Connect(GattConnectionConfig config)
        => Observable.Create <object>(ob =>
        {
            var sub = this.WhenStatusChanged()
                      .Where(x => x == ConnectionStatus.Connected)
                      .Subscribe(_ => ob.Respond(null));

            this.context.Connect();

            return(sub);
        });
Beispiel #7
0
        public override IObservable <object> Connect(GattConnectionConfig config)
        {
            config = config ?? GattConnectionConfig.DefaultConfiguration;
            this.SetupAutoReconnect(config);

            return(Observable.Create <object>(ob =>
            {
                var cancelSrc = new CancellationTokenSource();
                var connected = this
                                .WhenStatusChanged()
                                .Take(1)
                                .Where(x => x == ConnectionStatus.Connected)
                                .Subscribe(_ => ob.Respond(null));

                if (this.Status != ConnectionStatus.Connecting)
                {
                    try
                    {
                        ob.OnNext(ConnectionStatus.Connecting);

                        switch (AndroidConfig.ConnectionThread)
                        {
                        case ConnectionThread.MainThread:
                            Application.SynchronizationContext.Post(_ => this.Context.Connect(config), null);
                            break;

                        case ConnectionThread.ScanThread:
                            Task.Factory.StartNew(
                                () => this.Context.Connect(config),
                                cancelSrc.Token,
                                TaskCreationOptions.None,
                                this.scheduler
                                );
                            break;

                        case ConnectionThread.Default:
                        default:
                            this.Context.Connect(config);
                            break;
                        }
                    }
                    catch (Exception ex)
                    {
                        ob.OnNext(ConnectionStatus.Disconnected);
                        ob.OnError(ex);
                    }
                }
                return () =>
                {
                    connected?.Dispose();
                    cancelSrc.Dispose();
                };
            }));
        }
Beispiel #8
0
        public override IObservable <object> Connect(GattConnectionConfig config)
        => Observable.FromAsync(async token =>
        {
            //if (this.native == null)
            //this.native = await BluetoothLEDevice.FromIdAsync(this.deviceId);

            //this.native = await BluetoothLEDevice.FromBluetoothAddressAsync(0L);
            this.status = ConnectionStatus.Connected;
            this.connSubject.OnNext(ConnectionStatus.Connected);
            return(new object());
        });
Beispiel #9
0
        protected void DoConnect(IObserver <object> ob, GattConnectionConfig config)
        {
            try
            {
                this.connSubject.OnNext(ConnectionStatus.Connecting);
                if (!this.context.Connect(config))
                {
                    throw new ArgumentException("Unable to connect");
                }

                ob.Respond(null);
            }
            catch (Exception ex)
            {
                this.connSubject.OnNext(ConnectionStatus.Disconnected);
                ob.OnError(ex);
            }
        }
Beispiel #10
0
        public override IObservable <object> Connect(GattConnectionConfig config)
        {
            config = config ?? GattConnectionConfig.DefaultConfiguration;
            this.SetupAutoReconnect(config);

            return(Observable.Create <object>(ob =>
            {
                IDisposable sub1 = null;
                IDisposable sub2 = null;

                if (this.Status == ConnectionStatus.Connected)
                {
                    ob.Respond(null);
                }
                else
                {
                    sub1 = this.context
                           .PeripheralConnected
                           .Where(x => x.Equals(this.peripheral))
                           .Subscribe(x => ob.Respond(null));

                    sub2 = this.context
                           .FailedConnection
                           .Where(x => x.Peripheral.Equals(this.peripheral))
                           .Subscribe(x => ob.OnError(new Exception(x.Error.ToString())));

                    this.context.Manager.ConnectPeripheral(this.peripheral, new PeripheralConnectionOptions
                    {
                        NotifyOnDisconnection = config.NotifyOnDisconnect,
#if __IOS__ || __TVOS__
                        NotifyOnConnection = config.NotifyOnConnect,
                        NotifyOnNotification = config.NotifyOnNotification
#endif
                    });
                }

                return () =>
                {
                    sub1?.Dispose();
                    sub2?.Dispose();
                };
            }));
        }
Beispiel #11
0
        public override IObservable <object> Connect(GattConnectionConfig config)
        => Observable.Create <object>(ob =>
        {
            config           = config ?? GattConnectionConfig.DefaultConfiguration;
            IDisposable sub1 = null;
            IDisposable sub2 = null;

            if (this.Status == ConnectionStatus.Connected)
            {
                ob.Respond(null);
            }
            else
            {
                sub1 = this.context
                       .PeripheralConnected
                       .Where(x => x.Equals(this.peripheral))
                       .Subscribe(x =>
                {
                    if (config.IsPersistent)
                    {
                        this.autoReconnect = this.SetupAutoReconnect();
                    }

                    ob.Respond(null);
                });

                sub2 = this.context
                       .FailedConnection
                       .Where(x => x.Peripheral.Equals(this.peripheral))
                       .Subscribe(x => ob.OnError(new Exception(x.Error.ToString())));

                this.DoConnection();
            }

            return(() =>
            {
                sub1?.Dispose();
                sub2?.Dispose();
            });
        });
Beispiel #12
0
        public override IObservable <object> Connect(GattConnectionConfig config) => Observable.Create <object>(async ob =>
        {
            var connected = false;
            config        = config ?? GattConnectionConfig.DefaultConfiguration;

            var sub1 = this.WhenStatusChanged()
                       .Where(x => x == ConnectionStatus.Connected)
                       .Subscribe(_ =>
            {
                connected = true;
                if (config.IsPersistent)
                {
                    this.autoReconnectSub = this.CreateAutoReconnectSubscription(config);
                }

                ob.Respond(null);
            });

            var sub2 = this.connFailSubject.Subscribe(x =>
            {
                this.connSubject.OnNext(ConnectionStatus.Disconnected);
                this.context.Gatt?.Close();
                ob.OnError(new Exception("Connection failed - " + x));
            });

            this.connSubject.OnNext(ConnectionStatus.Connecting);
            await this.context.Connect(config.Priority, config.AndroidAutoConnect);

            return(() =>
            {
                if (!connected)
                {
                    this.context.Gatt?.Close();
                    this.connSubject.OnNext(ConnectionStatus.Disconnected);
                }
                sub1.Dispose();
                sub2.Dispose();
            });
        });
 public abstract IObservable <object> Connect(GattConnectionConfig config);
Beispiel #14
0
 public override IObservable <object> Connect(GattConnectionConfig config)
 {
     throw new NotImplementedException();
 }
Beispiel #15
0
 public override IObservable <object> Connect(GattConnectionConfig config) => Observable.Create <object>(ob =>
 {
     this.native.GattConnect(config.AutoConnect);
     return(() => { });
 });