From 82b2c63a7ccdda7fb2cb8e69e7deab8d273a75f7 Mon Sep 17 00:00:00 2001 From: Anay Wadhera Date: Thu, 8 Dec 2022 16:22:08 -0800 Subject: [PATCH] Implement BleConnectionInfo as a container for BLE mac address. Move PresenceDevice to use BleConnectionInfo. PiperOrigin-RevId: 494023973 --- Package.swift | 1 + connections/BUILD | 3 +- internal/device.h | 9 +- internal/platform/BUILD | 4 + internal/platform/ble_connection_info.cc | 30 +++++++ internal/platform/ble_connection_info.h | 65 ++++++++++++++ internal/platform/ble_connection_info_test.cc | 86 +++++++++++++++++++ internal/platform/bluetooth_connection_info.h | 2 - internal/platform/connection_info.h | 4 + presence/presence_device.cc | 12 +-- presence/presence_device.h | 7 +- presence/presence_device_test.cc | 6 +- 12 files changed, 206 insertions(+), 23 deletions(-) create mode 100644 internal/platform/ble_connection_info.cc create mode 100644 internal/platform/ble_connection_info.h create mode 100644 internal/platform/ble_connection_info_test.cc diff --git a/Package.swift b/Package.swift index cb180fb4..30676e7d 100644 --- a/Package.swift +++ b/Package.swift @@ -501,6 +501,7 @@ let package = Package( "internal/platform/atomic_reference_test.cc", "internal/platform/logging_test.cc", "internal/platform/multi_thread_executor_test.cc", + "internal/platform/ble_connection_info_test.cc", "internal/platform/ble_test.cc", "internal/platform/ble_v2_test.cc", "internal/platform/prng_test.cc", diff --git a/connections/BUILD b/connections/BUILD index 301d4e14..a939ae41 100644 --- a/connections/BUILD +++ b/connections/BUILD @@ -99,8 +99,8 @@ cc_test( deps = [ ":core", ":core_types", - "//connections/implementation:internal", "//connections/implementation:internal_test", + "//internal:device", "//internal/platform:base", "//internal/platform:logging", "//internal/platform:types", @@ -108,7 +108,6 @@ cc_test( "@com_github_protobuf_matchers//protobuf-matchers", "@com_google_absl//absl/strings", "@com_google_absl//absl/time", - "@com_google_absl//absl/types:variant", "@com_google_googletest//:gtest_main", ], ) diff --git a/internal/device.h b/internal/device.h index 5f49c509..ef5f5c75 100644 --- a/internal/device.h +++ b/internal/device.h @@ -20,12 +20,17 @@ #include "absl/strings/string_view.h" #include "absl/types/variant.h" +#include "internal/platform/ble_connection_info.h" #include "internal/platform/bluetooth_connection_info.h" #include "internal/platform/wifi_lan_connection_info.h" namespace location { namespace nearby { +using ConnectionInfoVariant = + absl::variant; + class NearbyDevice { public: enum Type { @@ -43,9 +48,7 @@ class NearbyDevice { virtual absl::string_view GetEndpointInfo() const = 0; // We will be adding more ConnectionInfo types to this variant as they are // implemented. - virtual std::vector< - absl::variant> - GetConnectionInfos() const = 0; + virtual std::vector GetConnectionInfos() const = 0; virtual Type GetType() const { return Type::kUnknownDevice; } }; diff --git a/internal/platform/BUILD b/internal/platform/BUILD index ad014181..8be21119 100644 --- a/internal/platform/BUILD +++ b/internal/platform/BUILD @@ -144,10 +144,12 @@ cc_library( cc_library( name = "connection_info", srcs = [ + "ble_connection_info.cc", "bluetooth_connection_info.cc", "wifi_lan_connection_info.cc", ], hdrs = [ + "ble_connection_info.h", "bluetooth_connection_info.h", "connection_info.h", "wifi_lan_connection_info.h", @@ -161,6 +163,7 @@ cc_library( ], deps = [ ":base", + "@com_google_absl//absl/log", "@com_google_absl//absl/status", "@com_google_absl//absl/status:statusor", "@com_google_absl//absl/strings", @@ -424,6 +427,7 @@ cc_test( srcs = [ "atomic_boolean_test.cc", "atomic_reference_test.cc", + "ble_connection_info_test.cc", "ble_test.cc", "ble_v2_test.cc", "bluetooth_adapter_test.cc", diff --git a/internal/platform/ble_connection_info.cc b/internal/platform/ble_connection_info.cc new file mode 100644 index 00000000..c3c37b5a --- /dev/null +++ b/internal/platform/ble_connection_info.cc @@ -0,0 +1,30 @@ +// Copyright 2022 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 "internal/platform/ble_connection_info.h" + +#include +#include + +namespace location { +namespace nearby { + +ByteArray BleConnectionInfo::ToBytes() const { return ByteArray(mac_address_); } + +BleConnectionInfo BleConnectionInfo::FromBytes(ByteArray bytes) { + std::string serial(bytes.AsStringView()); + return BleConnectionInfo(serial.substr(0, kMacAddressLength)); +} +} // namespace nearby +} // namespace location diff --git a/internal/platform/ble_connection_info.h b/internal/platform/ble_connection_info.h new file mode 100644 index 00000000..931a78ae --- /dev/null +++ b/internal/platform/ble_connection_info.h @@ -0,0 +1,65 @@ +// Copyright 2022 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 THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_BLE_CONNECTION_INFO_H_ +#define THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_BLE_CONNECTION_INFO_H_ + +#include + +#include "absl/log/log.h" +#include "absl/strings/string_view.h" +#include "internal/platform/byte_array.h" +#include "internal/platform/connection_info.h" + +namespace location { +namespace nearby { + +// 6 bytes that spell "BADMAC" +constexpr absl::string_view kDefunctMacAddr = "\x42\x41\x44\x4D\x41\x43"; + +class BleConnectionInfo : public ConnectionInfo { + public: + explicit BleConnectionInfo(absl::string_view mac_address) + : mac_address_(std::string(mac_address)) { + if (mac_address_.size() != kMacAddressLength) { + LOG(WARNING) << "MAC address is not of the expected length! Trying to " + "connect to this MAC address will not work!"; + mac_address_ = std::string(kDefunctMacAddr); + } + } + + BleConnectionInfo(BleConnectionInfo const& info) { + mac_address_ = info.mac_address_; + } + MediumType GetMediumType() const override { return MediumType::kBle; } + ByteArray ToBytes() const override; + static BleConnectionInfo FromBytes(ByteArray bytes); + ByteArray GetMacAddress() const { return ByteArray(mac_address_); } + + private: + std::string mac_address_; +}; + +inline bool operator==(const BleConnectionInfo& a, const BleConnectionInfo& b) { + return a.GetMacAddress() == b.GetMacAddress(); +} + +inline bool operator!=(const BleConnectionInfo& a, const BleConnectionInfo& b) { + return !(a == b); +} + +} // namespace nearby +} // namespace location + +#endif // THIRD_PARTY_NEARBY_INTERNAL_PLATFORM_BLE_CONNECTION_INFO_H_ diff --git a/internal/platform/ble_connection_info_test.cc b/internal/platform/ble_connection_info_test.cc new file mode 100644 index 00000000..d10da133 --- /dev/null +++ b/internal/platform/ble_connection_info_test.cc @@ -0,0 +1,86 @@ +// Copyright 2022 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 "internal/platform/ble_connection_info.h" + +#include + +#include "gmock/gmock.h" +#include "protobuf-matchers/protocol-buffer-matchers.h" +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" +#include "internal/platform/byte_array.h" + +namespace location { +namespace nearby { +namespace { + +constexpr absl::string_view kMacAddr = "\x4C\x8B\x1D\xCE\xBA\xD1"; + +TEST(BleConnectionInfoTest, TestMediumType) { + BleConnectionInfo info(kMacAddr); + EXPECT_EQ(info.GetMediumType(), BleConnectionInfo::MediumType::kBle); +} + +TEST(BleConnectionInfoTest, TestToBytes) { + ByteArray mac_addr_bytes = ByteArray(std::string(kMacAddr)); + BleConnectionInfo info(kMacAddr); + EXPECT_EQ(info.ToBytes(), mac_addr_bytes); +} + +TEST(BleConnectionInfoTest, TestFromBytes) { + ByteArray mac_addr_bytes = ByteArray(std::string(kMacAddr)); + BleConnectionInfo info = BleConnectionInfo::FromBytes(mac_addr_bytes); + EXPECT_EQ(info.GetMacAddress(), mac_addr_bytes); +} + +TEST(BleConnectionInfoTest, TestGetMacAddress) { + ByteArray mac_addr_bytes = ByteArray(std::string(kMacAddr)); + BleConnectionInfo info(kMacAddr); + EXPECT_EQ(info.GetMacAddress(), mac_addr_bytes); +} + +TEST(BleConnectionInfoTest, TestGetLongMacAddr) { + BleConnectionInfo info(absl::StrCat(kMacAddr, "\x56\x70\x89")); + EXPECT_EQ(info.GetMacAddress().AsStringView(), kDefunctMacAddr); +} + +TEST(BleConnectionInfoTest, TestGetShortMacAddr) { + BleConnectionInfo info("\x56\x70\x89"); + EXPECT_EQ(info.GetMacAddress().AsStringView(), kDefunctMacAddr); +} + +TEST(BleConnectionInfoTest, TestToFromBytes) { + BleConnectionInfo info(kMacAddr); + ByteArray serialized = info.ToBytes(); + BleConnectionInfo result = BleConnectionInfo::FromBytes(serialized); + EXPECT_EQ(result, info); +} + +TEST(BleConnectionInfoTest, TestCopy) { + BleConnectionInfo info(kMacAddr); + BleConnectionInfo copy(info); + EXPECT_EQ(info, copy); +} + +TEST(BleConnectionInfoTest, TestEquals) { + BleConnectionInfo info(kMacAddr); + BleConnectionInfo info2(kMacAddr); + EXPECT_EQ(info, info2); +} + +} // namespace +} // namespace nearby +} // namespace location diff --git a/internal/platform/bluetooth_connection_info.h b/internal/platform/bluetooth_connection_info.h index 1a7e9a5b..51b42887 100644 --- a/internal/platform/bluetooth_connection_info.h +++ b/internal/platform/bluetooth_connection_info.h @@ -24,8 +24,6 @@ namespace location { namespace nearby { -constexpr int kMacAddressLength = 6; - class BluetoothConnectionInfo : public ConnectionInfo { public: MediumType GetMediumType() const override { return MediumType::kBluetooth; } diff --git a/internal/platform/connection_info.h b/internal/platform/connection_info.h index 52a6c9db..fb542d2b 100644 --- a/internal/platform/connection_info.h +++ b/internal/platform/connection_info.h @@ -19,12 +19,16 @@ namespace location { namespace nearby { + +constexpr int kMacAddressLength = 6; + class ConnectionInfo { public: enum class MediumType { kUnknown = 0, kBluetooth = 1, kWifiLan = 2, + kBle = 3, }; virtual ~ConnectionInfo() = default; virtual MediumType GetMediumType() const = 0; diff --git a/presence/presence_device.cc b/presence/presence_device.cc index 533de492..c27a2510 100644 --- a/presence/presence_device.cc +++ b/presence/presence_device.cc @@ -18,9 +18,8 @@ #include #include "internal/crypto/random.h" -#include "internal/platform/bluetooth_connection_info.h" +#include "internal/platform/ble_connection_info.h" #include "internal/platform/implementation/system_clock.h" -#include "internal/platform/wifi_lan_connection_info.h" #include "presence/device_motion.h" namespace nearby { @@ -46,13 +45,10 @@ PresenceDevice::PresenceDevice(DeviceMotion device_motion, endpoint_id_ = GenerateRandomEndpointId(); } -std::vector> +std::vector PresenceDevice::GetConnectionInfos() const { - location::nearby::BluetoothConnectionInfo bluetooth_connection_info( - location::nearby::ByteArray(device_metadata_.bluetooth_mac_address()), - "Nearby Presence"); - return {bluetooth_connection_info}; + return {location::nearby::BleConnectionInfo( + device_metadata_.bluetooth_mac_address())}; } } // namespace presence } // namespace nearby diff --git a/presence/presence_device.h b/presence/presence_device.h index d0a9b00f..48ade932 100644 --- a/presence/presence_device.h +++ b/presence/presence_device.h @@ -22,8 +22,6 @@ #include "absl/time/time.h" #include "absl/types/variant.h" #include "internal/device.h" -#include "internal/platform/bluetooth_connection_info.h" -#include "internal/platform/wifi_lan_connection_info.h" #include "internal/proto/device_metadata.pb.h" #include "presence/device_motion.h" @@ -48,9 +46,8 @@ class PresenceDevice : public location::nearby::NearbyDevice { return NearbyDevice::Type::kPresenceDevice; } // Add more medium ConnectionInfos as we introduce them. - std::vector> - GetConnectionInfos() const override; + std::vector GetConnectionInfos() + const override; DeviceMotion GetDeviceMotion() const { return device_motion_; } DeviceMetadata GetMetadata() const { return device_metadata_; } absl::Time GetDiscoveryTimestamp() const { return discovery_timestamp_; } diff --git a/presence/presence_device_test.cc b/presence/presence_device_test.cc index a682f302..fadec235 100644 --- a/presence/presence_device_test.cc +++ b/presence/presence_device_test.cc @@ -20,7 +20,7 @@ #include "protobuf-matchers/protocol-buffer-matchers.h" #include "gtest/gtest.h" #include "absl/types/variant.h" -#include "internal/platform/bluetooth_connection_info.h" +#include "internal/platform/ble_connection_info.h" #include "internal/platform/logging.h" #include "internal/proto/device_metadata.pb.h" @@ -76,8 +76,8 @@ TEST(PresenceDeviceTest, TestGetBluetoothAddress) { PresenceDevice device = PresenceDevice({kDefaultMotionType}, metadata); auto info = (device.GetConnectionInfos().at(0)); ASSERT_TRUE( - absl::holds_alternative(info)); - EXPECT_EQ(absl::get(info) + absl::holds_alternative(info)); + EXPECT_EQ(absl::get(info) .GetMacAddress() .AsStringView(), kMacAddr);