/// <summary> /// Connect and manage connection as well as hook into your required characterisitcs with all proper cleanups necessary /// </summary> /// <param name="peripheral"></param> /// <param name="args"></param> /// <returns></returns> public static IObservable <CharacteristicGattResult> ConnectHook(this IPeripheral peripheral, ConnectHookArgs args) => Observable.Create <CharacteristicGattResult>(ob => { var sub = peripheral .WhenConnected() .Select(_ => peripheral.WhenKnownCharacteristicsDiscovered(args.ServiceUuid, args.CharacteristicUuids)) .Switch() .Select(x => x.Notify(false)) .Merge() .Subscribe( ob.OnNext, ob.OnError ); var connSub = peripheral .WhenConnectionFailed() .Subscribe(ob.OnError); peripheral.ConnectIf(args.Config); return(() => { peripheral.CancelConnection(); sub?.Dispose(); connSub?.Dispose(); }); });
/// <summary> /// /// </summary> /// <param name="peripheral"></param> /// <param name="serviceUuid"></param> /// <param name="characteristicUuid"></param> /// <param name="useIndicationsIfAvailable"></param> /// <returns></returns> public static IObservable <GattCharacteristicResult> WhenConnectedNotify(this IPeripheral peripheral, string serviceUuid, string characteristicUuid, bool useIndicationsIfAvailable = false) => peripheral .WhenConnected() .Select(x => x.GetKnownCharacteristic(serviceUuid, characteristicUuid, true)) .Switch() .Select(x => x.Notify(useIndicationsIfAvailable)) .Switch();
/// <summary> /// Attempts to connect if not already connected /// </summary> /// <param name="peripheral"></param> /// <param name="config"></param> /// <returns></returns> public static IObservable <IPeripheral> WithConnectIf(this IPeripheral peripheral, ConnectionConfig?config = null) => Observable.Create <IPeripheral>(ob => { if (peripheral.IsConnected()) { ob.Respond(peripheral); return(Disposable.Empty); } var sub1 = peripheral .WhenConnected() .Take(1) .Subscribe(_ => ob.Respond(peripheral)); var sub2 = peripheral .WhenConnectionFailed() .Subscribe(ob.OnError); peripheral.Connect(config); return(Disposable.Create(() => { sub1.Dispose(); sub2.Dispose(); if (peripheral.Status != ConnectionState.Connected) { peripheral.CancelConnection(); } })); });
/// <summary> /// Connect and manage connection as well as hook into your required characterisitcs with all proper cleanups necessary /// </summary> /// <param name="peripheral"></param> /// <param name="serviceUuid"></param> /// <param name="characteristicUuids"></param> /// <returns></returns> public static IObservable <CharacteristicGattResult> Notify(this IPeripheral peripheral, Guid serviceUuid, params Guid[] characteristicUuids) => peripheral .WhenConnected() .Select(_ => peripheral.WhenKnownCharacteristicsDiscovered(serviceUuid, characteristicUuids)) .Switch() .Select(x => x.Notify()) .Merge();
/// <summary> /// Connect and manage connection as well as hook into your required characterisitcs with all proper cleanups necessary /// </summary> /// <param name="device"></param> /// <param name="serviceUuid"></param> /// <param name="characteristicUuids"></param> /// <returns></returns> public static IObservable <CharacteristicGattResult> ConnectHook(this IPeripheral device, Guid serviceUuid, params Guid[] characteristicUuids) => Observable.Create <CharacteristicGattResult>(ob => { var sub = device .WhenConnected() .Select(_ => device.WhenKnownCharacteristicsDiscovered(serviceUuid, characteristicUuids)) .Switch() .Select(x => x.Notify(false)) .Merge() .Subscribe( ob.OnNext, ob.OnError ); var connSub = device .WhenConnectionFailed() .Subscribe(ob.OnError); // TODO: connectconfig - pass args object device.ConnectIf(); return(() => { device.CancelConnection(); sub?.Dispose(); connSub?.Dispose(); }); });
async Task DoManagedPeripheral() { const string serviceUuid = "FFF0"; const string rxUuid = "FFF1"; const string txUuid = "FFF2"; await this.FindDevice(); using (var managed = this.peripheral.CreateManaged()) { await managed.EnableNotifications(true, serviceUuid, rxUuid); this.Append("Ok - Disconnect the device now, we'll wait"); await this.peripheral.WhenDisconnected().Take(1).ToTask(this.cancelSrc.Token); peripheral.WhenConnected().Take(1).Subscribe(_ => this.Append("RE-CONNECTED - awaiting ready on rx notification")); var ready = managed.WhenNotificationReady().Take(1).ToTask(this.cancelSrc.Token); this.Append("Ok - Reconnect the device"); await ready.ConfigureAwait(false); this.Append("Ready fired! SUCCESS"); var responseTask = managed .WhenNotificationReceived(serviceUuid, rxUuid) .Select(Encoding.ASCII.GetString) .Take(1) .ToTask(this.cancelSrc.Token); this.Append("Sending TX"); await managed.Write(serviceUuid, txUuid, Encoding.ASCII.GetBytes("010D\r")); var response = await responseTask.ConfigureAwait(false); this.Append("RX Received - " + response); } }
/// <summary> /// Waits for connection to actually happen /// </summary> /// <param name="peripheral"></param> /// <returns></returns> public static IObservable <IPeripheral> ConnectWait(this IPeripheral peripheral) => Observable.Create <IPeripheral>(ob => { var sub1 = peripheral .WhenConnected() .Take(1) .Subscribe(_ => ob.Respond(peripheral)); var sub2 = peripheral .WhenConnectionFailed() .Subscribe(ob.OnError); peripheral.ConnectIf(); return(() => { sub1.Dispose(); sub2.Dispose(); if (peripheral.Status != ConnectionState.Connected) { peripheral.CancelConnection(); } }); });
/// <summary> /// When peripheral is connected, this will call for RSSI continuously /// </summary> /// <param name="peripheral"></param> /// <param name="readInterval"></param> /// <returns></returns> public static IObservable <int> WhenReadRssiContinuously(this IPeripheral peripheral, TimeSpan?readInterval = null) => peripheral .WhenConnected() .Select(x => x.ReadRssiContinuously(readInterval)) .Switch();
/// <summary> /// Will discover all services/characteristics when connected state occurs /// </summary> /// <param name="peripheral"></param> /// <returns></returns> public static IObservable <IGattCharacteristic> WhenAnyCharacteristicDiscovered(this IPeripheral peripheral) => peripheral .WhenConnected() .Select(x => peripheral.DiscoverServices()) .Switch() .SelectMany(x => x.DiscoverCharacteristics());
/// <summary> /// Get a known service when the peripheral is connected /// </summary> /// <param name="peripheral"></param> /// <param name="serviceUuid"></param> /// <returns></returns> public static IObservable <IGattService> WhenConnectedGetKnownService(this IPeripheral peripheral, Guid serviceUuid) => peripheral .WhenConnected() .Select(x => x.GetKnownService(serviceUuid)) .Switch();
/// <summary> /// Will call GetKnownCharacteristics when connected state occurs /// </summary> /// <param name="peripheral"></param> /// <param name="serviceUuid"></param> /// <param name="characteristicIds"></param> /// <returns></returns> public static IObservable <IGattCharacteristic> WhenKnownCharacteristicsDiscovered(this IPeripheral peripheral, Guid serviceUuid, params Guid[] characteristicIds) => peripheral .WhenConnected() .SelectMany(x => x.GetKnownCharacteristics(serviceUuid, characteristicIds));