private async Task <IBleResult <IReadOnlyList <IDevice> > > ExecuteDeviceSearchAsync(IDeviceFilter deviceFilter, bool stopAfterFirstResult, CancellationToken cancellationToken) { IBleResult <IReadOnlyList <IDevice> > result = null; try { await _searchSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { var searchResult = await _bleAdapter.SearchAsync(deviceFilter, stopAfterFirstResult, _executor, _logger, cancellationToken); result = BleResult.Success(searchResult); } finally { _searchSemaphore.Release(); } } catch (OperationCanceledException) { } catch (Exception e) { result = BleResult.Failure <IReadOnlyList <IDevice> >(e); } return(result); }
internal static async Task <IBleResult> ExecuteWithBleAvailabilityCheckAsync(this IBleAvailability bleAvailability, Func <Task <IBleResult> > executionProvider) { IBleResult result; try { switch (bleAvailability.BleState) { case BluetoothState.On: result = await executionProvider.Invoke().ConfigureAwait(false); break; case BluetoothState.Unavailable: result = BleResult.Failure(BleFailure.BleNotAvailable); break; case BluetoothState.Unauthorized: result = BleResult.Failure(BleFailure.NoBluetoothPermissions); break; default: result = BleResult.Failure(BleFailure.BluetoothNotEnabled); break; } } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
private async Task <IBleResult> EnsureDeviceIsFoundAsync(CancellationToken cancellationToken) { IBleResult result; if (IsFound) { result = BleResult.Success(); } else { var searchResult = await _bleInfrastructure.SearchManager.SearchForFirstDeviceAsync(_deviceSearchFilter, cancellationToken).ConfigureAwait(false); if (searchResult.IsOperationCompleted) { _device = searchResult.Data; result = _device != null?BleResult.Success() : BleResult.Failure(BleFailure.DeviceNotFound); } else { result = BleResult.Failure(BleFailure.DeviceNotFound, searchResult); } } return(result); }
public async Task <IBleResult> WriteAsync(IWriterBehavior <TIn> writer, TOut value, CancellationToken cancellationToken) { IBleResult result = null; try { using (var rawDataSequenceEnumerator = _valueConverter.Invoke(value).GetEnumerator()) { while (rawDataSequenceEnumerator.MoveNext() && result == null) { cancellationToken.ThrowIfCancellationRequested(); var writeChunkResult = await writer.WriteAsync(rawDataSequenceEnumerator.Current, cancellationToken).ConfigureAwait(false); if (!writeChunkResult.IsOperationCompleted) { result = writeChunkResult; } } } result = result ?? BleResult.Success(); } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public async Task <IBleResult <TOut> > ReadAsync(IParametrizedReaderBehavior <TIn, TOut> parametrizedReader, TIn parameter, CancellationToken cancellationToken) { IBleResult <TOut> result; try { if (_connector.IsConnected) { result = await parametrizedReader.ReadAsync(parameter, cancellationToken).ConfigureAwait(false); } else { var connectionResult = await _connector.ConnectAsync(cancellationToken); if (connectionResult.IsOperationCompleted) { cancellationToken.ThrowIfCancellationRequested(); result = await parametrizedReader.ReadAsync(parameter, cancellationToken); } else { result = BleResult.Failure <TOut>(BleFailure.DeviceNotConnected, connectionResult); } } } catch (OperationCanceledException) { result = BleResult.Failure <TOut>(BleFailure.OperationCancelled); } return(result); }
internal static IBleResult <T> ExecuteWithBleAvailabilityCheck <T>(this IBleAvailability bleAvailability, Func <IBleResult <T> > executionProvider) { IBleResult <T> result; try { switch (bleAvailability.BleState) { case BluetoothState.On: result = executionProvider.Invoke(); break; case BluetoothState.Unavailable: result = BleResult.Failure <T>(BleFailure.BleNotAvailable); break; case BluetoothState.Unauthorized: result = BleResult.Failure <T>(BleFailure.NoBluetoothPermissions); break; default: result = BleResult.Failure <T>(BleFailure.BluetoothNotEnabled); break; } } catch (Exception e) { result = BleResult.Failure <T>(e); } return(result); }
public override async Task <IBleResult> StartObservingAsync(IObserverBehavior <T> decoratedObserver, CancellationToken cancellationToken) { IBleResult result; try { if (_connector.IsConnected) { result = await decoratedObserver.StartObservingAsync(cancellationToken).ConfigureAwait(false); } else { var connectionResult = await _connector.ConnectAsync(cancellationToken); if (connectionResult.IsOperationCompleted) { cancellationToken.ThrowIfCancellationRequested(); result = await decoratedObserver.StartObservingAsync(cancellationToken); } else { result = BleResult.Failure(BleFailure.DeviceNotConnected, connectionResult); } } } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } return(result); }
private async Task <IBleResult <TValue> > ExecuteSequentiallyAsync <TValue>(Func <Task <IBleResult <TValue> > > executionProvider, CancellationToken cancellationToken) { IBleResult <TValue> result; try { await _operationExecutionSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); try { result = await executionProvider.Invoke(); } finally { _operationExecutionSemaphore.Release(); } } catch (OperationCanceledException) { result = BleResult.Failure <TValue>(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure <TValue>(e); } return(result); }
public Task <IBleResult> TryConnectToDeviceAsync(IDevice device, bool connectWhenAvailable, CancellationToken cancellationToken) { _logger?.Log(LogSender, $"Trying to connect to device [DeviceName={device.Name},GUID={device.Id:D}]"); return(_bleAvailability.ExecuteWithBleAvailabilityCheckAsync(async() => { IBleResult result; _logger?.Log(LogSender, $"Internal connect to device started"); try { var connectParameters = new ConnectParameters(connectWhenAvailable); await _bleAdapter.ConnectToDeviceAsync(device, connectParameters, cancellationToken); result = device.State == DeviceState.Connected ? BleResult.Success() : BleResult.Failure(BleFailure.ConnectNotCompleted); } catch (TimeoutException) { result = BleResult.Failure(BleFailure.OperationTimeout); } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } _logger?.Log(LogSender, $"Internal connect to device completed with result: {result}"); return result; })); }
private async Task <IBleResult> InitializeProtocolAsync(CancellationToken cancellationToken) { IBleResult result; try { var failedResults = new List <IBleResult>(); foreach (var characteristic in _deviceCharacteristics.Values) { cancellationToken.ThrowIfCancellationRequested(); var initializationResult = await characteristic.InitializeAsync(_device, cancellationToken); if (!initializationResult.IsOperationCompleted) { failedResults.Add(initializationResult); } } result = failedResults.Any() ? BleResult.Failure(failedResults.ToArray()) : BleResult.Success(); } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public async Task <IBleResult> WriteAsync(IWriterBehavior <T> writer, T value, CancellationToken cancellationToken) { IBleResult result; try { if (_connector.IsConnected) { result = await writer.WriteAsync(value, cancellationToken).ConfigureAwait(false); } else { var connectionResult = await _connector.ConnectAsync(cancellationToken); if (connectionResult.IsOperationCompleted) { cancellationToken.ThrowIfCancellationRequested(); result = await writer.WriteAsync(value, cancellationToken); } else { result = BleResult.Failure(BleFailure.DeviceNotConnected, connectionResult); } } } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } return(result); }
public Task <IBleResult <IDevice> > SearchForFirstDeviceAsync(IDeviceFilter deviceFilter, CancellationToken cancellationToken) { var foundDevice = GetConnectedDevices(deviceFilter).FirstOrDefault(); return(foundDevice != null ? Task.FromResult(BleResult.Success(foundDevice)) : _bleAvailabilityManager.ExecuteWithBleAvailabilityCheckAsync(async() => { var result = await ExecuteDeviceSearchAsync(deviceFilter, true, cancellationToken).ConfigureAwait(false); return result.Convert(list => list.FirstOrDefault()); })); }
private async Task <IBleResult> ConnectWithPolicyAsync(bool connectWhenAvailable, CancellationToken cancellationToken) { IBleResult result; var stopwatch = new Stopwatch(); stopwatch.Start(); try { var deviceSearchResult = await EnsureDeviceIsFoundAsync(cancellationToken).ConfigureAwait(false); _bleInfrastructure.Logger.Log(LogSender, $"Search completed after {stopwatch.Elapsed}"); if (deviceSearchResult.IsOperationCompleted) { cancellationToken.ThrowIfCancellationRequested(); var deviceConnectedResult = await EnsureDeviceIsConnectedAsync(connectWhenAvailable, cancellationToken); _bleInfrastructure.Logger.Log(LogSender, $"Connection completed after {stopwatch.Elapsed}"); if (deviceConnectedResult.IsOperationCompleted) { cancellationToken.ThrowIfCancellationRequested(); var initializationResult = await InitializeProtocolAsync(cancellationToken); _bleInfrastructure.Logger.Log(LogSender, $"Initialization completed after {stopwatch.Elapsed}"); result = initializationResult.IsOperationCompleted ? BleResult.Success() : BleResult.Failure(BleFailure.DeviceNotInitialized, initializationResult); } else { result = deviceConnectedResult; } } else { result = deviceSearchResult; } } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } finally { stopwatch.Stop(); } return(result); }
public static async Task <IBleResult> WriteAsync <T>(this IWriterBehavior <T> writerBehavior, Func <T> valueProvider, CancellationToken cancellationToken = default) { IBleResult result; try { result = await writerBehavior.WriteAsync(valueProvider.Invoke(), cancellationToken).ConfigureAwait(false); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public static IBleResult <T> TryParseData <T>(this byte[] rawData, Func <byte[], T> parser) { IBleResult <T> result; try { result = BleResult.Success(parser.Invoke(rawData)); } catch (Exception e) { result = BleResult.Failure <T>(BleFailure.DataConversionFailed, e); } return(result); }
public async Task <IBleResult> TryDisconnectAsync() { IBleResult result; if (IsConnected) { result = await _bleInfrastructure.ConnectionManager.TryDisconnectFromDeviceAsync(_device).ConfigureAwait(false); } else { _connectionCancellation?.Cancel(); _connectionCancellation = null; result = BleResult.Success(); } return(result); }
private async Task <IBleResult> EnsureDeviceIsConnectedAsync(bool connectWhenAvailable, CancellationToken cancellationToken) { IBleResult result; if (IsConnected) { result = BleResult.Success(); } else { var connectionResult = await DoConnectToDeviceAsync(connectWhenAvailable, cancellationToken).ConfigureAwait(false); result = connectionResult.IsOperationCompleted ? BleResult.Success() : BleResult.Failure(BleFailure.CannotConnect, connectionResult); } return(result); }
public async Task <IBleResult> InitializeAsync(IDevice device, CancellationToken cancellationToken) { IBleResult result; try { if (_bleCharacteristic != null) { _bleCharacteristic.ValueUpdated -= OnValueUpdated; _bleCharacteristic = null; } var service = await device.GetServiceAsync(_serviceId, cancellationToken).ConfigureAwait(false); if (service != null) { cancellationToken.ThrowIfCancellationRequested(); _bleCharacteristic = await service.GetCharacteristicAsync(_characteristicId); if (_bleCharacteristic != null) { _bleCharacteristic.ValueUpdated += OnValueUpdated; result = BleResult.Success(); } else { throw new CharacteristicNotFoundException(_characteristicId); } } else { throw new ServiceNotFoundException(_serviceId); } } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public async Task <IBleResult> TryDisconnectFromDeviceAsync(IDevice device) { IBleResult result; try { _logger?.Log(LogSender, $"Trying to disconnect to device [DeviceName={device.Name},GUID={device.Id:D}]"); await _bleAdapter.DisconnectDeviceAsync(device).ConfigureAwait(false); result = device.State != DeviceState.Connected ? BleResult.Success() : BleResult.Failure(BleFailure.DisconnectNotCompleted); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
private async Task <IBleResult <TValue> > CheckCharacteristicExistsAsync <TValue>(Guid characteristicId, Func <IBleCharacteristic, Task <IBleResult <TValue> > > executionProvider) { IBleResult <TValue> result; try { var characteristic = GetCharacteristic(characteristicId); result = characteristic != null ? await executionProvider.Invoke(characteristic).ConfigureAwait(false) : BleResult.Failure <TValue>(BleFailure.UnknownCharacteristic); } catch (Exception e) { result = BleResult.Failure <TValue>(e); } return(result); }
internal static async Task <IBleResult> TimeoutBleOperationAsync(this IExecutor executor, Func <CancellationToken, Task <IBleResult> > taskProvider, TimeSpan timeout, CancellationToken cancellationToken = default) { IBleResult result; try { result = await executor.CancelAfterTimeoutAsync(taskProvider, timeout, true, cancellationToken).ConfigureAwait(false); } catch (TimeoutException ex) { result = BleResult.Failure(BleFailure.OperationTimeout, ex); } catch (Exception ex) { result = BleResult.Failure(ex); } return(result); }
public Task <IBleResult> BeginSearchForAllDevicesAsync(IObserver <IDevice> observer, IDeviceFilter deviceFilter, CancellationToken cancellationToken) { return(_bleAvailabilityManager.ExecuteWithBleAvailabilityCheckAsync(async() => { await _searchSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); var searchCompletionObserver = new SearchCompletedObserver(observer, completedSuccessfully => _searchSemaphore.Release()); try { _bleAdapter.Search(searchCompletionObserver, deviceFilter, false, _executor, _logger, cancellationToken); } catch { _searchSemaphore.Release(); throw; } return BleResult.Success(); })); }
private async Task <IBleResult> DoConnectToDeviceAsync(bool connectWhenAvailable, CancellationToken cancellationToken) { IBleResult result; var stopwatch = new Stopwatch(); stopwatch.Start(); try { await _connectionSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false); _bleInfrastructure.Logger.Log(LogSender, $"Semaphore equired after {stopwatch.Elapsed}"); try { _connectionCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken); result = await _bleInfrastructure.ConnectionManager.TryConnectToDeviceAsync(_device, connectWhenAvailable, _connectionCancellation.Token); _bleInfrastructure.Logger.Log(LogSender, $"Connected after {stopwatch.Elapsed}"); } finally { _connectionCancellation = null; _connectionSemaphore.Release(); } } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } finally { stopwatch.Stop(); } return(result); }
public async Task <IBleResult <IReadOnlyList <TBleDevice> > > SearchForDevicesAsync(bool includeConnected, TimeSpan timeout, CancellationToken cancellationToken) { var searchResult = await _bleInfrastructure.Executor.CancelAfterTimeoutAsync( ct => _bleInfrastructure.SearchManager.SearchForAllDevicesAsync(_generalDeviceFilter, ct), timeout, false, cancellationToken).ConfigureAwait(false); if (searchResult.IsOperationCompleted) { var foundDevices = searchResult.Data.Select(GetBleDevice).ToList(); if (includeConnected) { foundDevices.AddRange(_bleInfrastructure.SearchManager.GetConnectedDevices(_generalDeviceFilter).Select(GetBleDevice).ToList()); } return(BleResult.Success <IReadOnlyList <TBleDevice> >(foundDevices)); } else { return(searchResult.Convert <IReadOnlyList <TBleDevice> >()); } }
public async Task <IBleResult> WriteAsync(IWriterBehavior <TIn> writer, TOut value, CancellationToken cancellationToken) { IBleResult result; try { var convertedValue = _valueConverter.Invoke(value); cancellationToken.ThrowIfCancellationRequested(); result = await writer.WriteAsync(convertedValue, cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public async Task <IBleResult> StopObservingAsync() { IBleResult result; try { if (_bleCharacteristic == null) { result = BleResult.Failure(BleFailure.DeviceNotInitialized); } else if (!_bleCharacteristic.CanUpdate) { result = BleResult.Failure(BleFailure.UpdateNotSupported); } else { if (IsObserving) { await _bleCharacteristic.StopUpdatesAsync().ConfigureAwait(false); IsObserving = false; NotifyObservationCompleted(); } result = BleResult.Success(); } } catch (TimeoutException) { result = BleResult.Failure(BleFailure.OperationTimeout); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
public async Task <IBleResult <byte[]> > ReadRawAsync(CancellationToken cancellationToken) { IBleResult <byte[]> result; try { if (_bleCharacteristic == null) { result = BleResult.Failure <byte[]>(BleFailure.DeviceNotInitialized); } else if (!_bleCharacteristic.CanRead) { result = BleResult.Failure <byte[]>(BleFailure.ReadNotSupported); } else { var rawData = await _bleCharacteristic.ReadAsync(cancellationToken).ConfigureAwait(false); result = BleResult.Success(rawData); } } catch (TimeoutException) { result = BleResult.Failure <byte[]>(BleFailure.OperationTimeout); } catch (OperationCanceledException) { result = BleResult.Failure <byte[]>(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure <byte[]>(e); } return(result); }
public async Task <IBleResult> WriteRawAsync(byte[] data, CancellationToken cancellationToken) { IBleResult result; try { if (_bleCharacteristic == null) { result = BleResult.Failure(BleFailure.DeviceNotInitialized); } else if (!_bleCharacteristic.CanWrite) { result = BleResult.Failure(BleFailure.WriteNotSupported); } else { var completed = await _bleExecutionProvider.ExecuteAsync(() => _bleCharacteristic.WriteAsync(data, cancellationToken)).ConfigureAwait(false); result = completed ? BleResult.Success() : BleResult.Failure(BleFailure.WriteFailed); } } catch (TimeoutException) { result = BleResult.Failure(BleFailure.OperationTimeout); } catch (OperationCanceledException) { result = BleResult.Failure(BleFailure.OperationCancelled); } catch (Exception e) { result = BleResult.Failure(e); } return(result); }
private Task <IBleResult> ExecuteOperationWithPolicyAsync(Func <Task <IBleResult> > executionProvider, CancellationToken cancellationToken) { return(IsConnected ? ExecuteSequentiallyAsync(executionProvider, cancellationToken) : Task.FromResult(BleResult.Failure(BleFailure.DeviceNotConnected))); }
public Task <IBleResult> StopObservingAsync(CancellationToken cancellationToken) { return(IsObserving ? _characteristicObserver.StopObservingRawValueAsync(_characteristicId, cancellationToken) : Task.FromResult(BleResult.Success())); }