protected override Task WriteNativeAsync(Byte[] data) { return(TaskBuilder.FromEvent <Boolean, EventHandler <DescriptorCallbackEventArgs>, EventHandler>( () => this.InternalWrite(data), (complete, reject) => (sender, args) => { if (args.Descriptor.Uuid != this._nativeDescriptor.Uuid) { return; } if (args.Exception != null) { reject(args.Exception); } else { complete(true); } }, handler => this._gattCallback.DescriptorValueWritten += handler, handler => this._gattCallback.DescriptorValueWritten -= handler, reject => (sender, args) => { reject(new Exception( $"Device '{this.Characteristic.Service.Device.Id}' disconnected while writing descriptor with {this.Id}.")); }, handler => this._gattCallback.ConnectionInterrupted += handler, handler => this._gattCallback.ConnectionInterrupted -= handler)); }
public static async Task <IDevice> DiscoverDeviceAsync(this IAdapter adapter, Func <IDevice, bool> deviceFilter, CancellationToken cancellationToken = default) { var device = adapter.DiscoveredDevices.FirstOrDefault(deviceFilter); if (device != null) { return(device); } if (adapter.IsScanning) { await adapter.StopScanningForDevicesAsync(); } return(await TaskBuilder.FromEvent <IDevice, EventHandler <DeviceEventArgs>, EventHandler>( execute : () => adapter.StartScanningForDevicesAsync(deviceFilter, cancellationToken), getCompleteHandler : (complete, reject) => ((sender, args) => { complete(args.Device); adapter.StopScanningForDevicesAsync(); }), subscribeComplete : handler => adapter.DeviceDiscovered += handler, unsubscribeComplete : handler => adapter.DeviceDiscovered -= handler, getRejectHandler : reject => ((sender, args) => { reject(new DeviceDiscoverException()); }), subscribeReject : handler => adapter.ScanTimeoutElapsed += handler, unsubscribeReject : handler => adapter.ScanTimeoutElapsed -= handler, token : cancellationToken)); }
protected override Task <IEnumerable <IService> > GetServicesNativeAsync() { return(TaskBuilder.FromEvent <IEnumerable <IService>, EventHandler <NSErrorEventArgs> >( execute: () => _nativeDevice.DiscoverServices(), getCompleteHandler: (complete, reject) => (sender, args) => { // If args.Error was not null then the Service might be null if (args.Error != null) { reject(new Exception($"Error while discovering services {args.Error.LocalizedDescription}")); } else if (_nativeDevice.Services == null) { // No service discovered. reject(new Exception($"Error while discovering services: returned list is null")); } else { var services = _nativeDevice.Services .Select(nativeService => new Service(nativeService, this)) .Cast <IService>().ToList(); complete(services); } }, subscribeComplete: handler => _nativeDevice.DiscoveredService += handler, unsubscribeComplete: handler => _nativeDevice.DiscoveredService -= handler)); }
private Task <bool> UpdateRssiNativeAsync() { return(TaskBuilder.FromEvent <bool, EventHandler <CBRssiEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( execute: () => NativeDevice.ReadRSSI(), getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Error != null) { reject(new Exception($"Error while reading rssi services {args.Error.LocalizedDescription}")); } else { Rssi = args.Rssi?.Int32Value ?? 0; complete(true); } }, subscribeComplete: handler => NativeDevice.RssiRead += handler, unsubscribeComplete: handler => NativeDevice.RssiRead -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Peripheral.Identifier == NativeDevice.Identifier) { reject(new Exception($"Device {Name} disconnected while reading RSSI.")); } }), subscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral += handler, unsubscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral -= handler)); }
public override async Task <Boolean> UpdateRssiAsync() { if (this._gatt == null || this._gattCallback == null) { Trace.Message( "You can't read the RSSI value for disconnected devices except on discovery on Android. Device is {0}", this.State); return(false); } return(await TaskBuilder.FromEvent <Boolean, EventHandler <RssiReadCallbackEventArgs>, EventHandler>( () => this._gatt.ReadRemoteRssi(), (complete, reject) => (sender, args) => { if (args.Error == null) { Trace.Message("Read RSSI for {0} {1}: {2}", this.Id, this.Name, args.Rssi); this.Rssi = args.Rssi; complete(true); } else { Trace.Message($"Failed to read RSSI for device {this.Id}-{this.Name}. {args.Error.Message}"); complete(false); } }, handler => this._gattCallback.RemoteRssiRead += handler, handler => this._gattCallback.RemoteRssiRead -= handler, reject => (sender, args) => { reject(new Exception($"Device {this.Name} disconnected while updating rssi.")); }, handler => this._gattCallback.ConnectionInterrupted += handler, handler => this._gattCallback.ConnectionInterrupted -= handler)); }
protected override Task <bool> WriteNativeAsync(byte[] data) { Task <bool> task; if (CharacteristicWriteType == CBCharacteristicWriteType.WithResponse) { task = TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs> >( execute: () => { }, getCompleteHandler: complete => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } complete(args.Error == null); }, subscribeComplete: handler => _parentDevice.WroteCharacteristicValue += handler, unsubscribeComplete: handler => _parentDevice.WroteCharacteristicValue -= handler); } else { task = Task.FromResult(true); } var nsdata = NSData.FromArray(data); _parentDevice.WriteValue(nsdata, _nativeCharacteristic, CharacteristicWriteType); return(task); }
protected override Task WriteNativeAsync(byte[] data) { return(TaskBuilder.FromEvent <bool, EventHandler <DescriptorCallbackEventArgs>, EventHandler>( execute: () => InternalWrite(data), getCompleteHandler: (complete, reject) => ((sender, args) => { if (args.Descriptor.Uuid != _nativeDescriptor.Uuid) { return; } if (args.Exception != null) { reject(args.Exception); } else { complete(true); } }), subscribeComplete: handler => _gattCallback.DescriptorValueWritten += handler, unsubscribeComplete: handler => _gattCallback.DescriptorValueWritten -= handler, getRejectHandler: reject => ((sender, args) => { reject(new Exception($"Device '{Characteristic.Service.Device.Id}' disconnected while writing descriptor with {Id}.")); }), subscribeReject: handler => _gattCallback.ConnectionInterrupted += handler, unsubscribeReject: handler => _gattCallback.ConnectionInterrupted -= handler)); }
public Task DisconnectDeviceAsync(IDevice device) { if (!ConnectedDevices.Contains(device)) { Trace.Message("Disconnect async: device {0} not in the list of connected devices.", device.Name); return(Task.FromResult(false)); } return(TaskBuilder.FromEvent <bool, EventHandler <DeviceEventArgs>, EventHandler <DeviceErrorEventArgs> >( execute: () => DisconnectDeviceNative(device), getCompleteHandler: (complete, reject) => ((sender, args) => { if (args.Device.Id == device.Id) { Trace.Message("DisconnectAsync Disconnected: {0} {1}", args.Device.Id, args.Device.Name); complete(true); } }), subscribeComplete: handler => DeviceDisconnected += handler, unsubscribeComplete: handler => DeviceDisconnected -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Device.Id == device.Id) { Trace.Message("DisconnectAsync", "Disconnect Error: {0} {1}", args.Device?.Id, args.Device?.Name); reject(new Exception("Disconnect operation exception")); } }), subscribeReject: handler => DeviceConnectionError += handler, unsubscribeReject: handler => DeviceConnectionError -= handler)); }
protected override Task StopUpdatesNativeAsync() { _parentDevice.UpdatedCharacterteristicValue -= UpdatedNotify; // JTS Added this if-statement. We found that on iOS, when you turn off Bluetooth during a connection it gets the characteristic into a stale state // and the IsNotifying property remains True. Then attempting to reset it does not trigger the callback thus resulting in a deadlock. if (_parentDevice.State == CBPeripheralState.Disconnected) { return(Task.FromResult(true)); } return(TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs> >( execute: () => _parentDevice.SetNotifyValue(false, _nativeCharacteristic), getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Stop Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StopUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, subscribeComplete: handler => _parentDevice.UpdatedNotificationState += handler, unsubscribeComplete: handler => _parentDevice.UpdatedNotificationState -= handler)); }
public override async Task <bool> UpdateRssiAsync() { if (_gatt == null || _gattCallback == null) { Trace.Message("You can't read the RSSI value for disconnected devices except on discovery on Android. Device is {0}", State); return(false); } return(await TaskBuilder.FromEvent <bool, EventHandler <RssiReadCallbackEventArgs>, EventHandler>( execute : () => _gatt.ReadRemoteRssi(), getCompleteHandler : (complete, reject) => ((sender, args) => { if (args.Error == null) { Trace.Message("Read RSSI for {0} {1}: {2}", Id, Name, args.Rssi); Rssi = args.Rssi; complete(true); } else { Trace.Message($"Failed to read RSSI for device {Id}-{Name}. {args.Error.Message}"); complete(false); } }), subscribeComplete : handler => _gattCallback.RemoteRssiRead += handler, unsubscribeComplete : handler => _gattCallback.RemoteRssiRead -= handler, getRejectHandler : reject => ((sender, args) => { reject(new Exception($"Device {Name} disconnected while updating rssi.")); }), subscribeReject : handler => _gattCallback.ConnectionInterrupted += handler, unsubscribeReject : handler => _gattCallback.ConnectionInterrupted -= handler)); }
protected override Task <IList <ICharacteristic> > GetCharacteristicsNativeAsync() { return(TaskBuilder.FromEvent <IList <ICharacteristic>, EventHandler <CBServiceEventArgs> >( execute: () => _device.DiscoverCharacteristics(_service), getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Error != null) { reject(new Exception($"Discover characteristics error: {args.Error.Description}")); } else if (args.Service?.Characteristics == null) { reject(new Exception($"Discover characteristics error: returned list is null")); } else { var characteristics = args.Service.Characteristics .Select(characteristic => new Characteristic(characteristic, _device, this)) .Cast <ICharacteristic>().ToList(); complete(characteristics); } }, subscribeComplete: handler => _device.DiscoveredCharacteristic += handler, unsubscribeComplete: handler => _device.DiscoveredCharacteristic -= handler)); }
protected override Task StopUpdatesNativeAsync() { _parentDevice.UpdatedCharacterteristicValue -= UpdatedNotify; return(TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs> >( execute: () => _parentDevice.SetNotifyValue(false, _nativeCharacteristic), getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Stop Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StopUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, subscribeComplete: handler => _parentDevice.UpdatedNotificationState += handler, unsubscribeComplete: handler => _parentDevice.UpdatedNotificationState -= handler)); }
protected override Task StartUpdatesNativeAsync() { _parentDevice.UpdatedCharacterteristicValue -= UpdatedNotify; _parentDevice.UpdatedCharacterteristicValue += UpdatedNotify; //https://developer.apple.com/reference/corebluetooth/cbperipheral/1518949-setnotifyvalue return(TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs> >( execute: () => _parentDevice.SetNotifyValue(true, _nativeCharacteristic), getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Start Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StartUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, subscribeComplete: handler => _parentDevice.UpdatedNotificationState += handler, unsubscribeComplete: handler => _parentDevice.UpdatedNotificationState -= handler)); }
public static async Task <IDevice> DiscoverDeviceAsync(this IAdapter adapter, Func <IDevice, Boolean> deviceFilter, CancellationToken cancellationToken = default(CancellationToken)) { IDevice device = adapter.DiscoveredDevices.FirstOrDefault(deviceFilter); if (device != null) { return(device); } if (adapter.IsScanning) { await adapter.StopScanningForDevicesAsync(); } return(await TaskBuilder.FromEvent <IDevice, EventHandler <DeviceEventArgs>, EventHandler>( () => adapter.StartScanningForDevicesAsync(deviceFilter, cancellationToken), (complete, reject) => (sender, args) => { complete(args.Device); adapter.StopScanningForDevicesAsync(); }, handler => adapter.DeviceDiscovered += handler, handler => adapter.DeviceDiscovered -= handler, reject => (sender, args) => { reject(new DeviceDiscoverException()); }, handler => adapter.ScanTimeoutElapsed += handler, handler => adapter.ScanTimeoutElapsed -= handler, cancellationToken)); }
protected override async Task <bool> WriteNativeAsync(byte[] data, CharacteristicWriteType writeType) { _nativeCharacteristic.WriteType = writeType.ToNative(); if (writeType == CharacteristicWriteType.WithoutResponse) { return(InternalWrite(data)); } return(await TaskBuilder.FromEvent <bool, EventHandler <CharacteristicWriteCallbackEventArgs>, EventHandler>( execute : () => InternalWrite(data), getCompleteHandler : (complete, reject) => ((sender, args) => { if (args.Characteristic.Uuid == _nativeCharacteristic.Uuid) { complete(args.Exception == null); } }), subscribeComplete : handler => _gattCallback.CharacteristicValueWritten += handler, unsubscribeComplete : handler => _gattCallback.CharacteristicValueWritten -= handler, getRejectHandler : reject => ((sender, args) => { reject(new Exception($"Device '{Service.Device.Id}' disconnected while writing characteristic with {Id}.")); }), subscribeReject : handler => _gattCallback.ConnectionInterrupted += handler, unsubscribeReject : handler => _gattCallback.ConnectionInterrupted -= handler)); }
private Task <IReadOnlyList <Service> > GetServicesInternal(CBUUID id = null) { var exception = new Exception($"Device {Name} disconnected while fetching services."); return(TaskBuilder.FromEvent <IReadOnlyList <Service>, EventHandler <NSErrorEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( execute: () => { if (NativeDevice.State != CBPeripheralState.Connected) { throw exception; } if (id != null) { NativeDevice.DiscoverServices(new[] { id }); } else { NativeDevice.DiscoverServices(); } }, getCompleteHandler: (complete, reject) => (sender, args) => { // If args.Error was not null then the Service might be null if (args.Error != null) { reject(new Exception($"Error while discovering services {args.Error.LocalizedDescription}")); } else if (NativeDevice.Services == null) { // No service discovered. reject(new Exception($"Error while discovering services: returned list is null")); } else { var services = NativeDevice.Services .Select(nativeService => new Service(nativeService, this, _bleCentralManagerDelegate)) .Cast <Service>().ToList(); complete(services); } }, subscribeComplete: handler => NativeDevice.DiscoveredService += handler, unsubscribeComplete: handler => NativeDevice.DiscoveredService -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Peripheral.Identifier == NativeDevice.Identifier) { reject(exception); } }), subscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral += handler, unsubscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral -= handler)); }
protected override Task <Boolean> WriteNativeAsync(Byte[] data, CharacteristicWriteType writeType) { Exception exception = new Exception( $"Device {this.Service.Device.Id} disconnected while writing characteristic with {this.Id}."); Task <Boolean> task; if (writeType.ToNative() == CBCharacteristicWriteType.WithResponse) { task = TaskBuilder .FromEvent <Boolean, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._parentDevice.State != CBPeripheralState.Connected) { throw exception; } }, (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != this._nativeCharacteristic.UUID) { return; } complete(args.Error == null); }, handler => this._parentDevice.WroteCharacteristicValue += handler, handler => this._parentDevice.WroteCharacteristicValue -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._parentDevice.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler); } else { task = Task.FromResult(true); } NSData nsdata = NSData.FromArray(data); this._parentDevice.WriteValue(nsdata, this._nativeCharacteristic, writeType.ToNative()); return(task); }
protected override Task StartUpdatesNativeAsync() { Exception exception = new Exception( $"Device {this.Service.Device.Id} disconnected while starting updates for characteristic with {this.Id}."); this._parentDevice.UpdatedCharacterteristicValue -= this.UpdatedNotify; this._parentDevice.UpdatedCharacterteristicValue += this.UpdatedNotify; //https://developer.apple.com/reference/corebluetooth/cbperipheral/1518949-setnotifyvalue return(TaskBuilder .FromEvent <Boolean, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._parentDevice.State != CBPeripheralState.Connected) { throw exception; } this._parentDevice.SetNotifyValue(true, this._nativeCharacteristic); }, (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != this._nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Start Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StartUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, handler => this._parentDevice.UpdatedNotificationState += handler, handler => this._parentDevice.UpdatedNotificationState -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._parentDevice.Identifier) { reject(new Exception( $"Device {this.Service.Device.Id} disconnected while starting updates for characteristic with {this.Id}.")); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
protected override Task <IList <ICharacteristic> > GetCharacteristicsNativeAsync() { Exception exception = new Exception( $"Device '{this.Device.Id}' disconnected while fetching characteristics for service with {this.Id}."); return(TaskBuilder .FromEvent <IList <ICharacteristic>, EventHandler <CBServiceEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._device.State != CBPeripheralState.Connected) { throw exception; } this._device.DiscoverCharacteristics(this._service); }, (complete, reject) => (sender, args) => { if (args.Error != null) { reject(new Exception($"Discover characteristics error: {args.Error.Description}")); } else if (args.Service?.Characteristics == null) { reject(new Exception("Discover characteristics error: returned list is null")); } else { List <ICharacteristic> characteristics = args.Service.Characteristics .Select(characteristic => new Characteristic(characteristic, this._device, this, this._centralManager)) .Cast <ICharacteristic>().ToList(); complete(characteristics); } }, handler => this._device.DiscoveredCharacteristic += handler, handler => this._device.DiscoveredCharacteristic -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._device.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
protected override Task <IEnumerable <IService> > GetServicesNativeAsync() { Exception exception = new Exception($"Device {this.Name} disconnected while fetching services."); return(TaskBuilder .FromEvent <IEnumerable <IService>, EventHandler <NSErrorEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._nativeDevice.State != CBPeripheralState.Connected) { throw exception; } this._nativeDevice.DiscoverServices(); }, (complete, reject) => (sender, args) => { // If args.Error was not null then the Service might be null if (args.Error != null) { reject(new Exception( $"Error while discovering services {args.Error.LocalizedDescription}")); } else if (this._nativeDevice.Services == null) { // No service discovered. reject(new Exception("Error while discovering services: returned list is null")); } else { List <IService> services = this._nativeDevice.Services .Select(nativeService => new Service(nativeService, this, this._centralManager)) .Cast <IService>().ToList(); complete(services); } }, handler => this._nativeDevice.DiscoveredService += handler, handler => this._nativeDevice.DiscoveredService -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._nativeDevice.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
protected override async Task <byte[]> ReadNativeAsync() { return(await TaskBuilder.FromEvent <byte[], EventHandler <DescriptorCallbackEventArgs> >( execute : ReadInternal, getCompleteHandler : (complete, reject) => ((sender, args) => { if (args.Descriptor.Uuid == _nativeDescriptor.Uuid) { complete(args.Descriptor.GetValue()); } }), subscribeComplete : handler => _gattCallback.DescriptorValueRead += handler, unsubscribeComplete : handler => _gattCallback.DescriptorValueRead -= handler )); }
protected override Task StartUpdatesNativeAsync(CancellationToken cancellationToken = default) { var exception = new Exception($"Device {Service.Device.Id} disconnected while starting updates for characteristic with {Id}."); _parentDevice.UpdatedCharacterteristicValue -= UpdatedNotify; _parentDevice.UpdatedCharacterteristicValue += UpdatedNotify; //https://developer.apple.com/reference/corebluetooth/cbperipheral/1518949-setnotifyvalue return(TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( execute: () => { if (_parentDevice.State != CBPeripheralState.Connected) { throw exception; } _parentDevice.SetNotifyValue(true, _nativeCharacteristic); }, getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Start Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StartUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, subscribeComplete: handler => _parentDevice.UpdatedNotificationState += handler, unsubscribeComplete: handler => _parentDevice.UpdatedNotificationState -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Peripheral.Identifier == _parentDevice.Identifier) { reject(new Exception($"Device {Service.Device.Id} disconnected while starting updates for characteristic with {Id}.")); } }), subscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral += handler, unsubscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral -= handler, token: cancellationToken)); }
protected override Task <bool> WriteNativeAsync(byte[] data, CharacteristicWriteType writeType) { var exception = new Exception($"Device {Service.Device.Id} disconnected while writing characteristic with {Id}."); Task <bool> task; if (writeType.ToNative() == CBCharacteristicWriteType.WithResponse) { task = TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( execute: () => { if (_parentDevice.State != CBPeripheralState.Connected) { throw exception; } }, getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } complete(args.Error == null); }, subscribeComplete: handler => _parentDevice.WroteCharacteristicValue += handler, unsubscribeComplete: handler => _parentDevice.WroteCharacteristicValue -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Peripheral.Identifier == _parentDevice.Identifier) { reject(exception); } }), subscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral += handler, unsubscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral -= handler); } else { task = Task.FromResult(true); } var nsdata = NSData.FromArray(data); _parentDevice.WriteValue(nsdata, _nativeCharacteristic, writeType.ToNative()); return(task); }
protected override Task <IList <IDescriptor> > GetDescriptorsNativeAsync() { Exception exception = new Exception( $"Device '{this.Service.Device.Id}' disconnected while fetching descriptors for characteristic with {this.Id}."); return(TaskBuilder .FromEvent <IList <IDescriptor>, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._parentDevice.State != CBPeripheralState.Connected) { throw exception; } this._parentDevice.DiscoverDescriptors(this._nativeCharacteristic); }, (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != this._nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Discover descriptors error: {args.Error.Description}")); } else { complete(args.Characteristic.Descriptors.Select(descriptor => new Descriptor(descriptor, this._parentDevice, this, this._centralManager)) .Cast <IDescriptor>().ToList()); } }, handler => this._parentDevice.DiscoveredDescriptor += handler, handler => this._parentDevice.DiscoveredDescriptor -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._parentDevice.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
protected override async Task <IEnumerable <IService> > GetServicesNativeAsync() { if (_gattCallback == null || _gatt == null) { return(Enumerable.Empty <IService>()); } return(await TaskBuilder.FromEvent <IEnumerable <IService>, EventHandler <ServicesDiscoveredCallbackEventArgs> >( execute : () => _gatt.DiscoverServices(), getCompleteHandler : (complete, reject) => ((sender, args) => { complete(_gatt.Services.Select(service => new Service(service, _gatt, _gattCallback, this))); }), subscribeComplete : handler => _gattCallback.ServicesDiscovered += handler, unsubscribeComplete : handler => _gattCallback.ServicesDiscovered -= handler)); }
protected override async Task <bool> WriteNativeAsync(byte[] data, CharacteristicWriteType writeType) { _nativeCharacteristic.WriteType = writeType.ToNative(); return(await TaskBuilder.FromEvent <bool, EventHandler <CharacteristicWriteCallbackEventArgs> >( execute : () => InternalWrite(data), getCompleteHandler : (complete, reject) => ((sender, args) => { if (args.Characteristic.Uuid == _nativeCharacteristic.Uuid) { complete(args.Exception == null); } }), subscribeComplete : handler => _gattCallback.CharacteristicValueWritten += handler, unsubscribeComplete : handler => _gattCallback.CharacteristicValueWritten -= handler )); }
protected override Task <Byte[]> ReadNativeAsync() { Exception exception = new Exception( $"Device '{this.Service.Device.Id}' disconnected while reading characteristic with {this.Id}."); return(TaskBuilder .FromEvent <Byte[], EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._parentDevice.State != CBPeripheralState.Connected) { throw exception; } this._parentDevice.ReadValue(this._nativeCharacteristic); }, (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != this._nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new CharacteristicReadException($"Read async error: {args.Error.Description}")); } else { Trace.Message($"Read characterteristic value: {this.Value?.ToHexString()}"); complete(this.Value); } }, handler => this._parentDevice.UpdatedCharacterteristicValue += handler, handler => this._parentDevice.UpdatedCharacterteristicValue -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._parentDevice.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
public async Task ConnectToDeviceAsync(IDevice device, bool autoconnect = false, CancellationToken cancellationToken = default(CancellationToken)) { if (device == null) { throw new ArgumentNullException(nameof(device)); } if (device.State == DeviceState.Connected) { return; } using (var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { await TaskBuilder.FromEvent <bool, EventHandler <DeviceEventArgs>, EventHandler <DeviceErrorEventArgs> >( execute : () => { ConnectToDeviceNativeAsync(device, autoconnect, cts.Token); }, getCompleteHandler : (complete, reject) => (sender, args) => { if (args.Device.Id == device.Id) { Trace.Message("ConnectToDeviceAsync Connected: {0} {1}", args.Device.Id, args.Device.Name); complete(true); } }, subscribeComplete : handler => DeviceConnected += handler, unsubscribeComplete : handler => DeviceConnected -= handler, getRejectHandler : reject => (sender, args) => { if (args.Device?.Id == device.Id) { Trace.Message("ConnectAsync Error: {0} {1}", args.Device?.Id, args.Device?.Name); reject(new DeviceConnectionException((Guid)args.Device?.Id, args.Device?.Name, args.ErrorMessage)); } }, subscribeReject : handler => DeviceConnectionError += handler, unsubscribeReject : handler => DeviceConnectionError -= handler, token : cts.Token); } }
protected override Task WriteNativeAsync(Byte[] data) { Exception exception = new Exception( $"Device '{this.Characteristic.Service.Device.Id}' disconnected while writing descriptor with {this.Id}."); return(TaskBuilder .FromEvent <Boolean, EventHandler <CBDescriptorEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( () => { if (this._parentDevice.State != CBPeripheralState.Connected) { throw exception; } this._parentDevice.WriteValue(NSData.FromArray(data), this._nativeDescriptor); }, (complete, reject) => (sender, args) => { if (args.Descriptor.UUID != this._nativeDescriptor.UUID) { return; } if (args.Error != null) { reject(new Exception(args.Error.Description)); } else { complete(true); } }, handler => this._parentDevice.WroteDescriptorValue += handler, handler => this._parentDevice.WroteDescriptorValue -= handler, reject => (sender, args) => { if (args.Peripheral.Identifier == this._parentDevice.Identifier) { reject(exception); } }, handler => this._centralManager.DisconnectedPeripheral += handler, handler => this._centralManager.DisconnectedPeripheral -= handler)); }
protected override Task StopUpdatesNativeAsync() { var exception = new Exception($"Device {Service.Device.Id} disconnected while stopping updates for characteristic with {Id}."); _parentDevice.UpdatedCharacterteristicValue -= UpdatedNotify; return(TaskBuilder.FromEvent <bool, EventHandler <CBCharacteristicEventArgs>, EventHandler <CBPeripheralErrorEventArgs> >( execute: () => { if (_parentDevice.State != CBPeripheralState.Connected) { throw exception; } _parentDevice.SetNotifyValue(false, _nativeCharacteristic); }, getCompleteHandler: (complete, reject) => (sender, args) => { if (args.Characteristic.UUID != _nativeCharacteristic.UUID) { return; } if (args.Error != null) { reject(new Exception($"Stop Notifications: Error {args.Error.Description}")); } else { Trace.Message($"StopUpdates IsNotifying: {args.Characteristic.IsNotifying}"); complete(args.Characteristic.IsNotifying); } }, subscribeComplete: handler => _parentDevice.UpdatedNotificationState += handler, unsubscribeComplete: handler => _parentDevice.UpdatedNotificationState -= handler, getRejectHandler: reject => ((sender, args) => { if (args.Peripheral.Identifier == _parentDevice.Identifier) { reject(exception); } }), subscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral += handler, unsubscribeReject: handler => _bleCentralManagerDelegate.DisconnectedPeripheral -= handler)); }