예제 #1
0
        public override IObservable <IScanResult> Scan(ScanConfig config)
        {
            if (this.IsScanning)
            {
                throw new ArgumentException("There is already an active scan");
            }

            return(Observable.Create <IScanResult>(ob =>
            {
                this.IsScanning = true;
                this.context.Clear();

                var sub = this
                          .WhenRadioReady()
                          .Where(rdo => rdo != null)
                          .Select(_ => this.CreateScanner(config))
                          .Switch()
                          .Subscribe(
                    async args =>     // CAREFUL
                {
                    var device = this.context.GetPeripheral(args.BluetoothAddress);
                    if (device == null)
                    {
                        var btDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
                        if (btDevice != null)
                        {
                            device = this.context.AddOrGetPeripheral(btDevice);
                        }
                    }
                    if (device != null)
                    {
                        var adData = new AdvertisementData(args);
                        var scanResult = new ScanResult(device, args.RawSignalStrengthInDBm, adData);
                        ob.OnNext(scanResult);
                    }
                },
                    ob.OnError
                    );

                var stopSub = this.scanSubject.Subscribe(_ =>
                {
                    this.IsScanning = false;
                    sub?.Dispose();
                    ob.OnCompleted();
                });

                return () =>
                {
                    this.IsScanning = false;
                    sub?.Dispose();
                    stopSub?.Dispose();
                };
            }));
        }
        public override IObservable <IScanResult> Scan(ScanConfig config)
        {
            if (this.IsScanning)
            {
                throw new ArgumentException("There is already an active scan");
            }

            this.isScanning = true;
            return(this.context
                   .Scan(config ?? new ScanConfig())
                   .Finally(() => this.isScanning = false));
        }
예제 #3
0
        public override IObservable <IScanResult> Scan(ScanConfig config)
        {
            config = config ?? new ScanConfig();

            if (this.IsScanning)
            {
                throw new ArgumentException("There is already an existing scan");
            }

            //if (config.ScanType == BleScanType.Background && (config.ServiceUuids == null || config.ServiceUuids.Count == 0))
            //    throw new ArgumentException("Background scan type set but not ServiceUUID");

            this.context.Clear();
            return(this.context
                   .Manager
                   .WhenReady()
                   .Select(_ => Observable.Create <IScanResult>(ob =>
            {
                var scan = this.context
                           .ScanResultReceived
                           .AsObservable()
                           .Subscribe(ob.OnNext);

                if (config.ServiceUuids == null || config.ServiceUuids.Count == 0)
                {
                    this.context.Manager.ScanForPeripherals(null, new PeripheralScanningOptions {
                        AllowDuplicatesKey = true
                    });
                }
                else
                {
                    var uuids = config.ServiceUuids.Select(o => o.ToCBUuid()).ToArray();
                    this.context.Manager.ScanForPeripherals(uuids, new PeripheralScanningOptions {
                        AllowDuplicatesKey = true
                    });
                }

                return () =>
                {
                    this.context.Manager.StopScan();
                    scan.Dispose();
                };
            }))
                   .Switch());
        }
예제 #4
0
        IObservable <BluetoothLEAdvertisementReceivedEventArgs> CreateScanner(ScanConfig config)
        => Observable.Create <BluetoothLEAdvertisementReceivedEventArgs>(ob =>
        {
            this.context.Clear();
            config = config ?? new ScanConfig {
                ScanType = BleScanType.Balanced
            };

            var adWatcher = new BluetoothLEAdvertisementWatcher();
            if (config.ServiceUuids != null)
            {
                foreach (var serviceUuid in config.ServiceUuids)
                {
                    adWatcher.AdvertisementFilter.Advertisement.ServiceUuids.Add(serviceUuid);
                }
            }

            switch (config.ScanType)
            {
            case BleScanType.Balanced:
                adWatcher.ScanningMode = BluetoothLEScanningMode.Active;
                break;

            //case BleScanType.Background:
            case BleScanType.LowLatency:
            case BleScanType.LowPowered:
                adWatcher.ScanningMode = BluetoothLEScanningMode.Passive;
                break;
            }
            var handler = new TypedEventHandler <BluetoothLEAdvertisementWatcher, BluetoothLEAdvertisementReceivedEventArgs>
                              ((sender, args) => ob.OnNext(args)
                              );

            adWatcher.Received += handler;
            adWatcher.Start();

            return(() =>
            {
                adWatcher.Stop();
                adWatcher.Received -= handler;
            });
        });
 /// <summary>
 /// Runs BLE scan for a set timespan then pauses for configured timespan before starting again
 /// </summary>
 /// <param name="centralManager"></param>
 /// <param name="scanTime"></param>
 /// <param name="scanPauseTime"></param>
 /// <param name="config"></param>
 /// <returns></returns>
 public static IObservable <IScanResult> ScanInterval(this ICentralManager centralManager, TimeSpan scanTime, TimeSpan scanPauseTime, ScanConfig config = null) => Observable.Create <IScanResult>(ob =>
 /// <summary>
 /// This method wraps the traditional scan, but waits for the centralManager to be ready before initiating scan
 /// </summary>
 /// <param name="centralManager">The centralManager to scan with</param>
 /// <param name="restart">Stops any current scan running</param>
 /// <param name="config">ScanConfig parameters you would like to use</param>
 /// <returns></returns>
 public static IObservable <IScanResult> Scan(this ICentralManager centralManager, ScanConfig config = null, bool restart = false)
 {
     if (restart && centralManager.IsScanning)
     {
         centralManager.StopScan(); // need a pause to wait for scan to end
     }
     return(centralManager.Scan(config));
 }
 /// <summary>
 /// Scans only for distinct peripherals instead of repeating each peripheral scan response - this will only give you peripherals, not RSSI or ad packets
 /// </summary>
 /// <param name="centralManager"></param>
 /// <param name="config"></param>
 /// <returns></returns>
 public static IObservable <IPeripheral> ScanForUniquePeripherals(this ICentralManager centralManager, ScanConfig config = null) => centralManager
 .Scan(config)
 .Distinct(x => x.Peripheral.Uuid)
 .Select(x => x.Peripheral);
예제 #8
0
 public abstract IObservable <IScanResult> Scan(ScanConfig config = null);