From 05cd950539ac475210e23a5806d3eb40338efa47 Mon Sep 17 00:00:00 2001 From: Janusz Sobczak Date: Fri, 28 Apr 2023 12:37:16 -0700 Subject: [PATCH] Add read,write callbacks to characteristics During Fast pair handshake, the seeker writes to GATT characteristics, the provider reads the value and sends the response. We need callbacks for reading and writing GATT characteristics to test the handshake. Static GATT DB entries are not sufficient. PiperOrigin-RevId: 527958868 --- internal/platform/ble_v2.cc | 23 ++++++++++++++++++++ internal/platform/ble_v2.h | 26 +++++++++++++++++------ internal/platform/implementation/ble_v2.h | 22 +++++++++++++++++++ 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/internal/platform/ble_v2.cc b/internal/platform/ble_v2.cc index 584062d3..d6b5bff5 100644 --- a/internal/platform/ble_v2.cc +++ b/internal/platform/ble_v2.cc @@ -26,9 +26,15 @@ namespace nearby { +namespace { using ::nearby::api::ble_v2::BleAdvertisementData; using ::nearby::api::ble_v2::GattCharacteristic; using ::nearby::api::ble_v2::TxPowerLevel; +using ReadValueCallback = + ::nearby::api::ble_v2::ServerGattConnectionCallback::ReadValueCallback; +using WriteValueCallback = + ::nearby::api::ble_v2::ServerGattConnectionCallback::WriteValueCallback; +} // namespace bool BleV2Medium::StartAdvertising( const BleAdvertisementData& advertising_data, @@ -205,6 +211,23 @@ std::unique_ptr BleV2Medium::StartGattServer( server_gatt_connection_callback_ .characteristic_unsubscription_cb(characteristic); }, + .on_characteristic_read_cb = + [this](const api::ble_v2::BlePeripheral& remote_device, + const GattCharacteristic& characteristic, int offset, + ReadValueCallback callback) { + MutexLock lock(&mutex_); + server_gatt_connection_callback_.on_characteristic_read_cb( + remote_device, characteristic, offset, std::move(callback)); + }, + .on_characteristic_write_cb = + [this](const api::ble_v2::BlePeripheral& remote_device, + const GattCharacteristic& characteristic, int offset, + absl::string_view data, WriteValueCallback callback) { + MutexLock lock(&mutex_); + server_gatt_connection_callback_.on_characteristic_write_cb( + remote_device, characteristic, offset, data, + std::move(callback)); + }, }); return std::make_unique(std::move(api_gatt_server)); } diff --git a/internal/platform/ble_v2.h b/internal/platform/ble_v2.h index 8feca81c..dfdcb1ef 100644 --- a/internal/platform/ble_v2.h +++ b/internal/platform/ble_v2.h @@ -276,14 +276,28 @@ class BleV2Medium final { const api::ble_v2::BleAdvertisementData&>(); }; struct ServerGattConnectionCallback { - absl::AnyInvocable + using BlePeripheral = api::ble_v2::BlePeripheral; + using GattCharacteristic = api::ble_v2::GattCharacteristic; + using ReadValueCallback = + api::ble_v2::ServerGattConnectionCallback::ReadValueCallback; + using WriteValueCallback = + api::ble_v2::ServerGattConnectionCallback::WriteValueCallback; + + absl::AnyInvocable characteristic_subscription_cb = - nearby::DefaultCallback(); - absl::AnyInvocable + nearby::DefaultCallback(); + absl::AnyInvocable characteristic_unsubscription_cb = - nearby::DefaultCallback(); + nearby::DefaultCallback(); + absl::AnyInvocable + on_characteristic_read_cb; + absl::AnyInvocable + on_characteristic_write_cb; }; // TODO(b/231318879): Remove this wrapper callback and use impl callback if // there is only disconnect function here in the end. diff --git a/internal/platform/implementation/ble_v2.h b/internal/platform/implementation/ble_v2.h index b2aaefea..8dd5ad50 100644 --- a/internal/platform/implementation/ble_v2.h +++ b/internal/platform/implementation/ble_v2.h @@ -27,6 +27,7 @@ #include "absl/container/flat_hash_map.h" #include "absl/functional/any_invocable.h" #include "absl/status/status.h" +#include "absl/status/statusor.h" #include "absl/strings/string_view.h" #include "internal/platform/byte_array.h" #include "internal/platform/cancellation_flag.h" @@ -284,6 +285,9 @@ struct ClientGattConnectionCallback { // Callback for asynchronous events on the server side of a GATT connection. struct ServerGattConnectionCallback { + using ReadValueCallback = + absl::AnyInvocable data)>; + using WriteValueCallback = absl::AnyInvocable; // Called when a remote peripheral connected to us and subscribed to one of // our characteristics. absl::AnyInvocable @@ -293,6 +297,24 @@ struct ServerGattConnectionCallback { // characteristics. absl::AnyInvocable characteristic_unsubscription_cb; + + // Called when a gatt client is reading from the characteristic. + // Must call `callback` with the read result. + // When a characteristic has a static value set with + // `GattServer::UpdateCharacteristic()`, then reading from the characteristic + // yields that static value. The read callback is not called. + // Otherwise, the gatt server calls the read callback to get the value. + absl::AnyInvocable + on_characteristic_read_cb; + + // Called when a gatt client is writing to the characteristic. + // Must call `callback` with the write result. + absl::AnyInvocable + on_characteristic_write_cb; }; // A BLE GATT client socket for requesting GATT socket.