private async void DeviceInRange(object sender, BluetoothWin32RadioInRangeEventArgs?e) { if (e?.Device == null) { Log.Warning("Windows.BluetoothService: Discovered NULL device"); return; } if (e.Device.DeviceAddress == MacUtils.ToAddress(_currentMac)) { Log.Debug($"Windows.BluetoothService: Target device inbound ({_currentMac})"); if (IsStreamConnected) { Log.Debug($"Windows.BluetoothService: Target device already connected"); } else { try { await ConnectAsync(_currentMac, _currentUuid); } catch (InvalidOperationException ex) { BluetoothErrorAsync?.Invoke(this, new BluetoothException(BluetoothException.ErrorCodes.Unknown, ex.Message)); Log.Error($"Windows.BluetoothService: DeviceInRange: InvalidOperationException caught ({ex.Message})"); } catch (BluetoothException ex) { BluetoothErrorAsync?.Invoke(this, ex); Log.Error($"Windows.BluetoothService: DeviceInRange: BluetoothException caught ({ex.Message})"); } } } }
public async Task ConnectAsync(string macAddress, string uuid, bool noRetry = false) { var semResult = await _connSemaphore.WaitAsync(5000); if (semResult == false) { Log.Error($"Windows.BluetoothService: Connection attempt timed out due to blocked semaphore"); throw new BluetoothException(BluetoothException.ErrorCodes.TimedOut, "Timed out while waiting to enter connection phase. Another task is already preparing a connection."); } if (_client?.Connected ?? false) { Log.Debug("Windows.BluetoothService: Already connected, skipped."); _connSemaphore.Release(); return; } SelectAdapter(); Connecting?.Invoke(this, EventArgs.Empty); Log.Debug($"Windows.BluetoothService: Connecting..."); _cancelSource?.Cancel(); _client?.Close(); _client = null; SelectAdapter(); if (_client == null) { Log.Error("Windows.BluetoothService: Cannot create client and connect."); BluetoothErrorAsync?.Invoke(this, new BluetoothException(BluetoothException.ErrorCodes.Unknown, "Cannot create client")); _connSemaphore.Release(); return; } try { try { var addr = MacUtils.ToAddress(macAddress); if (addr == null) { Log.Error("Windows.BluetoothService: Invalid MAC address. Failed to connect."); throw new BluetoothException(BluetoothException.ErrorCodes.ConnectFailed, "Invalid MAC address. Please deregister your device and try again."); } _currentMac = macAddress; _currentUuid = uuid; _client.Connect(addr, new Guid(uuid)); /*await Task.Factory.FromAsync( * (callback, stateObject) => _client.BeginConnect(addr, new Guid(uuid), callback, stateObject), * _client.EndConnect, null);*/ } catch (ArgumentException) { BluetoothErrorAsync?.Invoke(this, new BluetoothException( BluetoothException.ErrorCodes.ConnectFailed, $"Invalid MAC address. Please deregister your device and try again.")); _connSemaphore.Release(); return; } Connected?.Invoke(this, EventArgs.Empty); Log.Debug($"Windows.BluetoothService: Connected. Launching BluetoothServiceLoop."); _cancelSource = new CancellationTokenSource(); _loop = Task.Run(BluetoothServiceLoop, _cancelSource.Token); } catch (SocketException e) { BluetoothErrorAsync?.Invoke(this, new BluetoothException(BluetoothException.ErrorCodes.ConnectFailed, e.Message)); } finally { _connSemaphore.Release(); } }