private async Task <(ProcedureCompletedEventArgs, AttributeValueEventArgs)> ReadByHandle(byte connection, ushort attributeHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Read device characteristic, Connection={connection}, AttributeHandle={attributeHandle}"); var taskCompletionSource = new TaskCompletionSource <(ProcedureCompletedEventArgs, AttributeValueEventArgs)>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); void OnAttributeValue(object sender, AttributeValueEventArgs e) { if (e.connection == connection && e.atthandle == attributeHandle) { taskCompletionSource.SetResult((null, new AttributeValueEventArgs(e.connection, e.atthandle, e.type, e.value))); } } try { BgLib.BLEEventATTClientAttributeValue += OnAttributeValue; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadByHandle(connection, attributeHandle)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventATTClientAttributeValue -= OnAttributeValue; } } }
public async Task <ProcedureCompletedEventArgs> ExecuteAsync(byte connection, ushort attributeHandle, byte[] value, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Write device characteristic, Connection={connection}, AttributeHandle={attributeHandle}, Value={value.ToHexString()}"); var taskCompletionSource = new TaskCompletionSource <ProcedureCompletedEventArgs>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e) { if (e.connection == connection && e.chrhandle == attributeHandle) { taskCompletionSource.SetResult(e); } } try { BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientAttributeWrite(connection, attributeHandle, value)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted; } } }
private async Task <(ProcedureCompletedEventArgs, AttributeValueEventArgs)> ReadLong(byte connection, ushort attributeHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Read long device characteristic, Connection={connection}, AttributeHandle={attributeHandle}"); var taskCompletionSource = new TaskCompletionSource <(ProcedureCompletedEventArgs, AttributeValueEventArgs)>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); AttributeValueEventArgs attributeValueEventArgs = null; var attributeValueBuffer = new List <byte>(); void OnAttributeValue(object sender, AttributeValueEventArgs e) { if (e.connection == connection && e.atthandle == attributeHandle) { attributeValueEventArgs = e; attributeValueBuffer.AddRange(e.value); } } void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e) { if (e.connection == connection && e.chrhandle == attributeHandle) { if (attributeValueEventArgs != null) { taskCompletionSource.SetResult((e, new AttributeValueEventArgs(attributeValueEventArgs.connection, attributeValueEventArgs.atthandle, attributeValueEventArgs.type, attributeValueBuffer.ToArray()))); } else { taskCompletionSource.SetException(new Exception("Didn't receive any attribute values")); } } } try { BgLib.BLEEventATTClientAttributeValue += OnAttributeValue; BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadLong(connection, attributeHandle)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventATTClientAttributeValue -= OnAttributeValue; BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted; } } }
public Task ExecuteAsync(byte connection) { Logger?.LogDebug($"Disconnect from device, Connection={connection}"); var disconnect = BgLib.BLECommandConnectionDisconnect(connection); BgLib.SendCommand(BleModuleConnection.SerialPort, disconnect); return(Task.FromResult(0)); }
public async Task <(List <BleCharacteristic>, List <BleAttribute>)> ExecuteAsync(byte connection, ushort startHandle, ushort endHandle, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Find device characteristics, Connection={connection}, StartHandle={startHandle}, EndHandle={endHandle}"); var taskCompletionSource = new TaskCompletionSource <(List <BleCharacteristic>, List <BleAttribute>)>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); var attributes = new List <BleAttribute>(); void OnFindInformationFound(object sender, FindInformationFoundEventArgs e) { if (e.connection == connection) { attributes.Add(new BleAttribute(e.connection, e.uuid, e.chrhandle)); } } void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e) { if (e.connection == connection) { if (attributes.Any()) { var characteristics = ConvertAttributesToCharacteristics(attributes); taskCompletionSource.SetResult((characteristics, attributes)); } else { taskCompletionSource.SetException(new Exception("Couldn't find any characteristics")); } } } try { BgLib.BLEEventATTClientFindInformationFound += OnFindInformationFound; BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientFindInformation(connection, startHandle, endHandle)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventATTClientFindInformationFound -= OnFindInformationFound; BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted; } } }
public async Task <List <BleService> > ExecuteAsync(byte connection, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Find device services, Connection={connection}"); var taskCompletionSource = new TaskCompletionSource <List <BleService> >(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); var services = new List <BleService>(); void OnGroupFound(object sender, GroupFoundEventArgs e) { if (e.connection == connection) { services.Add(new BleService(e.uuid, e.start, e.end)); } } void OnProcedureCompleted(object sender, ProcedureCompletedEventArgs e) { if (e.connection == connection) { if (services.Any()) { taskCompletionSource.SetResult(services); } else { taskCompletionSource.SetException(new Exception("Couldn't find any services")); } } } try { BgLib.BLEEventATTClientGroupFound += OnGroupFound; BgLib.BLEEventATTClientProcedureCompleted += OnProcedureCompleted; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandATTClientReadByGroupType(connection, GattMinHandle, GattMaxHandle, (byte[])GattServiceTypePrimary)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventATTClientGroupFound -= OnGroupFound; BgLib.BLEEventATTClientProcedureCompleted -= OnProcedureCompleted; } } }
public async Task <ScanResponseEventArgs> ExecuteAsync(ushort manufacturerId, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Discover device by Manufacturer ID {manufacturerId}"); var taskCompletionSource = new TaskCompletionSource <ScanResponseEventArgs>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); void OnScanResponse(object sender, ScanResponseEventArgs e) { var advertisementData = BleAdvertisingDataParser.Parse(e.data); var manufacturerAdvertisementData = advertisementData.SingleOrDefault(x => x.Type == BleAdvertisingDataType.ManufacturerSpecificData); if (manufacturerAdvertisementData?.GetManufacturerId() == manufacturerId) { taskCompletionSource.SetResult(e); } } try { BgLib.BLEEventGAPScanResponse += OnScanResponse; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPSetScanParameters(0xC8, 0xC8, 1)); BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPDiscover(1)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPEndProcedure()); BgLib.BLEEventGAPScanResponse -= OnScanResponse; } } }
public async Task <ScanResponseEventArgs> ExecuteAsync(byte[] serviceUuid, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Discover device by service Uuid {serviceUuid.ToHexString()}"); var taskCompletionSource = new TaskCompletionSource <ScanResponseEventArgs>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); void OnScanResponse(object sender, ScanResponseEventArgs e) { var advertisementData = BleAdvertisingDataParser.Parse(e.data); if (advertisementData.Where(x => ServiceUuidAdvertisements.Contains(x.Type)).Any(x => x.Data.SequenceEqual(serviceUuid))) { taskCompletionSource.SetResult(e); } } try { BgLib.BLEEventGAPScanResponse += OnScanResponse; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPSetScanParameters(0xC8, 0xC8, 1)); BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPDiscover(1)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPEndProcedure()); BgLib.BLEEventGAPScanResponse -= OnScanResponse; } } }
public async Task <StatusEventArgs> ExecuteAsync(byte[] address, BleAddressType addressType, CancellationToken cancellationToken, int timeout = DefaultTimeout) { Logger?.LogDebug($"Connect to device, Address={address.ToHexString()}, AddressType={addressType}"); var taskCompletionSource = new TaskCompletionSource <StatusEventArgs>(); using (var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken)) { cancellationTokenSource.CancelAfter(timeout); void OnConnectionStatus(object sender, StatusEventArgs e) { if ((e.flags & 0x05) == 0x05) { taskCompletionSource.SetResult(e); } else { taskCompletionSource.SetException(new Exception("Couldn't connect to device")); } } try { BgLib.BLEEventConnectionStatus += OnConnectionStatus; using (cancellationTokenSource.Token.Register(() => taskCompletionSource.SetCanceled(), false)) { BgLib.SendCommand(BleModuleConnection.SerialPort, BgLib.BLECommandGAPConnectDirect((byte[])address, (byte)addressType, 0x20, 0x30, 0x100, 0)); return(await taskCompletionSource.Task.ConfigureAwait(false)); } } finally { BgLib.BLEEventConnectionStatus -= OnConnectionStatus; } } }