public override IObservable <CharacteristicGattResult> WriteWithoutResponse(byte[] value) => this.context.Invoke(Observable.Create <CharacteristicGattResult>(ob => { this.AssertWrite(false); this.context.InvokeOnMainThread(() => { try { this.native.WriteType = GattWriteType.NoResponse; if (!this.native.SetValue(value)) { throw new BleException("Failed to write characteristic value"); } if (!this.context.Gatt.WriteCharacteristic(this.native)) { throw new BleException("Failed to write to characteristic"); } ob.Respond(new CharacteristicGattResult(this, value)); } catch (Exception ex) { throw new BleException("Error during charactersitic write", ex); } }); return(Disposable.Empty); }));
public override IObservable <CharacteristicResult> WhenNotificationReceived() { this.AssertNotify(); this.notifyOb = this.notifyOb ?? Observable.Create <CharacteristicResult>(ob => this.context .Callbacks .CharacteristicChanged .Where(this.NativeEquals) .Subscribe(args => { if (!args.IsSuccessful) { ob.OnError(new ArgumentException("Error subscribing to " + args.Characteristic.Uuid)); } else { this.Value = args.Characteristic.GetValue(); var result = new CharacteristicResult(this, CharacteristicEvent.Notification, this.Value); ob.OnNext(result); } }) ) .Publish() .RefCount(); return(this.notifyOb); }
public override IObservable <ReadRequest> WhenReadReceived() { return(Observable.Create <ReadRequest>(ob => { var handler = new EventHandler <CharacteristicReadEventArgs>((sender, args) => { if (!args.Characteristic.Equals(this.Native)) { return; } var device = new Device(args.Device); var request = new ReadRequest(device, args.Offset); ob.OnNext(request); lock (this.context.ServerReadWriteLock) { this.context.Server.SendResponse( args.Device, args.RequestId, request.Status.ToNative(), args.Offset, request.Value ); } }); this.context.Callbacks.CharacteristicRead += handler; return () => this.context.Callbacks.CharacteristicRead -= handler; })); }
public override IObservable <WriteRequest> WhenWriteReceived() => Observable.Create <WriteRequest>(ob => { var handler = new EventHandler <CharacteristicWriteEventArgs>((sender, args) => { if (!args.Characteristic.Equals(this.Native)) { return; } var device = new Device(args.Device); var request = new WriteRequest(device, args.Value, args.Offset, args.ResponseNeeded); ob.OnNext(request); if (request.IsReplyNeeded) { lock (this.context.ServerReadWriteLock) { this.context.Server.SendResponse ( args.Device, args.RequestId, request.Status.ToNative(), request.Offset, request.Value ); } } }); this.context.Callbacks.CharacteristicWrite += handler; return(() => this.context.Callbacks.CharacteristicWrite -= handler); });
public override IObservable <CharacteristicGattResult> Read() => this.context.Invoke(Observable.Create <CharacteristicGattResult>(ob => { this.AssertRead(); var sub = this.context .Callbacks .CharacteristicRead .Where(this.NativeEquals) .Subscribe(args => { if (args.IsSuccessful) { ob.Respond(new CharacteristicGattResult(this, args.Characteristic.GetValue())); } else { ob.OnError(new BleException($"Failed to read characteristic - {args.Status}")); } }); this.context.InvokeOnMainThread(() => { if (!this.context.Gatt.ReadCharacteristic(this.native)) { ob.OnError(new BleException("Failed to read characteristic")); } }); return(sub); }));
public override IObservable <CharacteristicBroadcast> BroadcastObserve(byte[] value, params IDevice[] devices) { return(Observable.Create <CharacteristicBroadcast>(ob => { var cancel = false; this.Native.SetValue(value); if (devices == null || devices.Length == 0) { devices = this.subscribers.Values.ToArray(); } var indicate = this.Properties.HasFlag(CharacteristicProperties.Indicate); foreach (var x in devices.OfType <Device>()) { if (!cancel) { lock (this.context.ServerReadWriteLock) { if (!cancel) { var result = this.context.Server.NotifyCharacteristicChanged(x.Native, this.Native, indicate); ob.OnNext(new CharacteristicBroadcast(x, this, value, indicate, result)); } } } } ob.OnCompleted(); return () => cancel = true; })); }
public override IObservable <CharacteristicResult> WhenNotificationReceived() { this.AssertNotify(); this.notifyOb = this.notifyOb ?? Observable.Create <CharacteristicResult>(ob => { var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (this.NativeEquals(args)) { if (!args.IsSuccessful) { ob.OnError(new ArgumentException("Error subscribing to " + args.Characteristic.Uuid)); } else { this.Value = args.Characteristic.GetValue(); var result = new CharacteristicResult(this, CharacteristicEvent.Notification, this.Value); ob.OnNext(result); } } }); this.context.Callbacks.CharacteristicChanged += handler; return(() => this.context.Callbacks.CharacteristicChanged -= handler); }) .Publish() .RefCount(); return(this.notifyOb); }
public override IObservable <CharacteristicResult> Read() { this.AssertRead(); return(Observable.Create <CharacteristicResult>(ob => { var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (args.Characteristic.Equals(this.native)) { if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to read characteristic - {args.Status}")); } else { this.Value = args.Characteristic.GetValue(); var result = new CharacteristicResult(this, CharacteristicEvent.Read, this.Value); ob.Respond(result); this.ReadSubject.OnNext(result); } } }); this.context.Callbacks.CharacteristicRead += handler; this.context.Gatt.ReadCharacteristic(this.native); return () => this.context.Callbacks.CharacteristicRead -= handler; })); }
public override IObservable <CharacteristicGattResult> WhenNotificationReceived() { this.AssertNotify(); this.notifyOb = this.notifyOb ?? Observable.Create <CharacteristicGattResult>(ob => this.context .Callbacks .CharacteristicChanged .Where(this.NativeEquals) .Subscribe(args => { if (args.IsSuccessful) { ob.OnNext(new CharacteristicGattResult(this, args.Characteristic.GetValue())); } else { ob.OnError(new BleException($"Notification error - {args.Status}")); } }) ) .Publish() .RefCount(); return(this.notifyOb); }
public override IObservable <CharacteristicResult> Write(byte[] value) { this.AssertWrite(false); return(Observable.Create <CharacteristicResult>(async ob => { CancellationTokenSource cancelSrc = null; var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (this.NativeEquals(args)) { if (cancelSrc != null) { this.context.Semaphore.Release(); } Log.Write("Incoming Characteristic Write Event - " + args.Characteristic.Uuid); if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to write characteristic - {args.Status}")); } else { this.Value = value; var result = new CharacteristicResult(this, CharacteristicEvent.Write, this.Value); ob.Respond(result); this.WriteSubject.OnNext(result); } } }); if (this.Properties.HasFlag(CharacteristicProperties.Write)) { cancelSrc = new CancellationTokenSource(); Log.Write("Hooking for write response - " + this.Uuid); await this.context.Semaphore.WaitAsync(cancelSrc.Token); this.context.Callbacks.CharacteristicWrite += handler; this.RawWriteWithResponse(value); } else { Log.Write("Write with No Response - " + this.Uuid); this.RawWriteNoResponse(ob, value); } return () => { cancelSrc?.Dispose(); this.context.Callbacks.CharacteristicWrite -= handler; }; })); }
public IObservable <AppState> WhenStateChanged() => Observable.Create <AppState>(ob => { var handler = new EventHandler((sender, args) => { var state = this.appState.IsActive ? AppState.Foreground : AppState.Background; ob.OnNext(state); }); this.appState.StatusChanged += handler; return(() => this.appState.StatusChanged -= handler); });
public override IObservable <IGattDescriptor> DiscoverDescriptors() => this.descriptorOb ??= Observable.Create <IGattDescriptor>(ob => { foreach (var nd in this.native.Descriptors) { var wrap = new GattDescriptor(this, this.context, nd); ob.OnNext(wrap); } return(Disposable.Empty); }) .Replay() .RefCount();
public override IObservable <DeviceSubscriptionEvent> WhenDeviceSubscriptionChanged() { this.subscriptionOb = this.subscriptionOb ?? Observable.Create <DeviceSubscriptionEvent>(ob => { var handler = new EventHandler <DescriptorWriteEventArgs>((sender, args) => { if (args.Descriptor.Equals(this.NotificationDescriptor)) { if (args.Value.SequenceEqual(NotifyEnabledBytes) || args.Value.SequenceEqual(IndicateEnableBytes)) { var device = this.GetOrAdd(args.Device); ob.OnNext(new DeviceSubscriptionEvent(device, true)); } else { var device = this.Remove(args.Device); if (device != null) { ob.OnNext(new DeviceSubscriptionEvent(device, false)); } } } }); var dhandler = new EventHandler <ConnectionStateChangeEventArgs>((sender, args) => { if (args.NewState != ProfileState.Disconnected) { return; } var device = this.Remove(args.Device); if (device != null) { ob.OnNext(new DeviceSubscriptionEvent(device, false)); } }); this.context.Callbacks.ConnectionStateChanged += dhandler; this.context.Callbacks.DescriptorWrite += handler; return(() => { this.context.Callbacks.DescriptorWrite -= handler; this.context.Callbacks.ConnectionStateChanged -= dhandler; }); }) .Publish() .RefCount(); return(this.subscriptionOb); }
public IObservable <Unit> WhenEnteringForeground() => Observable.Create <Unit>(ob => { var handler = new EventHandler((sender, args) => { if (this.appState.IsActive) { Debug.WriteLine("Firing WhenEnteringForeground Observable"); ob.OnNext(Unit.Default); } }); this.appState.StatusChanged += handler; return(() => this.appState.StatusChanged -= handler); });
public override IObservable <CharacteristicResult> Read() { this.AssertRead(); return(Observable.Create <CharacteristicResult>(async ob => { var cancelSrc = new CancellationTokenSource(); var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (this.NativeEquals(args)) { this.context.Semaphore.Release(); if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to read characteristic - {args.Status}")); } else { this.Value = args.Characteristic.GetValue(); var result = new CharacteristicResult(this, CharacteristicEvent.Read, this.Value); ob.Respond(result); this.ReadSubject.OnNext(result); } } }); this.context.Callbacks.CharacteristicRead += handler; await this.context.Semaphore.WaitAsync(cancelSrc.Token); this.context.Marshall(() => { try { this.context.Gatt.ReadCharacteristic(this.native); } catch (Exception ex) { ob.OnError(ex); } }); return () => this.context.Callbacks.CharacteristicRead -= handler; })); }
public override IObservable <IGattCharacteristic?> GetKnownCharacteristic(string characteristicUuid, bool throwIfNotFound = false) => Observable.Create <IGattCharacteristic?>(ob => { var uuid = UUID.FromString(characteristicUuid); var cs = this.native.GetCharacteristic(uuid); if (cs == null) { ob.Respond(null); } else { var characteristic = new GattCharacteristic(this, this.context, cs); ob.Respond(characteristic); } return(Disposable.Empty); }) .Assert(this.Uuid, characteristicUuid, throwIfNotFound);
public override IObservable <HttpTransfer> WhenUpdated() { // TODO: cancel/error, should remove from db var query = new QueryFilter().ToNative(); this.httpObs = this.httpObs ?? Observable .Create <HttpTransfer>(ob => { var lastRun = DateTime.UtcNow; var disposer = new CompositeDisposable(); HttpTransferBroadcastReceiver .HttpEvents .Subscribe(ob.OnNext) .DisposedBy(disposer); Observable .Interval(TimeSpan.FromSeconds(2)) .Subscribe(_ => { using (var cursor = this.context.GetManager().InvokeQuery(query)) { while (cursor.MoveToNext()) { var lastModEpoch = cursor.GetLong(cursor.GetColumnIndex(Native.ColumnLastModifiedTimestamp)); var epoch = DateTimeOffset.FromUnixTimeMilliseconds(lastModEpoch); if (epoch > lastRun) { var transfer = cursor.ToLib(); ob.OnNext(transfer); } } } lastRun = DateTime.UtcNow; }) .DisposedBy(disposer); return(disposer); }) .Publish() .RefCount(); return(this.httpObs.Merge(base.WhenUpdated())); }
public IObservable <object> WhenEnteringBackground() { return(Observable.Create <object>(ob => { var handler = new EventHandler((sender, args) => { Debug.WriteLine("Firing 1 WhenEnteringBackground Observable"); if (!this.appState.IsActive) { Debug.WriteLine("Firing WhenEnteringBackground Observable"); ob.OnNext(null); } }); this.appState.StatusChanged += handler; return () => this.appState.StatusChanged -= handler; })); }
public IObservable <ScanResult> Scan(ScanConfig config) => Observable.Create <ScanResult>(ob => { this.devices.Clear(); this.callbacks = new LollipopScanCallback( sr => { var scanResult = this.ToScanResult(sr.Device, sr.Rssi, new AdvertisementData(sr)); ob.OnNext(scanResult); }, errorCode => ob.OnError(new BleException("Error during scan: " + errorCode.ToString())) ); var builder = new ScanSettings.Builder(); var scanMode = this.ToNative(config.ScanType); builder.SetScanMode(scanMode); var scanFilters = new List <ScanFilter>(); if (config.ServiceUuids != null && config.ServiceUuids.Count > 0) { foreach (var uuid in config.ServiceUuids) { var parcel = new ParcelUuid(UUID.FromString(uuid)); scanFilters.Add(new ScanFilter.Builder() .SetServiceUuid(parcel) .Build() ); } } if (config.AndroidUseScanBatching && this.Manager.Adapter.IsOffloadedScanBatchingSupported) { builder.SetReportDelay(100); } this.Manager.Adapter.BluetoothLeScanner.StartScan( scanFilters, builder.Build(), this.callbacks ); return(() => this.Manager.Adapter.BluetoothLeScanner?.StopScan(this.callbacks)); });
public override IObservable <object> Write(byte[] value) { this.AssertWrite(false); return(Observable.Create <object>(ob => { var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (args.Characteristic.Uuid.Equals(this.native.Uuid)) { if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to write characteristic - {args.Status}")); } else { this.Value = value; ob.Respond(this.Value); this.WriteSubject.OnNext(this.Value); } } }); this.context.Callbacks.CharacteristicWrite += handler; this.native.SetValue(value); if (this.Properties.HasFlag(CharacteristicProperties.Write)) { this.native.WriteType = GattWriteType.Default; this.context.Gatt.WriteCharacteristic(this.native); } else { this.native.WriteType = GattWriteType.NoResponse; this.context.Gatt.WriteCharacteristic(this.native); this.Value = value; ob.Respond(this.Value); this.WriteSubject.OnNext(this.Value); } return () => this.context.Callbacks.CharacteristicWrite -= handler; })); }
public override IObservable <CharacteristicResult> Write(byte[] value) { this.AssertWrite(false); return(Observable.Create <CharacteristicResult>(ob => { var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { WriteLine($"Incoming Characteristic Write Event - " + args.Characteristic.Uuid); if (args.Characteristic.Equals(this.native)) { if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to write characteristic - {args.Status}")); } else { this.Value = value; var result = new CharacteristicResult(this, CharacteristicEvent.Write, this.Value); ob.Respond(result); this.WriteSubject.OnNext(result); } } }); if (this.Properties.HasFlag(CharacteristicProperties.Write)) { WriteLine("Hooking for write response - " + this.Uuid); this.context.Callbacks.CharacteristicWrite += handler; this.RawWriteWithResponse(value); } else { WriteLine("Write with No Response - " + this.Uuid); this.RawWriteNoResponse(ob, value); } return () => this.context.Callbacks.CharacteristicWrite -= handler; })); }
public override IObservable <CharacteristicGattResult> Write(byte[] value) => this.context.Invoke(Observable.Create <CharacteristicGattResult>(ob => { this.AssertWrite(false); var sub = this.context .Callbacks .CharacteristicWrite .Where(this.NativeEquals) .Subscribe(args => { Log.Debug(BleLogCategory.Characteristic, "write event - " + args.Characteristic.Uuid); if (args.IsSuccessful) { ob.Respond(new CharacteristicGattResult(this, value)); } else { ob.OnError(new BleException($"Failed to write characteristic - {args.Status}")); } }); Log.Debug(BleLogCategory.Characteristic, "Hooking for write response - " + this.Uuid); this.context.InvokeOnMainThread(() => { this.native.WriteType = GattWriteType.Default; this.native.SetValue(value); //if (!this.native.SetValue(value)) //ob.OnError(new BleException("Failed to set characteristic value")); //else if (!this.context.Gatt.WriteCharacteristic(this.native)) if (!this.context.Gatt.WriteCharacteristic(this.native)) { ob.OnError(new BleException("Failed to write to characteristic")); } }); return(sub); }));
public override IObservable <byte[]> SubscribeToNotifications() { this.AssertNotify(); this.notifyOb = this.notifyOb ?? Observable.Create <byte[]>(ob => { var handler = new EventHandler <GattCharacteristicEventArgs>((sender, args) => { if (args.Characteristic.Uuid.Equals(this.native.Uuid)) { if (!args.IsSuccessful) { ob.OnError(new ArgumentException("Error subscribing to " + args.Characteristic.Uuid)); } else { this.Value = args.Characteristic.GetValue(); ob.OnNext(this.Value); this.NotifySubject.OnNext(this.Value); } } }); this.EnableNotifications(); this.context.Callbacks.CharacteristicChanged += handler; return(() => { this.DisableNotifications(); this.context.Callbacks.CharacteristicChanged -= handler; }); }) .Publish() .RefCount(); return(this.notifyOb); }
public override IObservable <CharacteristicGattResult> Write(byte[] value, bool withResponse) => this.context.Invoke(Observable.Create <CharacteristicGattResult>(ob => { this.AssertWrite(false); var sub = this.context .Callbacks .CharacteristicWrite .Where(this.NativeEquals) .Subscribe(args => { Log.Write("BLE-Characteristic", "write event - " + args.Characteristic.Uuid); if (args.IsSuccessful) { ob.Respond(new CharacteristicGattResult(this, value, withResponse ? CharacteristicResultType.Write : CharacteristicResultType.WriteWithoutResponse)); } else { ob.OnError(new BleException($"Failed to write characteristic - {args.Status}")); } }); Log.Write("BLE-Characteristic", "Hooking for write response - " + this.Uuid); this.context.InvokeOnMainThread(() => { try { // TODO: signed write this.native.WriteType = withResponse ? GattWriteType.Default : GattWriteType.NoResponse; this.native.SetValue(value); //if (!this.native.SetValue(value)) //ob.OnError(new BleException("Failed to set characteristic value")); //else if (!this.context.Gatt.WriteCharacteristic(this.native)) if (!this.context.Gatt?.WriteCharacteristic(this.native) ?? false) { ob.OnError(new BleException("Failed to write to characteristic")); } } catch (Exception ex) { ob.OnError(ex); } }); return(sub); }));
internal static IObservable <TResult> SelectMany <TSource, TContext, TCollection, TResult>( this IObservable <TSource> source, TContext context, Func <TContext, Tuple <TSource, bool>, Tuple <TContext, IObservable <TCollection> > > firstCollectionSelector, IEnumerable <Func <TContext, Tuple <TCollection, bool>, Tuple <TContext, IObservable <TCollection> > > > otherCollectionSelectors, Func <TSource, IList <TCollection>, TResult> resultSelector) { Contract.Requires(source != null); Contract.Requires(context != null); Contract.Requires(firstCollectionSelector != null); Contract.Requires(otherCollectionSelectors != null); Contract.Requires(resultSelector != null); Contract.Ensures(Contract.Result <IObservable <TResult> >() != null); return(Observable.Create <TResult>( observer => { object gate = new object(); var disposables = new CompositeDisposable(); int running = 0; bool sourceCompleted = false; Action <Action> checkCompleted = change => { bool completeNow = false; lock (gate) { change(); completeNow = running == 0 && sourceCompleted; } if (completeNow) { observer.OnCompleted(); } }; Action <Func <IObservable <TCollection> >, Action <Tuple <TCollection, bool> > > subscribe = (selector, onNext) => { IObservable <TCollection> sequence; try { sequence = selector(); } catch (Exception ex) { observer.OnError(ex); return; } var subscription = new SingleAssignmentDisposable(); disposables.Add(subscription); Interlocked.Increment(ref running); subscription.Disposable = sequence.WithLastElementIndicator().SubscribeSafe( onNext, observer.OnError, () => { checkCompleted(() => Interlocked.Decrement(ref running)); disposables.Remove(subscription); }); }; object selectorCacheGate = new object(); var selectorCache = new List <Func <TContext, Tuple <TCollection, bool>, Tuple <TContext, IObservable <TCollection> > > >(); var enumerator = otherCollectionSelectors.GetEnumerator(); disposables.Add(Disposable.Create(() => { lock (selectorCacheGate) { enumerator.Dispose(); enumerator = null; } })); Func <int, Func <TContext, Tuple <TCollection, bool>, Tuple <TContext, IObservable <TCollection> > > > getSelector = depth => { Func <TContext, Tuple <TCollection, bool>, Tuple <TContext, IObservable <TCollection> > > selector = null; lock (selectorCacheGate) { if (enumerator == null) { return null; } else if (selectorCache.Count > depth) { selector = selectorCache[depth]; } else if (enumerator.MoveNext()) { selector = enumerator.Current; selectorCache.Add(selector); } else { selectorCache.Add(null); } } return selector; }; Func <int, TContext, TSource, IEnumerable <TCollection>, Action <Tuple <TCollection, bool> > > onNextSequential = null; onNextSequential = (depth, currentContext, first, others) => value => { var list = others.ToList(); list.Add(value.Item1); var selector = getSelector(depth); if (selector != null) { var sequence = selector(currentContext, value); subscribe( () => sequence.Item2, onNextSequential(depth + 1, sequence.Item1, first, list)); } else { TResult result; try { result = resultSelector(first, list.AsReadOnly()); } catch (Exception ex) { observer.OnError(ex); return; } observer.OnNext(result); } }; disposables.Add(source.WithLastElementIndicator().SubscribeSafe( first => { var sequence = firstCollectionSelector(context, first); subscribe( () => sequence.Item2, onNextSequential(0, sequence.Item1, first.Item1, Enumerable.Empty <TCollection>())); }, observer.OnError, () => checkCompleted(() => sourceCompleted = true))); return disposables; })); }
public override IObservable <IGattCharacteristic> EnableNotifications(bool enable, bool useIndicationsIfAvailable) => this.context.Invoke(Observable.Create <IGattCharacteristic>(ob => { if (!this.context.Gatt.SetCharacteristicNotification(this.native, enable)) { throw new BleException("Failed to set characteristic notification value"); } IDisposable?sub = null; var descriptor = this.native.GetDescriptor(NotifyDescriptorId); if (descriptor == null) { throw new ArgumentException("Notification descriptor not found"); } var wrap = new GattDescriptor(this, this.context, descriptor); var bytes = enable ? this.GetNotifyDescriptorBytes(useIndicationsIfAvailable) : BluetoothGattDescriptor.DisableNotificationValue.ToArray(); sub = wrap .WriteInternal(bytes) .Subscribe( _ => { this.IsNotifying = enable; ob.Respond(this); }, ob.OnError ); return(() => sub?.Dispose()); }));
public override IObservable <GattCharacteristicResult> Write(byte[] value, bool withResponse = true) => this.context.Invoke(Observable.Create <GattCharacteristicResult>((Func <IObserver <GattCharacteristicResult>, IDisposable>)(ob => { this.AssertWrite(withResponse); var sub = this.context .Callbacks .CharacteristicWrite .Where(this.NativeEquals) .Subscribe(args => { if (!args.IsSuccessful) { ob.OnError(new BleException($"Failed to write characteristic - {args.Status}")); } else { var writeType = withResponse ? GattCharacteristicResultType.Write : GattCharacteristicResultType.WriteWithoutResponse; ob.Respond(new GattCharacteristicResult(this, value, writeType)); } }); this.context.InvokeOnMainThread(() => { try { this.native.WriteType = withResponse ? GattWriteType.Default : GattWriteType.NoResponse; var authSignedWrite = this.native.Properties.HasFlag(GattProperty.SignedWrite) && this.context.NativeDevice.BondState == Bond.Bonded; if (authSignedWrite) { this.native.WriteType |= GattWriteType.Signed; } this.native.SetValue(value); //if (!this.native.SetValue(value)) //ob.OnError(new BleException("Failed to set characteristic value")); //else if (!this.context.Gatt.WriteCharacteristic(this.native)) if (!this.context.Gatt?.WriteCharacteristic(this.native) ?? false) { ob.OnError(new BleException("Failed to write to characteristic")); } } catch (Exception ex) { ob.OnError(ex); } }); return(sub); })));
public override IObservable <GattCharacteristicResult> Read() => this.context.Invoke(Observable.Create <GattCharacteristicResult>((Func <IObserver <GattCharacteristicResult>, IDisposable>)(ob => { this.AssertRead(); var sub = this.context .Callbacks .CharacteristicRead .Where(this.NativeEquals) .Subscribe(args => { if (!args.IsSuccessful) { ob.OnError(new BleException($"Failed to read characteristic - {args.Status}")); } else { var value = args.Characteristic.GetValue(); var result = new GattCharacteristicResult(this, value, GattCharacteristicResultType.Read); ob.Respond(result); } }); this.context.InvokeOnMainThread(() => { try { if (!this.context.Gatt?.ReadCharacteristic(this.native) ?? false) { throw new BleException("Failed to read characteristic"); } } catch (Exception ex) { ob.OnError(ex); } }); return(sub); })));
public override IObservable <CharacteristicResult> Write(byte[] value) => this.context.Lock(Observable.Create <CharacteristicResult>(async ob => { this.AssertWrite(false); Log.Debug("Characteristic", "past write gate"); var sub = this.context .Callbacks .CharacteristicWrite .Where(this.NativeEquals) .Subscribe(args => { Log.Debug("Characteristic", "write vent - " + args.Characteristic.Uuid); if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to write characteristic - {args.Status}")); } else { this.Value = value; var result = new CharacteristicResult(this, CharacteristicEvent.Write, this.Value); ob.Respond(result); this.WriteSubject.OnNext(result); } }); if (this.Properties.HasFlag(CharacteristicProperties.Write)) { Log.Debug("Characteristic", "Hooking for write response - " + this.Uuid); await this.RawWriteWithResponse(value); } else { Log.Debug("Characteristic", "Write with No Response - " + this.Uuid); await this.RawWriteNoResponse(ob, value); } return(sub); }));
public override IObservable <CharacteristicResult> Read() => this.context.Lock(Observable.Create <CharacteristicResult>(async ob => { this.AssertRead(); var sub = this.context .Callbacks .CharacteristicRead .Where(this.NativeEquals) .Subscribe(args => { if (!args.IsSuccessful) { ob.OnError(new ArgumentException($"Failed to read characteristic - {args.Status}")); } else { this.Value = args.Characteristic.GetValue(); var result = new CharacteristicResult(this, CharacteristicEvent.Read, this.Value); ob.Respond(result); this.ReadSubject.OnNext(result); } }); await this.context.Marshall(() => { try { if (!this.context.Gatt.ReadCharacteristic(this.native)) { ob.OnError(new Exception($"Failed to read characteristic.")); } } catch (Exception ex) { ob.OnError(ex); } }); return(sub); }));