From abe68db97d1884702620025887f501d2180fa2a7 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Fri, 24 Feb 2023 11:44:52 -0800 Subject: [PATCH] Add GattServer#NotifyCharacteristicChanged to ble_v2 PiperOrigin-RevId: 512124578 --- internal/platform/ble_v2.h | 9 +++++++ internal/platform/ble_v2_test.cc | 27 +++++++++++++++++++ internal/platform/implementation/apple/ble.h | 2 ++ internal/platform/implementation/apple/ble.mm | 7 +++++ internal/platform/implementation/ble_v2.h | 10 +++++++ internal/platform/implementation/g3/ble_v2.cc | 8 ++++++ internal/platform/implementation/g3/ble_v2.h | 4 +++ 7 files changed, 67 insertions(+) diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index 19454fe5..5dfb7f70 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -148,6 +148,7 @@ class BleV2ServerSocket final { // // Note that some of the methods return absl::optional instead // of std::optional, because iOS platform is still in C++14. +// LINT.IfChange class GattServer final { public: explicit GattServer(std::unique_ptr gatt_server) @@ -171,6 +172,13 @@ class GattServer final { return impl_->UpdateCharacteristic(characteristic, value); } + absl::Status NotifyCharacteristicChanged( + const api::ble_v2::GattCharacteristic& characteristic, bool confirm, + const ByteArray& new_value) { + return impl_->NotifyCharacteristicChanged(characteristic, confirm, + new_value); + } + void Stop() { if (impl_) return impl_->Stop(); } @@ -187,6 +195,7 @@ class GattServer final { private: std::unique_ptr impl_; }; +// LINT.ThenChange(//depot/google3/third_party/nearby/internal/platform/implementation/ble_v2.h) // Opaque wrapper for a GattClient. // diff --git a/internal/platform/ble_v2_test.cc b/internal/platform/ble_v2_test.cc index d8679fb2..9db810b1 100644 --- a/internal/platform/ble_v2_test.cc +++ b/internal/platform/ble_v2_test.cc @@ -532,5 +532,32 @@ TEST_F(BleV2MediumTest, GattClientConnectToGattServerWorks) { env_.Stop(); } +TEST_F(BleV2MediumTest, GattServerCanNotifyChange) { + env_.Start(); + BluetoothAdapter adapter_a; + BleV2Medium ble_a(adapter_a); + Uuid service_uuid(1234, 5678); + Uuid characteristic_uuid(5678, 1234); + std::vector permissions = { + GattCharacteristic::Permission::kRead}; + std::vector properties = { + GattCharacteristic::Property::kRead}; + + // Start GattServer + std::unique_ptr gatt_server = + ble_a.StartGattServer(/*ServerGattConnectionCallback=*/{}); + + ASSERT_NE(gatt_server, nullptr); + // Add characteristic and its value. + // NOLINTNEXTLINE(google3-legacy-absl-backports) + absl::optional server_characteristic = + gatt_server->CreateCharacteristic(service_uuid, characteristic_uuid, + permissions, properties); + + EXPECT_THAT(gatt_server->NotifyCharacteristicChanged( + server_characteristic.value(), false, ByteArray("hello")), + testing::status::StatusIs(absl::StatusCode::kUnimplemented)); +} + } // namespace } // namespace nearby diff --git a/internal/platform/implementation/apple/ble.h b/internal/platform/implementation/apple/ble.h index a2b7c5ae..919522e1 100644 --- a/internal/platform/implementation/apple/ble.h +++ b/internal/platform/implementation/apple/ble.h @@ -157,6 +157,8 @@ class BleMedium : public api::ble_v2::BleMedium { bool UpdateCharacteristic(const api::ble_v2::GattCharacteristic &characteristic, const nearby::ByteArray &value) override; + absl::Status NotifyCharacteristicChanged(const api::ble_v2::GattCharacteristic &characteristic, + bool confirm, const ByteArray &new_value) override; void Stop() override; private: diff --git a/internal/platform/implementation/apple/ble.mm b/internal/platform/implementation/apple/ble.mm index ee388125..a4d16f64 100644 --- a/internal/platform/implementation/apple/ble.mm +++ b/internal/platform/implementation/apple/ble.mm @@ -511,6 +511,13 @@ bool BleMedium::GattServer::UpdateCharacteristic( return true; } +absl::Status BleMedium::GattServer::NotifyCharacteristicChanged( + const api::ble_v2::GattCharacteristic& characteristic, bool confirm, + const ByteArray& new_value) { + // no-op because client cannot request notifications. + return absl::UnimplementedError("Unimplemented!"); +} + void BleMedium::GattServer::Stop() { [peripheral_ stopGATTService]; } bool BleMedium::GattClient::DiscoverServiceAndCharacteristics( diff --git a/internal/platform/implementation/ble_v2.h b/internal/platform/implementation/ble_v2.h index d7a41098..9c87b77e 100644 --- a/internal/platform/implementation/ble_v2.h +++ b/internal/platform/implementation/ble_v2.h @@ -194,6 +194,7 @@ class GattClient { // https://developer.android.com/reference/android/bluetooth/BluetoothGattServer // // Representation of a BLE GATT server. +// LINT.IfChange class GattServer { public: virtual ~GattServer() = default; @@ -223,9 +224,18 @@ class GattServer { virtual bool UpdateCharacteristic(const GattCharacteristic& characteristic, const nearby::ByteArray& value) = 0; + // https://developer.android.com/reference/android/bluetooth/BluetoothGattServer#notifyCharacteristicChanged(android.bluetooth.BluetoothDevice,%20android.bluetooth.BluetoothGattCharacteristic,%20boolean,%20byte[]) + // + // Send a notification or indication that a local characteristic has been + // updated and returns an absl::Status indicating success or what went wrong. + virtual absl::Status NotifyCharacteristicChanged( + const GattCharacteristic& characteristic, bool confirm, + const ByteArray& new_value) = 0; + // Stops a GATT server. virtual void Stop() = 0; }; +// LINT.ThenChange(//depot/google3/third_party/nearby/internal/platform/ble_v2.h) // Callback for asynchronous events on the client side of a GATT connection. struct ClientGattConnectionCallback { diff --git a/internal/platform/implementation/g3/ble_v2.cc b/internal/platform/implementation/g3/ble_v2.cc index 80b92d85..5e60986a 100644 --- a/internal/platform/implementation/g3/ble_v2.cc +++ b/internal/platform/implementation/g3/ble_v2.cc @@ -375,6 +375,14 @@ bool BleV2Medium::GattServer::UpdateCharacteristic( return true; } +absl::Status BleV2Medium::GattServer::NotifyCharacteristicChanged( + const api::ble_v2::GattCharacteristic& characteristic, bool confirm, + const ByteArray& new_value) { + // check if client has requested notifications. + // no-op for now because client cannot request notifications. + return absl::UnimplementedError("Unimplemented!"); +} + void BleV2Medium::GattServer::Stop() { NEARBY_LOGS(INFO) << "G3 Ble GattServer Stop"; MediumEnvironment::Instance().ClearBleV2MediumGattCharacteristics(); diff --git a/internal/platform/implementation/g3/ble_v2.h b/internal/platform/implementation/g3/ble_v2.h index ccf86551..43223545 100644 --- a/internal/platform/implementation/g3/ble_v2.h +++ b/internal/platform/implementation/g3/ble_v2.h @@ -220,6 +220,10 @@ class BleV2Medium : public api::ble_v2::BleMedium { const api::ble_v2::GattCharacteristic& characteristic, const nearby::ByteArray& value) override; + absl::Status NotifyCharacteristicChanged( + const api::ble_v2::GattCharacteristic& characteristic, bool confirm, + const ByteArray& new_value) override; + void Stop() override; };