From 06c3b88cdebbde6e501b34378b080175b564664c Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 May 2022 03:03:06 -0700 Subject: [PATCH 1/3] Add PairAsync Method --- .../windows/quick_blue_windows_plugin.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/quick_blue_windows/windows/quick_blue_windows_plugin.cpp b/quick_blue_windows/windows/quick_blue_windows_plugin.cpp index 0ce97280..7df048bd 100644 --- a/quick_blue_windows/windows/quick_blue_windows_plugin.cpp +++ b/quick_blue_windows/windows/quick_blue_windows_plugin.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ using namespace winrt::Windows::Devices::Radios; using namespace winrt::Windows::Devices::Bluetooth; using namespace winrt::Windows::Devices::Bluetooth::Advertisement; using namespace winrt::Windows::Devices::Bluetooth::GenericAttributeProfile; +using namespace winrt::Windows::Devices::Enumeration; using flutter::EncodableValue; using flutter::EncodableMap; @@ -152,7 +154,9 @@ class QuickBlueWindowsPlugin : public flutter::Plugin, public flutter::StreamHan std::map> connectedDevices{}; winrt::fire_and_forget ConnectAsync(uint64_t bluetoothAddress); + winrt::fire_and_forget PairAsync(uint64_t bluetoothAddress, DevicePairingProtectionLevel level); void BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, IInspectable args); + void BluetoothLEDevice_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args); void CleanConnection(uint64_t bluetoothAddress); winrt::fire_and_forget DiscoverServicesAsync(BluetoothDeviceAgent &bluetoothDeviceAgent); winrt::fire_and_forget SetNotifiableAsync(BluetoothDeviceAgent& bluetoothDeviceAgent, std::string service, std::string characteristic, std::string bleInputProperty); @@ -380,6 +384,24 @@ std::unique_ptr> QuickBlueWindowsPlu return nullptr; } +winrt::fire_and_forget QuickBlueWindowsPlugin::PairAsync(uint64_t bluetoothAddress, DevicePairingProtectionLevel level) { + auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(bluetoothAddress); + if(device != nullptr) { + if(device.DeviceInformation().Pairing().CanPair()) { + try { + device.DeviceInformation().Pairing().Custom().PairingRequested({ this, &QuickBlueWindowsPlugin::BluetoothLEDevice_PairingRequested }); + auto result = co_await device.DeviceInformation().Pairing().Custom().PairAsync(DevicePairingKinds::ConfirmOnly, DevicePairingProtectionLevel::Encryption); + if(result.Status() != DevicePairingResultStatus::Paired && result.Status() != DevicePairingResultStatus::AlreadyPaired) { + OutputDebugString((L"PairAsync error: " + winrt::to_hstring((int32_t)result.Status()) + L"\n").c_str()); + } + } catch(winrt::hresult_error const& ex) { + OutputDebugString((L"PairAsync " + ex.message() + L"\n").c_str()); + } + } + } + co_return; +} + winrt::fire_and_forget QuickBlueWindowsPlugin::ConnectAsync(uint64_t bluetoothAddress) { auto device = co_await BluetoothLEDevice::FromBluetoothAddressAsync(bluetoothAddress); auto servicesResult = co_await device.GetGattServicesAsync(); @@ -400,6 +422,11 @@ winrt::fire_and_forget QuickBlueWindowsPlugin::ConnectAsync(uint64_t bluetoothAd {"deviceId", std::to_string(bluetoothAddress)}, {"ConnectionState", "connected"}, }); + PairAsync(bluetoothAddress, DevicePairingProtectionLevel::Encryption); +} + +void QuickBlueWindowsPlugin::BluetoothLEDevice_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args) { + args.Accept(); } void QuickBlueWindowsPlugin::BluetoothLEDevice_ConnectionStatusChanged(BluetoothLEDevice sender, IInspectable args) { From ec1a0cc1c9be948d6ac3e57204713673daee4bfb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Jun 2022 09:29:00 -0700 Subject: [PATCH 2/3] Add pair method --- quick_blue/lib/quick_blue.dart | 2 ++ quick_blue/pubspec.yaml | 4 ++++ .../lib/method_channel_quick_blue.dart | 9 +++++++++ .../lib/quick_blue_platform_interface.dart | 2 ++ quick_blue_windows/windows/quick_blue_windows_plugin.cpp | 8 ++++++-- 5 files changed, 23 insertions(+), 2 deletions(-) diff --git a/quick_blue/lib/quick_blue.dart b/quick_blue/lib/quick_blue.dart index 7be23021..36508b0f 100644 --- a/quick_blue/lib/quick_blue.dart +++ b/quick_blue/lib/quick_blue.dart @@ -60,6 +60,8 @@ class QuickBlue { static void connect(String deviceId) => _platform.connect(deviceId); + static void pair(String deviceId) => _platform.pair(deviceId); + static void disconnect(String deviceId) => _platform.disconnect(deviceId); static void setConnectionHandler(OnConnectionChanged? onConnectionChanged) { diff --git a/quick_blue/pubspec.yaml b/quick_blue/pubspec.yaml index 002f386e..7069e2ca 100644 --- a/quick_blue/pubspec.yaml +++ b/quick_blue/pubspec.yaml @@ -17,6 +17,10 @@ dependencies: quick_blue_linux: ^0.2.0-dev.0 convert: ^3.0.0 +dependency_overrides: + quick_blue_platform_interface: + path: ../quick_blue_platform_interface + dev_dependencies: flutter_test: sdk: flutter diff --git a/quick_blue_platform_interface/lib/method_channel_quick_blue.dart b/quick_blue_platform_interface/lib/method_channel_quick_blue.dart index 1e673a0e..0a69b98d 100644 --- a/quick_blue_platform_interface/lib/method_channel_quick_blue.dart +++ b/quick_blue_platform_interface/lib/method_channel_quick_blue.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'dart:typed_data'; import 'package:flutter/services.dart'; @@ -140,4 +141,12 @@ class MethodChannelQuickBlue extends QuickBluePlatform { }).then((_) => _log('requestMtu invokeMethod success')); return await _mtuConfigController.stream.first; } + + @override + void pair(String deviceId) { + if(!Platform.isWindows)throw UnimplementedError(); + _method.invokeMethod('pair', { + 'deviceId': deviceId, + }).then((_) => _log('pair invokeMethod success')); + } } diff --git a/quick_blue_platform_interface/lib/quick_blue_platform_interface.dart b/quick_blue_platform_interface/lib/quick_blue_platform_interface.dart index 722c7f1c..bfcadc8b 100644 --- a/quick_blue_platform_interface/lib/quick_blue_platform_interface.dart +++ b/quick_blue_platform_interface/lib/quick_blue_platform_interface.dart @@ -47,6 +47,8 @@ abstract class QuickBluePlatform extends PlatformInterface { void disconnect(String deviceId); + void pair(String deviceId); + OnConnectionChanged? onConnectionChanged; void discoverServices(String deviceId); diff --git a/quick_blue_windows/windows/quick_blue_windows_plugin.cpp b/quick_blue_windows/windows/quick_blue_windows_plugin.cpp index 7df048bd..ae4a9573 100644 --- a/quick_blue_windows/windows/quick_blue_windows_plugin.cpp +++ b/quick_blue_windows/windows/quick_blue_windows_plugin.cpp @@ -245,7 +245,12 @@ void QuickBlueWindowsPlugin::HandleMethodCall( auto deviceId = std::get(args[EncodableValue("deviceId")]); ConnectAsync(std::stoull(deviceId)); result->Success(nullptr); - } else if (method_name.compare("disconnect") == 0) { + }else if (method_name.compare("pair") == 0) { + auto args = std::get(*method_call.arguments()); + auto deviceId = std::get(args[EncodableValue("deviceId")]); + PairAsync(std::stoull(deviceId), DevicePairingProtectionLevel::Encryption); + result->Success(nullptr); + }else if (method_name.compare("disconnect") == 0) { auto args = std::get(*method_call.arguments()); auto deviceId = std::get(args[EncodableValue("deviceId")]); CleanConnection(std::stoull(deviceId)); @@ -422,7 +427,6 @@ winrt::fire_and_forget QuickBlueWindowsPlugin::ConnectAsync(uint64_t bluetoothAd {"deviceId", std::to_string(bluetoothAddress)}, {"ConnectionState", "connected"}, }); - PairAsync(bluetoothAddress, DevicePairingProtectionLevel::Encryption); } void QuickBlueWindowsPlugin::BluetoothLEDevice_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args) { From 6e4b226a76ff494e918aa3c1a384b4979e980794 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Jun 2022 09:44:43 -0700 Subject: [PATCH 3/3] Add pair in example --- quick_blue_example/lib/PeripheralDetailPage.dart | 10 +++++++++- quick_blue_linux/lib/quick_blue_linux.dart | 6 ++++++ quick_blue_linux/pubspec.yaml | 4 ++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/quick_blue_example/lib/PeripheralDetailPage.dart b/quick_blue_example/lib/PeripheralDetailPage.dart index 37c23a51..4969d75c 100644 --- a/quick_blue_example/lib/PeripheralDetailPage.dart +++ b/quick_blue_example/lib/PeripheralDetailPage.dart @@ -1,3 +1,4 @@ +import 'dart:io'; import 'dart:typed_data'; import 'package:convert/convert.dart'; @@ -46,7 +47,7 @@ class _PeripheralDetailPageState extends State { } void _handleConnectionChange(String deviceId, BlueConnectionState state) { - print('_handleConnectionChange $deviceId, $state'); + print('_handleConnectionChange $deviceId, ${state.value}'); } void _handleServiceDiscovery(String deviceId, String serviceId, List characteristicIds) { @@ -80,6 +81,13 @@ class _PeripheralDetailPageState extends State { QuickBlue.connect(widget.deviceId); }, ), + if(Platform.isWindows) + RaisedButton( + child: Text('pair'), + onPressed: () { + QuickBlue.pair(widget.deviceId); + }, + ), RaisedButton( child: Text('disconnect'), onPressed: () { diff --git a/quick_blue_linux/lib/quick_blue_linux.dart b/quick_blue_linux/lib/quick_blue_linux.dart index 83b9f2dd..cc51a59d 100644 --- a/quick_blue_linux/lib/quick_blue_linux.dart +++ b/quick_blue_linux/lib/quick_blue_linux.dart @@ -117,6 +117,12 @@ class QuickBlueLinux extends QuickBluePlatform { // TODO: implement requestMtu throw UnimplementedError(); } + + @override + void pair(String deviceId) { + // TODO: implement pair + throw UnimplementedError(); + } } extension BlueZDeviceExtension on BlueZDevice { diff --git a/quick_blue_linux/pubspec.yaml b/quick_blue_linux/pubspec.yaml index 8fbc4104..46e6b2ff 100644 --- a/quick_blue_linux/pubspec.yaml +++ b/quick_blue_linux/pubspec.yaml @@ -16,6 +16,10 @@ dependencies: collection: ^1.15.0 logging: ^1.0.2 +dependency_overrides: + quick_blue_platform_interface: + path: ../quick_blue_platform_interface + dev_dependencies: flutter_test: sdk: flutter