From 135bda84515e0a8b5d73330ed98ae6b883a427fc Mon Sep 17 00:00:00 2001 From: Ask Bojesen Date: Thu, 29 Feb 2024 11:04:44 +0100 Subject: [PATCH 1/4] Implemented and tested: - Adapter.BondAsync - Adapter.BondedDevices --- .../BLE.Client.WinConsole/PluginDemos.cs | 18 +++++++ .../BLE.Client.WinConsole/Program.cs | 2 + Source/Plugin.BLE/Windows/Adapter.cs | 54 ++++++++++++++++--- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs b/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs index e065b27b..3c14db01 100644 --- a/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs +++ b/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs @@ -211,6 +211,24 @@ public async Task Connect_Change_Parameters_Disconnect() Write("Test_Connect_Disconnect done"); } + public async Task BondAsync() + { + string bleaddress = BleAddressSelector.GetBleAddress(); + var id = bleaddress.ToBleDeviceGuid(); + IDevice dev = await Adapter.ConnectToKnownDeviceAsync(id); + await Adapter.BondAsync(dev); + } + + public Task GetBondedDevices() + { + int idx = 0; + foreach(var dev in Adapter.BondedDevices) + { + Write($"{idx++} Bonded device: {dev.Name} : {dev.Id}"); + } + return Task.FromResult(true); + } + public async Task Pair_Connect_Disconnect() { string bleaddress = BleAddressSelector.GetBleAddress(); diff --git a/Source/BLE.Client/BLE.Client.WinConsole/Program.cs b/Source/BLE.Client/BLE.Client.WinConsole/Program.cs index 9bed9006..1f34b72b 100644 --- a/Source/BLE.Client/BLE.Client.WinConsole/Program.cs +++ b/Source/BLE.Client/BLE.Client.WinConsole/Program.cs @@ -25,6 +25,8 @@ {ConsoleKey.D7, new Demo("5X: Connect -> Read services -> Disconnect", ppemos.Connect_Read_Services_Disconnect_5X) }, {ConsoleKey.D8, new Demo("5X: Connect -> Read services -> Dispose", ppemos.Connect_Read_Services_Dispose_5X) }, {ConsoleKey.D9, new Demo("Connect -> Loop: ConnectionLost -> Connect", ppemos.Connect_ConnectionLost_Connect) }, + {ConsoleKey.Q, new Demo("Adapter.BondAsync", ppemos.BondAsync) }, + {ConsoleKey.W, new Demo("Adapter.BondedDevices", ppemos.GetBondedDevices) }, {ConsoleKey.A, new Demo("Pure Windows: Connect -> Disconnect", wdemos.Connect_Disconnect) }, {ConsoleKey.S, new Demo("Pure Windows: Unpair all BLE devices", wdemos.UnPairAllBleDevices) }, }; diff --git a/Source/Plugin.BLE/Windows/Adapter.cs b/Source/Plugin.BLE/Windows/Adapter.cs index de1275bf..1ad0baa2 100644 --- a/Source/Plugin.BLE/Windows/Adapter.cs +++ b/Source/Plugin.BLE/Windows/Adapter.cs @@ -28,9 +28,27 @@ public Adapter() { } - public override Task BondAsync(IDevice device) + public override async Task BondAsync(IDevice device) { - throw new NotImplementedException(); + var bleDevice = device.NativeDevice as BluetoothLEDevice; + if (bleDevice is null) + { + Trace.Message($"BondAsync failed since NativeDevice is null with: {device.Name}: {device.Id} "); + return; + } + DeviceInformation deviceInformation = await DeviceInformation.CreateFromIdAsync(bleDevice.DeviceId); + if (deviceInformation.Pairing.IsPaired) + { + Trace.Message($"BondAsync is already paired with: {device.Name}: {device.Id}"); + return; + } + if (!deviceInformation.Pairing.CanPair) + { + Trace.Message($"BondAsync cannot pair with: {device.Name}: {device.Id}"); + return; + } + DevicePairingResult result = await deviceInformation.Pairing.PairAsync(); + Trace.Message($"BondAsync pairing result was {result.Status} with: {device.Name}: {device.Id}"); } protected override Task StartScanningForDevicesNativeAsync(ScanFilterOptions scanFilterOptions, bool allowDuplicatesKey, CancellationToken scanCancellationToken) @@ -161,6 +179,33 @@ public override async Task ConnectToKnownDeviceNativeAsync(Guid deviceG return knownDevice; } + protected override IReadOnlyList GetBondedDevices() + { + string pairedSelector = BluetoothLEDevice.GetDeviceSelectorFromPairingState(true); + DeviceInformationCollection pairedDevices = DeviceInformation.FindAllAsync(pairedSelector).GetAwaiter().GetResult(); + List devlist = new List(); + foreach (var dev in pairedDevices) + { + Guid id = dev.Id.ToBleDeviceGuidFromId(); + ulong bleaddress = id.ToBleAddress(); + var bluetoothLeDevice = BluetoothLEDevice.FromBluetoothAddressAsync(bleaddress).AsTask().Result; + if (bluetoothLeDevice != null) + { + var device = new Device( + this, + bluetoothLeDevice, + 0, id); + devlist.Add(device); + Trace.Message("GetBondedDevices: {0}: {1}", dev.Id, dev.Name); + } + else + { + Trace.Message("GetBondedDevices: {0}: {1}, BluetoothLEDevice == null", dev.Id, dev.Name); + } + } + return devlist; + } + public override IReadOnlyList GetSystemConnectedOrPairedDevices(Guid[] services = null) { string pairedSelector = BluetoothLEDevice.GetDeviceSelectorFromPairingState(true); @@ -194,11 +239,6 @@ public override IReadOnlyList GetSystemConnectedOrPairedDevices(Guid[] return devlist; } - protected override IReadOnlyList GetBondedDevices() - { - return null; // not supported - } - /// /// Parses a given advertisement for various stored properties /// Currently only parses the manufacturer specific data From 8709368db6bc075c48e389055548171b757a233d Mon Sep 17 00:00:00 2001 From: Ask Bojesen Date: Tue, 19 Mar 2024 16:25:18 +0100 Subject: [PATCH 2/4] Implemented GetBondState Test for GetBondState --- .../BLE.Client.WinConsole/PluginDemos.cs | 9 +++++++++ .../BLE.Client.WinConsole/Program.cs | 1 + Source/Plugin.BLE/Windows/Device.cs | 19 ++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs b/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs index 3c14db01..b9ad1bc0 100644 --- a/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs +++ b/Source/BLE.Client/BLE.Client.WinConsole/PluginDemos.cs @@ -81,6 +81,15 @@ public async Task Connect_Disconnect() Write("Test_Connect_Disconnect done"); } + public async Task ShowBondState() + { + string bleaddress = BleAddressSelector.GetBleAddress(); + var id = bleaddress.ToBleDeviceGuid(); + IDevice dev = await Adapter.ConnectToKnownDeviceAsync(id); + Write("BondState: " + dev.BondState); + dev.Dispose(); + } + public async Task Connect_Read_Services_Disconnect_5X() { string bleaddress = BleAddressSelector.GetBleAddress(); diff --git a/Source/BLE.Client/BLE.Client.WinConsole/Program.cs b/Source/BLE.Client/BLE.Client.WinConsole/Program.cs index 1f34b72b..6fc66477 100644 --- a/Source/BLE.Client/BLE.Client.WinConsole/Program.cs +++ b/Source/BLE.Client/BLE.Client.WinConsole/Program.cs @@ -27,6 +27,7 @@ {ConsoleKey.D9, new Demo("Connect -> Loop: ConnectionLost -> Connect", ppemos.Connect_ConnectionLost_Connect) }, {ConsoleKey.Q, new Demo("Adapter.BondAsync", ppemos.BondAsync) }, {ConsoleKey.W, new Demo("Adapter.BondedDevices", ppemos.GetBondedDevices) }, + {ConsoleKey.E, new Demo("Device.BondState", ppemos.ShowBondState) }, {ConsoleKey.A, new Demo("Pure Windows: Connect -> Disconnect", wdemos.Connect_Disconnect) }, {ConsoleKey.S, new Demo("Pure Windows: Unpair all BLE devices", wdemos.UnPairAllBleDevices) }, }; diff --git a/Source/Plugin.BLE/Windows/Device.cs b/Source/Plugin.BLE/Windows/Device.cs index 1798f471..2ee90265 100644 --- a/Source/Plugin.BLE/Windows/Device.cs +++ b/Source/Plugin.BLE/Windows/Device.cs @@ -11,6 +11,7 @@ using WBluetooth = global::Windows.Devices.Bluetooth; using static System.Net.Mime.MediaTypeNames; using Windows.Devices.Bluetooth.GenericAttributeProfile; +using Windows.Devices.Enumeration; namespace Plugin.BLE.Windows { @@ -238,7 +239,23 @@ public override void Dispose() protected override DeviceBondState GetBondState() { - return DeviceBondState.NotSupported; + try + { + DeviceInformation deviceInformation = DeviceInformation.CreateFromIdAsync(NativeDevice.DeviceId).AsTask().Result; + if (deviceInformation.Pairing.IsPaired) + { + return DeviceBondState.Bonded; + } + else + { + return DeviceBondState.NotBonded; + } + } + catch (Exception ex) + { + Trace.Message($"GetBondState exception for {NativeDevice.DeviceId} : {ex.Message}"); + return DeviceBondState.NotSupported; + } } public override bool UpdateConnectionParameters(ConnectParameters connectParameters = default) From 337205bc5ceef411e5b55e803b6961b8e0de579f Mon Sep 17 00:00:00 2001 From: Ask Bojesen Date: Wed, 20 Mar 2024 08:09:34 +0100 Subject: [PATCH 3/4] Simplified expression --- Source/Plugin.BLE/Windows/Device.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Source/Plugin.BLE/Windows/Device.cs b/Source/Plugin.BLE/Windows/Device.cs index 2ee90265..1c5d9a25 100644 --- a/Source/Plugin.BLE/Windows/Device.cs +++ b/Source/Plugin.BLE/Windows/Device.cs @@ -242,14 +242,7 @@ protected override DeviceBondState GetBondState() try { DeviceInformation deviceInformation = DeviceInformation.CreateFromIdAsync(NativeDevice.DeviceId).AsTask().Result; - if (deviceInformation.Pairing.IsPaired) - { - return DeviceBondState.Bonded; - } - else - { - return DeviceBondState.NotBonded; - } + return deviceInformation.Pairing.IsPaired ? DeviceBondState.Bonded : DeviceBondState.NotBonded; } catch (Exception ex) { From 92d59e15d8be7982b73a3896d1a5559ba4364483 Mon Sep 17 00:00:00 2001 From: Ask Bojesen Date: Fri, 19 Apr 2024 08:54:47 +0200 Subject: [PATCH 4/4] Added comment for DeviceBondStateChanged --- Source/Plugin.BLE/Shared/Contracts/IAdapter.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Source/Plugin.BLE/Shared/Contracts/IAdapter.cs b/Source/Plugin.BLE/Shared/Contracts/IAdapter.cs index bab0553d..0250336e 100644 --- a/Source/Plugin.BLE/Shared/Contracts/IAdapter.cs +++ b/Source/Plugin.BLE/Shared/Contracts/IAdapter.cs @@ -39,6 +39,9 @@ public interface IAdapter event EventHandler DeviceConnectionError; /// /// Occurs when the bonding state of a device changed + /// Android: Supported + /// iOS: Not supported + /// Windows: Not supported /// event EventHandler DeviceBondStateChanged; ///