From 7bde3abf8b21c1dfa29f1ed523681b5904d60ccd Mon Sep 17 00:00:00 2001 From: Aaron Yu Date: Wed, 20 Sep 2023 13:47:42 -0700 Subject: [PATCH] Harden ble v2 gatt server PiperOrigin-RevId: 567069079 --- .../implementation/windows/ble_gatt_client.cc | 7 ++ .../implementation/windows/ble_gatt_server.cc | 34 ++++++++- .../windows/bluetooth_adapter.cc | 69 +++++++++++++++++++ .../windows/bluetooth_adapter.h | 10 +++ .../windows/bluetooth_adapter_test.cc | 15 ++++ 5 files changed, 133 insertions(+), 2 deletions(-) diff --git a/internal/platform/implementation/windows/ble_gatt_client.cc b/internal/platform/implementation/windows/ble_gatt_client.cc index 41d56644..7c553252 100644 --- a/internal/platform/implementation/windows/ble_gatt_client.cc +++ b/internal/platform/implementation/windows/ble_gatt_client.cc @@ -122,6 +122,13 @@ bool BleGattClient::DiscoverServiceAndCharacteristics( return false; } + if (!windows_bluetooth_adapter_.IsCentralRoleSupported()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Bluetooth Hardware does not support Central " + "Role, which is required to start GATT client."; + return false; + } + if (!NearbyFlags::GetInstance().GetBoolFlag( platform::config_package_nearby::nearby_platform_feature:: kEnableBleV2GattOnNonExtendedDevice)) { diff --git a/internal/platform/implementation/windows/ble_gatt_server.cc b/internal/platform/implementation/windows/ble_gatt_server.cc index ea4ef93d..9dfe45db 100644 --- a/internal/platform/implementation/windows/ble_gatt_server.cc +++ b/internal/platform/implementation/windows/ble_gatt_server.cc @@ -226,6 +226,13 @@ bool BleGattServer::InitializeGattServer() { return false; } + if (!adapter_->IsLowEnergySupported()) { + NEARBY_LOGS(ERROR) << __func__ + << ": Bluetooth adapter does not support BLE, which " + "is needed to start GATT server."; + return false; + } + winrt::guid service_uuid = nearby_uuid_to_winrt_guid(service_uuid_); GattServiceProviderResult service_provider_result = GattServiceProvider::CreateAsync(service_uuid).get(); @@ -371,14 +378,37 @@ bool BleGattServer::StartAdvertisement(const ByteArray& service_data, return false; } - is_advertising_ = true; - if (!is_gatt_server_inited_ && !InitializeGattServer()) { NEARBY_LOGS(ERROR) << ":Failed to initalize GATT service."; is_advertising_ = false; return false; } + if (gatt_service_provider_ == nullptr) { + NEARBY_LOGS(WARNING) << __func__ << ": no GATT server is running."; + is_advertising_ = false; + return false; + } + + if (gatt_service_provider_.AdvertisementStatus() == + GattServiceProviderAdvertisementStatus::Started) { + NEARBY_LOGS(WARNING) << __func__ + << ": GATT server is already in advertising."; + is_advertising_ = true; + return false; + } + + if (!adapter_->IsPeripheralRoleSupported()) { + NEARBY_LOGS(ERROR) + << __func__ + << ": Bluetooth Hardware does not support Peripheral Role, which is " + "required to start GATT server."; + is_advertising_ = false; + return false; + } + + is_advertising_ = true; + // Start the GATT server advertising GattServiceProviderAdvertisingParameters advertisement_parameters; advertisement_parameters.IsConnectable(is_connectable); diff --git a/internal/platform/implementation/windows/bluetooth_adapter.cc b/internal/platform/implementation/windows/bluetooth_adapter.cc index 7f9d143c..42f0832c 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter.cc @@ -218,6 +218,75 @@ bool BluetoothAdapter::IsExtendedAdvertisingSupported() const { } } +// Returns true if the Bluetooth hardware supports BLE Central Role +bool BluetoothAdapter::IsCentralRoleSupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports the BLE Central Role + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.iscentralrolesupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsCentralRoleSupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + +// Returns true if the Bluetooth hardware supports BLE Peripheral Role +bool BluetoothAdapter::IsPeripheralRoleSupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports the BLE Peripheral Role + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.isperipheralrolesupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsPeripheralRoleSupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + +// Returns true if the Bluetooth hardware supports BLE +bool BluetoothAdapter::IsLowEnergySupported() const { + if (windows_bluetooth_adapter_ == nullptr) { + NEARBY_LOGS(ERROR) << __func__ << ": No Bluetooth adapter on this device."; + return false; + } + try { + // Indicates whether the adapter supports BLE + // https://learn.microsoft.com/en-us/uwp/api/windows.devices.bluetooth.bluetoothadapter.islowenergysupported?view=winrt-22621 + return windows_bluetooth_adapter_.IsLowEnergySupported(); + } catch (std::exception exception) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << exception.what(); + return false; + } catch (const winrt::hresult_error &ex) { + NEARBY_LOGS(ERROR) << __func__ << ": exception:" << ex.code() << ": " + << winrt::to_string(ex.message()); + return false; + } catch (...) { + NEARBY_LOGS(ERROR) << __func__ << ": unknown error."; + return false; + } +} + // https://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getScanMode() // // Returns ScanMode::kUnknown on error. diff --git a/internal/platform/implementation/windows/bluetooth_adapter.h b/internal/platform/implementation/windows/bluetooth_adapter.h index d1e6a001..dadb2f9a 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter.h +++ b/internal/platform/implementation/windows/bluetooth_adapter.h @@ -98,6 +98,16 @@ class BluetoothAdapter : public api::BluetoothAdapter { // Returns true if the Bluetooth hardware supports Bluetooth 5.0 Extended // Advertising bool IsExtendedAdvertisingSupported() const; + + // Returns true if the Bluetooth hardware supports BLE Central Role + bool IsCentralRoleSupported() const; + + // Returns true if the Bluetooth hardware supports BLE Peripheral Role + bool IsPeripheralRoleSupported() const; + + // Returns true if the Bluetooth hardware supports BLE + bool IsLowEnergySupported() const; + void RestoreRadioNameIfNecessary(); private: diff --git a/internal/platform/implementation/windows/bluetooth_adapter_test.cc b/internal/platform/implementation/windows/bluetooth_adapter_test.cc index 8c9c5ae1..32577ca2 100644 --- a/internal/platform/implementation/windows/bluetooth_adapter_test.cc +++ b/internal/platform/implementation/windows/bluetooth_adapter_test.cc @@ -183,6 +183,21 @@ TEST(BluetoothAdapter, DISABLED_IsExtendedAdvertisingSupported) { EXPECT_TRUE(bluetooth_adapter.IsExtendedAdvertisingSupported()); } +TEST(BluetoothAdapter, DISABLED_IsCentralRoleSupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsCentralRoleSupported()); +} + +TEST(BluetoothAdapter, DISABLED_IsPeripheralRoleSupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsPeripheralRoleSupported()); +} + +TEST(BluetoothAdapter, DISABLED_IsLowEnergySupported) { + BluetoothAdapter bluetooth_adapter; + EXPECT_TRUE(bluetooth_adapter.IsLowEnergySupported()); +} + TEST(BluetoothAdapter, DISABLED_GetNameFromComputerName) { BluetoothAdapter bluetooth_adapter; EXPECT_TRUE(!bluetooth_adapter.GetNameFromComputerName().empty());