From 011a201ee21da4a720899b4105a39f7195679e4d Mon Sep 17 00:00:00 2001 From: hais Date: Wed, 1 Sep 2021 13:11:36 -0700 Subject: [PATCH] Check in BLE cal interface. PiperOrigin-RevId: 394298358 --- cpp/cal/api/BUILD | 33 +++++++ cpp/cal/api/ble.h | 180 ++++++++++++++++++++++++++++++++++++ cpp/cal/base/BUILD | 30 ++++++ cpp/cal/base/ble_types.h | 78 ++++++++++++++++ cpp/cal/public/BUILD | 50 ++++++++++ cpp/cal/public/ble.cc | 103 +++++++++++++++++++++ cpp/cal/public/ble.h | 102 +++++++++++++++++++++ cpp/cal/public/ble_test.cc | 182 +++++++++++++++++++++++++++++++++++++ cpp/platform/base/BUILD | 1 + 9 files changed, 759 insertions(+) create mode 100644 cpp/cal/api/BUILD create mode 100644 cpp/cal/api/ble.h create mode 100644 cpp/cal/base/BUILD create mode 100644 cpp/cal/base/ble_types.h create mode 100644 cpp/cal/public/BUILD create mode 100644 cpp/cal/public/ble.cc create mode 100644 cpp/cal/public/ble.h create mode 100644 cpp/cal/public/ble_test.cc diff --git a/cpp/cal/api/BUILD b/cpp/cal/api/BUILD new file mode 100644 index 00000000..895cb796 --- /dev/null +++ b/cpp/cal/api/BUILD @@ -0,0 +1,33 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "ble", + hdrs = [ + "ble.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = [ + "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", + "//third_party/nearby_connections/cpp:__subpackages__", + ], + deps = [ + "//absl/strings", + "//absl/time", + "//absl/types:optional", + "//third_party/nearby_connections/cpp/cal/base:types", + ], +) diff --git a/cpp/cal/api/ble.h b/cpp/cal/api/ble.h new file mode 100644 index 00000000..80682b4e --- /dev/null +++ b/cpp/cal/api/ble.h @@ -0,0 +1,180 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CAL_API_BLE_H_ +#define CAL_API_BLE_H_ + +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "absl/time/time.h" +#include "absl/types/optional.h" +#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" +namespace nearby { +namespace cal { +namespace api { + +class BlePeripheral { + public: + virtual ~BlePeripheral() {} + virtual std::string GetName() const = 0; + virtual std::string GetAddress() const = 0; + virtual ByteArray GetAdvertisementBytes() const = 0; +}; + +struct ScanResult { + std::unique_ptr peripheral; + int rssi; + int tx_power; + absl::Time timestamp; +}; + +class GattCharacteristic { + public: + virtual ~GattCharacteristic() {} + + enum class Permission { + kUnknown = 0, + kRead = 1, + kWrite = 2, + kLast, + }; + + enum class Property { + kUnknown = 0, + kRead = 1, + kWrite = 2, + kIndicate = 3, + kLast, + }; + + virtual std::string GetServiceUuid() = 0; +}; + +class ClientGattConnection { + public: + virtual ~ClientGattConnection() {} + virtual BlePeripheral& GetPeripheral() = 0; + virtual bool DiscoverServices() = 0; + virtual absl::optional GetCharacteristic( + absl::string_view service_uuid, + absl::string_view characteristic_uuid) = 0; + virtual absl::optional ReadCharacteristic( + const GattCharacteristic& characteristic) = 0; + virtual bool WriteCharacteristic(const GattCharacteristic& characteristic, + const ByteArray& value) = 0; + virtual void Disconnect() = 0; + virtual bool SetCharacteristicNotification( + const GattCharacteristic& characteristic, bool enable) = 0; +}; + +class ServerGattConnection { + public: + virtual ~ServerGattConnection() {} + virtual bool SendCharacteristic(const GattCharacteristic& characteristic, + const ByteArray& value) = 0; +}; + +class ClientGattConnectionLifeCycleCallback { + public: + virtual ~ClientGattConnectionLifeCycleCallback() {} + virtual void OnDisconnected(ClientGattConnection* connection) = 0; + virtual void onConnectionStateChange(ClientGattConnection* connection) = 0; + virtual void onCharacteristicRead(ClientGattConnection* connection) = 0; +}; + +class ServerGattConnectionLifeCycleCallback { + public: + virtual ~ServerGattConnectionLifeCycleCallback() {} + virtual void OnCharacteristicSubscription( + ServerGattConnection* connection, + const GattCharacteristic& characteristic) = 0; + virtual void OnCharacteristicUnsubscription( + ServerGattConnection* connection, + const GattCharacteristic& characteristic) = 0; +}; + +class GattServer { + public: + virtual ~GattServer() {} + virtual std::unique_ptr CreateCharacteristic( + absl::string_view service_uuid, absl::string_view characteristic_uuid, + const std::set& permissions, + const std::set& properties) = 0; + virtual bool UpdateCharacteristic(const GattCharacteristic& characteristic, + const ByteArray& value) = 0; + virtual void Stop() = 0; +}; + +class BleSocket { + public: + virtual ~BleSocket() {} + virtual api::BlePeripheral& GetRemotePeripheral() = 0; + virtual Exception Write(const ByteArray& message) = 0; + virtual Exception Close() = 0; + virtual InputStream& GetInputStream() = 0; + virtual OutputStream& GetOutputStream() = 0; +}; + +class BleSocketLifeCycleCallback { + public: + virtual ~BleSocketLifeCycleCallback() {} + virtual void OnMessageReceived(BleSocket* socket, + const ByteArray& message) = 0; + virtual void OnDisconnected(BleSocket* socket) = 0; +}; + +class ServerBleSocketLifeCycleCallback : public BleSocketLifeCycleCallback { + public: + ~ServerBleSocketLifeCycleCallback() override {} + virtual void OnSocketEstablished(BleSocket* socket) = 0; +}; + +class BleMedium { + public: + using Mtu = uint32_t; + virtual ~BleMedium() {} + virtual bool StartAdvertising( + const BleAdvertisementData& advertisement_data) = 0; + virtual void StopAdvertising(const std::string& service_id) = 0; + class ScanCallback { + public: + virtual ~ScanCallback() {} + virtual void OnAdvertisementFound( + const ScanResult& scan_result, + const BleAdvertisementData& advertisement_data) = 0; + }; + virtual bool StartScanning(const std::set& service_uuids, + PowerMode power_mode, + const ScanCallback& scan_callback) = 0; + virtual void StopScanning() = 0; + virtual std::unique_ptr StartGattServer( + const ServerGattConnectionLifeCycleCallback& callback) = 0; + virtual bool StartListeningForIncomingBleSockets( + const ServerBleSocketLifeCycleCallback& callback) = 0; + virtual void StopListeningForIncomingBleSockets() = 0; + virtual std::unique_ptr ConnectToGattServer( + BlePeripheral* peripheral, Mtu mtu, PowerMode power_mode, + const ClientGattConnectionLifeCycleCallback& callback) = 0; + virtual std::unique_ptr EstablishBleSocket( + BlePeripheral* peripheral, + const BleSocketLifeCycleCallback& callback) = 0; +}; + +} // namespace api +} // namespace cal +} // namespace nearby +#endif // CAL_API_BLE_H_ diff --git a/cpp/cal/base/BUILD b/cpp/cal/base/BUILD new file mode 100644 index 00000000..aa9e115e --- /dev/null +++ b/cpp/cal/base/BUILD @@ -0,0 +1,30 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "types", + hdrs = [ + "ble_types.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = [ + "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", + "//third_party/nearby_connections/cpp:__subpackages__", + ], + deps = [ + "//platform/base", + ], +) diff --git a/cpp/cal/base/ble_types.h b/cpp/cal/base/ble_types.h new file mode 100644 index 00000000..3dba08fb --- /dev/null +++ b/cpp/cal/base/ble_types.h @@ -0,0 +1,78 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CAL_BASE_TYPES_H_ +#define CAL_BASE_TYPES_H_ +// TODO(hais) relocate base def class accordingly. +#include + +#include "platform/base/byte_array.h" +#include "platform/base/exception.h" +#include "platform/base/input_stream.h" +#include "platform/base/listeners.h" +#include "platform/base/output_stream.h" + +namespace nearby { +namespace cal { + +using ByteArray = location::nearby::ByteArray; +using Exception = location::nearby::Exception; +using InputStream = location::nearby::InputStream; +using OutputStream = location::nearby::OutputStream; + +enum class AdvertiseMode { + kUnknown = 0, + kLowPower = 1, + kBalanced = 2, + kLowLatency = 3, +}; + +enum class PowerMode { + kUnknown = 0, + kUltraLow = 1, + kLow = 2, + kMedium = 3, + kHigh = 4, +}; + +struct AdvertiseSettings { + AdvertiseMode advertise_mode; + PowerMode poser_mode; + int timeout; + bool is_connectable; + std::string local_name; +}; + +struct BleAdvertisementData { + AdvertiseSettings advertise_settings; + // service UUID to advertise bytes map + std::map service_data_map; +}; + +enum class ScanMode { + kUnknown = 0, + kLowPower, + kBalanced, + kLowLatency, + // kOpportunistic not supported +}; + +struct ScanSettings { + ScanMode scan_mode; + // Do we need reportDelay, phy, legacy? +}; + +} // namespace cal +} // namespace nearby +#endif // CAL_BASE_TYPES_H_ diff --git a/cpp/cal/public/BUILD b/cpp/cal/public/BUILD new file mode 100644 index 00000000..ab5ecaaf --- /dev/null +++ b/cpp/cal/public/BUILD @@ -0,0 +1,50 @@ +# Copyright 2020 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +licenses(["notice"]) + +cc_library( + name = "ble", + srcs = [ + "ble.cc", + ], + hdrs = [ + "ble.h", + ], + compatible_with = ["//buildenv/target:non_prod"], + visibility = [ + "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", + "//third_party/nearby_connections/cpp:__subpackages__", + ], + deps = [ + "//third_party/nearby_connections/cpp/cal/api:ble", + "//third_party/nearby_connections/cpp/cal/base:types", + ], +) + +cc_test( + name = "cal_test", + size = "small", + timeout = "moderate", + srcs = [ + "ble_test.cc", + ], + deps = [ + ":ble", + "//testing/base/public:gunit", + "//testing/base/public:gunit_main", + "//third_party/nearby_connections/cpp/cal/api:ble", + "//third_party/nearby_connections/cpp/cal/base:types", + ], +) diff --git a/cpp/cal/public/ble.cc b/cpp/cal/public/ble.cc new file mode 100644 index 00000000..f460b447 --- /dev/null +++ b/cpp/cal/public/ble.cc @@ -0,0 +1,103 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "third_party/nearby_connections/cpp/cal/public/ble.h" + +#include + +#include "third_party/nearby_connections/cpp/cal/api/ble.h" +#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" + +namespace nearby { +namespace cal { + +InputStream& BleSocket::GetInputStream() { return impl_->GetInputStream(); } +OutputStream& BleSocket::GetOutputStream() { return impl_->GetOutputStream(); } +Exception BleSocket::Close() { return impl_->Close(); } +api::BlePeripheral& BleSocket::GetRemotePeripheral() { + return impl_->GetRemotePeripheral(); +} +bool BleSocket::IsValid() const { return false; } +api::BleSocket& BleSocket::GetImpl() { return *impl_; } + +BlePeripheral::BlePeripheral(api::BlePeripheral* peripheral) { + impl_ = peripheral; +} +std::string BlePeripheral::GetName() const { return impl_->GetName(); } +std::string BlePeripheral::GetAddress() const { return impl_->GetAddress(); } +ByteArray BlePeripheral::GetAdvertisementBytes( + const std::string& service_id) const { + return impl_->GetAdvertisementBytes(); +} +api::BlePeripheral& BlePeripheral::GetImpl() { return *impl_; } +bool BlePeripheral::IsValid() const { return impl_ != nullptr; } + +BleMedium::BleMedium(std::unique_ptr impl) { + impl_ = std::move(impl); +} + +bool BleMedium::StartAdvertising(const std::string& service_id, + const AdvertiseSettings& settings, + const ByteArray& advertisement_bytes, + const std::string& service_uuid) { + return impl_->StartAdvertising( + BleAdvertisementData{.advertise_settings = settings, + .service_data_map = std::map( + {{service_uuid, advertisement_bytes}})}); +} +bool BleMedium::StopAdvertising(const std::string& service_id) { + // TODO(hais): real impl b/196132654. + impl_->StopAdvertising(service_id); + return true; +} +bool BleMedium::StartScanning( + const std::string& service_id, const ScanSettings& settings, + const std::string& fast_advertisement_service_uuid, + DiscoveredPeripheralCallback callback) { + // TODO(hais): real impl b/196132654. + return false; +} +bool BleMedium::StopScanning(const std::string& service_id) { + // TODO(hais): real impl b/196132654. + return false; +} + +bool BleMedium::StartAcceptingConnections(const std::string& service_id, + AcceptedConnectionCallback callback) { + // TODO(hais): real impl b/196132654. + return false; +} + +bool cal::BleMedium::StopAcceptingConnections(const std::string& service_id) { + // TODO(hais): real impl b/196132654. + return false; +} +std::unique_ptr cal::BleMedium::ConnectGatt( + nearby::cal::api::BlePeripheral& peripheral, + const api::GattCharacteristic& characteristic, + const api::ClientGattConnectionLifeCycleCallback& callback) { + // TODO(hais): real impl b/196132654. + return impl_->ConnectToGattServer(&peripheral, -1, PowerMode::kUnknown, + callback); +} +void cal::BleMedium::DisconnectGatt( + api::BlePeripheral& peripheral, + const api::GattCharacteristic& characteristic) { + // TODO(hais): real impl b/196132654. +} +bool cal::BleMedium::IsValid() const { return impl_ != nullptr; } +cal::api::BleMedium& cal::BleMedium::GetImpl() { return *impl_; } + +} // namespace cal +} // namespace nearby diff --git a/cpp/cal/public/ble.h b/cpp/cal/public/ble.h new file mode 100644 index 00000000..dab6d239 --- /dev/null +++ b/cpp/cal/public/ble.h @@ -0,0 +1,102 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CAL_PUBLIC_BLE_H_ +#define CAL_PUBLIC_BLE_H_ + +#include + +#include "third_party/nearby_connections/cpp/cal/api/ble.h" +#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" + +namespace nearby { +namespace cal { + +class BlePeripheral final { + explicit BlePeripheral(api::BlePeripheral* peripheral); + std::string GetName() const; + std::string GetAddress() const; + ByteArray GetAdvertisementBytes(const std::string& service_id) const; + api::BlePeripheral& GetImpl(); + bool IsValid() const; + + private: + api::BlePeripheral* impl_; +}; + +class BleSocket final { + InputStream& GetInputStream(); + OutputStream& GetOutputStream(); + Exception Close(); + api::BlePeripheral& GetRemotePeripheral(); + bool IsValid() const; + api::BleSocket& GetImpl(); + + private: + std::shared_ptr impl_; +}; + +class BleMedium final { + public: + struct DiscoveredPeripheralCallback { + std::function + peripheral_discovered_cb; + std::function + peripheral_lost_cb; + }; + + struct AcceptedConnectionCallback { + std::function + accepted_cb = + location::nearby::DefaultCallback(); + }; + + struct AcceptedConnectionInfo { + BleSocket socket; + }; + + explicit BleMedium(std::unique_ptr impl); + bool StartAdvertising(const std::string& service_id, + const AdvertiseSettings& settings, + const ByteArray& advertisement_bytes, + const std::string& fast_advertisement_service_uuid); + bool StopAdvertising(const std::string& service_id); + bool StartScanning(const std::string& service_id, + const ScanSettings& settings, + const std::string& fast_advertisement_service_uuid, + DiscoveredPeripheralCallback callback); + bool StopScanning(const std::string& service_id); + bool StartAcceptingConnections(const std::string& service_id, + AcceptedConnectionCallback callback); + bool StopAcceptingConnections(const std::string& service_id); + std::unique_ptr ConnectGatt( + api::BlePeripheral& peripheral, + const api::GattCharacteristic& characteristic, + const api::ClientGattConnectionLifeCycleCallback& callback); + void DisconnectGatt(api::BlePeripheral& peripheral, + const api::GattCharacteristic& characteristic); + bool IsValid() const; + api::BleMedium& GetImpl(); + + private: + std::unique_ptr impl_; +}; + +} // namespace cal +} // namespace nearby + +#endif // CAL_PUBLIC_BLE_H_ diff --git a/cpp/cal/public/ble_test.cc b/cpp/cal/public/ble_test.cc new file mode 100644 index 00000000..81ecdc47 --- /dev/null +++ b/cpp/cal/public/ble_test.cc @@ -0,0 +1,182 @@ +// Copyright 2020 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "third_party/nearby_connections/cpp/cal/api/ble.h" +#include "third_party/nearby_connections/cpp/cal/base/ble_types.h" +#include "third_party/nearby_connections/cpp/cal/public/ble.h" + +namespace nearby { +namespace cal { +namespace { + +class MockBlePeripheral : public api::BlePeripheral { + MOCK_METHOD(std::string, GetName, (), (const override)); + MOCK_METHOD(std::string, GetAddress, (), (const override)); + MOCK_METHOD(ByteArray, GetAdvertisementBytes, (), (const override)); +}; + +class MockGattCharacteristic : public api::GattCharacteristic { + MOCK_METHOD(std::string, GetServiceUuid, (), (override)); +}; + +class MockClientGattConnection : public api::ClientGattConnection { + public: + MOCK_METHOD(api::BlePeripheral&, GetPeripheral, (), (override)); + MOCK_METHOD(bool, DiscoverServices, (), (override)); + MOCK_METHOD(absl::optional, GetCharacteristic, + (absl::string_view service_uuid, + absl::string_view characteristic_uuid), + (override)); + MOCK_METHOD(absl::optional, ReadCharacteristic, + (const api::GattCharacteristic& characteristic), (override)); + MOCK_METHOD(bool, WriteCharacteristic, + (const api::GattCharacteristic& characteristic, + const ByteArray& value), + (override)); + MOCK_METHOD(void, Disconnect, (), (override)); + MOCK_METHOD(bool, SetCharacteristicNotification, + (const api::GattCharacteristic& characteristic, bool enable), + (override)); +}; + +class MockServerGattConnection : public api::ServerGattConnection { + public: + MOCK_METHOD(bool, SendCharacteristic, + (const api::GattCharacteristic& characteristic, + const ByteArray& value), + (override)); +}; + +class MockClientGattConnectionLifeCycleCallback + : public api::ClientGattConnectionLifeCycleCallback { + public: + MOCK_METHOD(void, OnDisconnected, (api::ClientGattConnection * connection), + (override)); + MOCK_METHOD(void, onConnectionStateChange, + (api::ClientGattConnection * connection), (override)); + MOCK_METHOD(void, onCharacteristicRead, + (api::ClientGattConnection * connection), (override)); +}; + +class MockServerGattConnectionLifeCycleCallback + : public api::ServerGattConnectionLifeCycleCallback { + public: + MOCK_METHOD(void, OnCharacteristicSubscription, + (api::ServerGattConnection * connection, + const api::GattCharacteristic& characteristic), + (override)); + MOCK_METHOD(void, OnCharacteristicUnsubscription, + (api::ServerGattConnection * connection, + const api::GattCharacteristic& characteristic), + (override)); +}; + +class MockGattServer : public api::GattServer { + public: + MOCK_METHOD(std::unique_ptr, CreateCharacteristic, + (absl::string_view service_uuid, + absl::string_view characteristic_uuid, + const std::set& permissions, + const std::set& properties), + (override)); + MOCK_METHOD(bool, UpdateCharacteristic, + (const api::GattCharacteristic& characteristic, + const ByteArray& value), + (override)); + MOCK_METHOD(void, Stop, (), (override)); +}; + +class MockBleSocket : public api::BleSocket { + public: + MOCK_METHOD(api::BlePeripheral&, GetRemotePeripheral, (), (override)); + MOCK_METHOD(Exception, Write, (const ByteArray& message), (override)); + MOCK_METHOD(Exception, Close, (), (override)); +}; + +class MockBleSocketLifeCycleCallback : public api::BleSocketLifeCycleCallback { + public: + MOCK_METHOD(void, OnMessageReceived, + (api::BleSocket * socket, const ByteArray& message), (override)); + MOCK_METHOD(void, OnDisconnected, (api::BleSocket * socket), (override)); +}; + +class MockServerBleSocketLifeCycleCallback + : public api::ServerBleSocketLifeCycleCallback { + public: + MOCK_METHOD(void, OnSocketEstablished, (api::BleSocket * socket), (override)); +}; + +class MockBleMedium : public api::BleMedium { + public: + MOCK_METHOD(bool, StartAdvertising, + (const BleAdvertisementData& advertisement_data), (override)); + MOCK_METHOD(void, StopAdvertising, (const std::string& service_id), + (override)); + class MockScanCallback : public api::BleMedium::ScanCallback { + public: + MOCK_METHOD(void, OnAdvertisementFound, + (const api::ScanResult& scan_result, + const BleAdvertisementData& advertisement_data), + (override)); + }; + MOCK_METHOD(bool, StartScanning, + (const std::set& service_uuids, PowerMode power_mode, + const ScanCallback& scan_callback), + (override)); + MOCK_METHOD(void, StopScanning, (), (override)); + MOCK_METHOD(std::unique_ptr, StartGattServer, + (const api::ServerGattConnectionLifeCycleCallback& callback), + (override)); + MOCK_METHOD(bool, StartListeningForIncomingBleSockets, + (const api::ServerBleSocketLifeCycleCallback& callback), + (override)); + MOCK_METHOD(void, StopListeningForIncomingBleSockets, (), (override)); + MOCK_METHOD(std::unique_ptr, ConnectToGattServer, + (api::BlePeripheral * peripheral, Mtu mtu, PowerMode power_mode, + const api::ClientGattConnectionLifeCycleCallback& callback), + (override)); + MOCK_METHOD(std::unique_ptr, EstablishBleSocket, + (api::BlePeripheral * peripheral, + const api::BleSocketLifeCycleCallback& callback), + (override)); +}; + +class BleTest : public ::testing::Test { + public: + ::nearby::cal::BleMedium ble_medium_{std::make_unique()}; + const std::string kServiceId = "BleTest"; + const AdvertiseSettings kAdvertiseSettings = AdvertiseSettings{}; + const ByteArray kAdvertisementBytes = ByteArray{"BleTestBytes"}; + const std::string kServiceUuid = "0x2fec"; + const BleAdvertisementData kBleAdvertisementData = { + kAdvertiseSettings, {{kServiceUuid, kAdvertisementBytes}}}; +}; + +TEST_F(BleTest, ConstructorWorks) { EXPECT_TRUE(ble_medium_.IsValid()); } + +TEST_F(BleTest, StartAdvertising) { + MockBleMedium* mock_ble_medium = + static_cast(&ble_medium_.GetImpl()); + EXPECT_CALL(*mock_ble_medium, StartAdvertising).Times(1); + ble_medium_.StartAdvertising(kServiceId, kAdvertiseSettings, + kAdvertisementBytes, kServiceId); +} + +} // namespace +} // namespace cal +} // namespace nearby diff --git a/cpp/platform/base/BUILD b/cpp/platform/base/BUILD index f5400441..6703d20c 100644 --- a/cpp/platform/base/BUILD +++ b/cpp/platform/base/BUILD @@ -44,6 +44,7 @@ cc_library( visibility = [ "//googlemac/iPhone/Shared/Nearby/Connections:__subpackages__", "//third_party/nearby_connections/cpp/analytics:__subpackages__", + "//third_party/nearby_connections/cpp/cal:__subpackages__", "//core:__subpackages__", "//platform:__subpackages__", "//platform/api:__subpackages__",