From 0738d06b0a942d6be2f0732cab22fe428429fbfe Mon Sep 17 00:00:00 2001 From: hai007 Date: Fri, 9 Oct 2020 14:14:41 -0700 Subject: [PATCH] Roll forward to cl/336363104 Signed-off-by: hai007 --- cpp/core_v2/internal/base_pcp_handler.cc | 70 +++--- cpp/core_v2/internal/base_pcp_handler.h | 16 +- cpp/core_v2/internal/ble_advertisement.cc | 88 ++++++-- cpp/core_v2/internal/ble_advertisement.h | 35 ++- .../internal/ble_advertisement_test.cc | 205 +++++++++++++----- cpp/core_v2/internal/bluetooth_device_name.cc | 62 +++++- cpp/core_v2/internal/bluetooth_device_name.h | 17 +- .../internal/bluetooth_device_name_test.cc | 95 ++++++-- cpp/core_v2/internal/bwu_manager.cc | 10 +- cpp/core_v2/internal/bwu_manager.h | 4 +- cpp/core_v2/internal/mediums/BUILD | 3 + cpp/core_v2/internal/mediums/ble.cc | 67 +++++- cpp/core_v2/internal/mediums/ble.h | 12 +- cpp/core_v2/internal/mediums/ble_test.cc | 12 +- .../mediums/ble_v2/ble_advertisement.cc | 12 +- .../mediums/ble_v2/ble_advertisement.h | 2 - .../mediums/ble_v2/ble_advertisement_test.cc | 12 + .../mediums/webrtc/connection_flow.cc | 9 + cpp/core_v2/internal/offline_frames.cc | 8 + cpp/core_v2/internal/offline_frames_test.cc | 5 +- .../internal/p2p_cluster_pcp_handler.cc | 30 ++- .../internal/p2p_cluster_pcp_handler.h | 1 + cpp/core_v2/internal/wifi_lan_service_info.cc | 64 ++++-- cpp/core_v2/internal/wifi_lan_service_info.h | 26 +-- .../internal/wifi_lan_service_info_test.cc | 75 +++++-- cpp/platform_v2/public/ble.cc | 4 +- cpp/platform_v2/public/ble.h | 7 +- cpp/platform_v2/public/ble_test.cc | 16 +- cpp/platform_v2/public/future.h | 3 + cpp/platform_v2/public/settable_future.h | 10 +- script/oss.py | 2 + 31 files changed, 728 insertions(+), 254 deletions(-) diff --git a/cpp/core_v2/internal/base_pcp_handler.cc b/cpp/core_v2/internal/base_pcp_handler.cc index 12fdb676..b2eb73f9 100644 --- a/cpp/core_v2/internal/base_pcp_handler.cc +++ b/cpp/core_v2/internal/base_pcp_handler.cc @@ -321,19 +321,19 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client, OnEndpointFound(client, webrtc_endpoint); } - auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id); - std::unique_ptr channel; - ConnectImplResult connect_impl_result; - auto remote_bluetooth_mac_address = BluetoothUtils::ToString(options.remote_bluetooth_mac_address); if (!remote_bluetooth_mac_address.empty()) { - auto additional_endpoint = GetRemoteBluetoothMacAddressEndpoint( - endpoint_id, remote_bluetooth_mac_address, discovered_endpoints); - if (additional_endpoint != nullptr) - discovered_endpoints.push_back(additional_endpoint.get()); + if (AddRemoteBluetoothMacAddressEndpoint(endpoint_id, + remote_bluetooth_mac_address)) + NEARBY_LOGS(INFO) << "Appended remote Bluetooth MAC Address endpoint " + << "[" << remote_bluetooth_mac_address << "]"; } + auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id); + std::unique_ptr channel; + ConnectImplResult connect_impl_result; + for (auto connect_endpoint : discovered_endpoints) { connect_impl_result = ConnectImpl(client, connect_endpoint); if (connect_impl_result.status.Ok()) { @@ -637,7 +637,17 @@ void BasePcpHandler::OnIncomingFrame(OfflineFrame& frame, const ConnectionResponseFrame& connection_response = frame.v1().connection_response(); - if (connection_response.status() == Status::kSuccess) { + // For backward compatible, here still check both status and + // response parameters until the response feature is roll out in all + // supported devices. + bool accepted = false; + if (connection_response.has_response()) { + accepted = + connection_response.response() == ConnectionResponseFrame::ACCEPT; + } else { + accepted = connection_response.status() == Status::kSuccess; + } + if (accepted) { NEARBY_LOG(INFO, "OnConnectionResponse: remote accepted; id=%s", endpoint_id.c_str()); client->RemoteEndpointAcceptedConnection(endpoint_id); @@ -978,27 +988,28 @@ proto::connections::Medium BasePcpHandler::ChooseBestUpgradeMedium( return proto::connections::Medium::UNKNOWN_MEDIUM; } -std::unique_ptr -BasePcpHandler::GetRemoteBluetoothMacAddressEndpoint( - std::string endpoint_id, std::string remote_bluetooth_mac_address, - std::vector endpoints) { +bool BasePcpHandler::AddRemoteBluetoothMacAddressEndpoint( + std::string endpoint_id, std::string remote_bluetooth_mac_address) { if (!discovery_options_.allowed.bluetooth) { - return nullptr; + return false; } + auto endpoints = GetDiscoveredEndpoints(endpoint_id); if (endpoints.empty()) { - NEARBY_LOGS(INFO) - << "Cannot append remote Bluetooth MAC Address, because endpointId " - << endpoint_id << " has not been discovered"; - return nullptr; + NEARBY_LOGS(INFO) << "Cannot append remote Bluetooth MAC Address endpoint, " + "because endpointId " + << endpoint_id << " has not been discovered " + << "[" << remote_bluetooth_mac_address << "]"; + return false; } for (auto endpoint : endpoints) { if (endpoint->medium == proto::connections::Medium::BLUETOOTH) { NEARBY_LOGS(INFO) - << "Cannot append remote Bluetooth MAC Address, because the " - "endpoint has already been found over Bluetooth."; - return nullptr; + << "Cannot append remote Bluetooth MAC Address endpoint, because the " + "endpoint has already been found over Bluetooth " + << "[" << remote_bluetooth_mac_address << "]"; + return false; } } @@ -1006,14 +1017,15 @@ BasePcpHandler::GetRemoteBluetoothMacAddressEndpoint( mediums_->GetBluetoothClassic().GetRemoteDevice( remote_bluetooth_mac_address); if (!remote_bluetooth_device.IsValid()) { - NEARBY_LOGS(INFO) - << "Cannot append remote Bluetooth MAC Address, because a valid " - "Bluetooth device could not be derived."; - return nullptr; + NEARBY_LOGS(INFO) << "Cannot append remote Bluetooth MAC Address endpoint, " + "because a valid " + "Bluetooth device could not be derived " + << "[" << remote_bluetooth_mac_address << "]"; + return false; } auto bluetooth_endpoint = - std::make_unique(BluetoothEndpoint{ + std::make_shared(BluetoothEndpoint{ { endpoint_id, endpoints[0]->endpoint_info, @@ -1022,9 +1034,9 @@ BasePcpHandler::GetRemoteBluetoothMacAddressEndpoint( }, remote_bluetooth_device, }); - NEARBY_LOGS(INFO) << "Appended remote Bluetooth device " - << remote_bluetooth_mac_address; - return bluetooth_endpoint; + + discovered_endpoints_.emplace(endpoint_id, std::move(bluetooth_endpoint)); + return true; } void BasePcpHandler::EvaluateConnectionResult(ClientProxy* client, diff --git a/cpp/core_v2/internal/base_pcp_handler.h b/cpp/core_v2/internal/base_pcp_handler.h index 262d92cb..7bc24478 100644 --- a/cpp/core_v2/internal/base_pcp_handler.h +++ b/cpp/core_v2/internal/base_pcp_handler.h @@ -70,6 +70,13 @@ Swapper MakeSwapper(T* value) { return Swapper(value); } +// Represents the WebRtc state that mediums are connectable or not. +enum class WebRtcState { + kUndefined = 0, + kConnectable = 1, + kUnconnectable = 2, +}; + // A base implementation of the PcpHandler interface that takes care of all // bookkeeping and handshake protocols that are common across all PcpHandler // implementations -- thus, every concrete PcpHandler implementation must extend @@ -399,10 +406,11 @@ class BasePcpHandler : public PcpHandler, proto::connections::Medium ChooseBestUpgradeMedium( const std::vector& supported_mediums); - std::unique_ptr - GetRemoteBluetoothMacAddressEndpoint( - std::string endpoint_id, std::string remote_bluetooth_mac_address, - std::vector endpoints); + // Returns true if the bluetooth endpoint based on remote bluetooth mac + // address is created and added into discovered_endpoints_ with key + // endpoint_id. + bool AddRemoteBluetoothMacAddressEndpoint( + std::string endpoint_id, std::string remote_bluetooth_mac_address); void ProcessPreConnectionInitiationFailure(const std::string& endpoint_id, EndpointChannel* channel, diff --git a/cpp/core_v2/internal/ble_advertisement.cc b/cpp/core_v2/internal/ble_advertisement.cc index 1ad5df12..303d2e81 100644 --- a/cpp/core_v2/internal/ble_advertisement.cc +++ b/cpp/core_v2/internal/ble_advertisement.cc @@ -2,6 +2,7 @@ #include +#include "core_v2/internal/base_pcp_handler.h" #include "platform_v2/base/base_input_stream.h" #include "platform_v2/public/logging.h" #include "absl/strings/escaping.h" @@ -14,23 +15,29 @@ BleAdvertisement::BleAdvertisement(Version version, Pcp pcp, const ByteArray& service_id_hash, const std::string& endpoint_id, const ByteArray& endpoint_info, - const std::string& bluetooth_mac_address) { + const std::string& bluetooth_mac_address, + const ByteArray& uwb_address, + WebRtcState web_rtc_state) { DoInitialize(/*fast_advertisement=*/false, version, pcp, service_id_hash, - endpoint_id, endpoint_info, bluetooth_mac_address); + endpoint_id, endpoint_info, bluetooth_mac_address, uwb_address, + web_rtc_state); } BleAdvertisement::BleAdvertisement(Version version, Pcp pcp, const std::string& endpoint_id, - const ByteArray& endpoint_info) { + const ByteArray& endpoint_info, + const ByteArray& uwb_address) { DoInitialize(/*fast_advertisement=*/true, version, pcp, {}, endpoint_id, - endpoint_info, {}); + endpoint_info, {}, uwb_address, WebRtcState::kUndefined); } void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version, Pcp pcp, const ByteArray& service_id_hash, const std::string& endpoint_id, const ByteArray& endpoint_info, - const std::string& bluetooth_mac_address) { + const std::string& bluetooth_mac_address, + const ByteArray& uwb_address, + WebRtcState web_rtc_state) { fast_advertisement_ = fast_advertisement; if (!fast_advertisement_) { if (service_id_hash.size() != kServiceIdHashLength) return; @@ -57,10 +64,13 @@ void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version, service_id_hash_ = service_id_hash; endpoint_id_ = endpoint_id; endpoint_info_ = endpoint_info; + uwb_address_ = uwb_address; if (!fast_advertisement_) { if (!BluetoothUtils::FromString(bluetooth_mac_address).Empty()) { bluetooth_mac_address_ = bluetooth_mac_address; } + + web_rtc_state_ = web_rtc_state; } } @@ -120,7 +130,7 @@ BleAdvertisement::BleAdvertisement(bool fast_advertisement, // The next 4 bytes are supposed to be the endpoint_id. endpoint_id_ = std::string{base_input_stream.ReadBytes(kEndpointIdLength)}; - // The next 1 byte are supposed to be the length of the endpoint_info. + // The next 1 byte is supposed to be the length of the endpoint_info. std::uint32_t expected_endpoint_info_length = base_input_stream.ReadUint8(); // The next x bytes are the endpoint info. (Max length is 131 bytes or 17 @@ -137,7 +147,7 @@ BleAdvertisement::BleAdvertisement(bool fast_advertisement, fast_advertisement_, expected_endpoint_info_length, endpoint_info_.size()); - // Clear enpoint_id for validadity. + // Clear enpoint_id for validity. endpoint_id_.clear(); return; } @@ -150,6 +160,35 @@ BleAdvertisement::BleAdvertisement(bool fast_advertisement, BluetoothUtils::ToString(bluetooth_mac_address_bytes); } + // The next 1 byte is supposed to be the length of the uwb_address. + std::uint32_t expected_uwb_address_length = base_input_stream.ReadUint8(); + // If the length of uwb_address is not zero, then retrieve it. + if (expected_uwb_address_length != 0) { + uwb_address_ = base_input_stream.ReadBytes(expected_uwb_address_length); + if (uwb_address_.Empty() || + uwb_address_.size() != expected_uwb_address_length) { + NEARBY_LOG(INFO, + "Cannot deserialize BleAdvertisement: " + "expected uwbAddress size to be %d bytes, got %" PRIu64, + expected_uwb_address_length, uwb_address_.size()); + + // Clear enpoint_id for validity. + endpoint_id_.clear(); + return; + } + } + + // The next 1 byte is extra field. + web_rtc_state_ = WebRtcState::kUndefined; + if (!fast_advertisement_) { + if (base_input_stream.IsAvailable(kExtraFieldLength)) { + auto extra_field = static_cast(base_input_stream.ReadUint8()); + web_rtc_state_ = (extra_field & kWebRtcConnectableFlagBitmask) == 1 + ? WebRtcState::kConnectable + : WebRtcState::kUnconnectable; + } + } + base_input_stream.Close(); } @@ -168,21 +207,21 @@ BleAdvertisement::operator ByteArray() const { if (fast_advertisement_) { // clang-format off out = absl::StrCat(std::string(1, version_and_pcp_byte), - endpoint_id_, - std::string(1, endpoint_info_.size()), - std::string(endpoint_info_)); + endpoint_id_, + std::string(1, endpoint_info_.size()), + std::string(endpoint_info_)); // clang-format on } else { // clang-format off out = absl::StrCat(std::string(1, version_and_pcp_byte), - std::string(service_id_hash_), - endpoint_id_, - std::string(1, endpoint_info_.size()), - std::string(endpoint_info_)); + std::string(service_id_hash_), + endpoint_id_, + std::string(1, endpoint_info_.size()), + std::string(endpoint_info_)); // clang-format on // The next 6 bytes are the bluetooth mac address. If bluetooth_mac_address - // is invalid or empty, we get back a null byte array. + // is invalid or empty, we get back a empty byte array. auto bluetooth_mac_address_bytes{ BluetoothUtils::FromString(bluetooth_mac_address_)}; if (!bluetooth_mac_address_bytes.Empty()) { @@ -190,6 +229,25 @@ BleAdvertisement::operator ByteArray() const { } } + // The next bytes are UWB address field. + if (!uwb_address_.Empty()) { + absl::StrAppend(&out, std::string(1, uwb_address_.size())); + absl::StrAppend(&out, std::string(uwb_address_)); + } else { + // Write UWB address with length 0 to be able to read the next field when + // decode. + absl::StrAppend(&out, std::string(1, uwb_address_.size())); + } + + // The next 1 byte is extra field. + if (!fast_advertisement_) { + int web_rtc_connectable_flag = + (web_rtc_state_ == WebRtcState::kConnectable) ? 1 : 0; + char extra_field_byte = static_cast(web_rtc_connectable_flag) & + kWebRtcConnectableFlagBitmask; + absl::StrAppend(&out, std::string(1, extra_field_byte)); + } + return ByteArray(std::move(out)); } diff --git a/cpp/core_v2/internal/ble_advertisement.h b/cpp/core_v2/internal/ble_advertisement.h index 3f1d04f3..1e7edcdb 100644 --- a/cpp/core_v2/internal/ble_advertisement.h +++ b/cpp/core_v2/internal/ble_advertisement.h @@ -1,6 +1,7 @@ #ifndef CORE_V2_INTERNAL_BLE_ADVERTISEMENT_H_ #define CORE_V2_INTERNAL_BLE_ADVERTISEMENT_H_ +#include "core_v2/internal/base_pcp_handler.h" #include "core_v2/internal/pcp.h" #include "platform_v2/base/bluetooth_utils.h" #include "platform_v2/base/byte_array.h" @@ -13,7 +14,7 @@ namespace connections { // Advertising + Discovery. // //

[VERSION][PCP][SERVICE_ID_HASH][ENDPOINT_ID][ENDPOINT_INFO_SIZE] -// [ENDPOINT_INFO][BLUETOOTH_MAC] +// [ENDPOINT_INFO][BLUETOOTH_MAC][UWB_ADDRESS_SIZE][UWB_ADDRESS][EXTRA_FIELD] // //

The fast version of this advertisement simply omits SERVICE_ID_HASH and // the Bluetooth MAC address. @@ -35,27 +36,35 @@ class BleAdvertisement { static constexpr int kServiceIdHashLength = 3; static constexpr int kEndpointIdLength = 4; static constexpr int kEndpointInfoSizeLength = 1; + static constexpr int kBluetoothMacAddressLength = + BluetoothUtils::kBluetoothMacAddressLength; + static constexpr int kUwbAddressSizeLength = 1; + static constexpr int kExtraFieldLength = 1; static constexpr int kEndpointInfoLengthBitmask = 0x0FF; + static constexpr int kWebRtcConnectableFlagBitmask = 0x01; static constexpr int kMinAdvertisementLength = kVersionAndPcpLength + kServiceIdHashLength + kEndpointIdLength + - kEndpointInfoSizeLength + BluetoothUtils::kBluetoothMacAddressLength; + kEndpointInfoSizeLength + kBluetoothMacAddressLength; // The difference between normal and fast advertisements is that the fast one // omits the SERVICE_ID_HASH and Bluetooth MAC address. This is done to save // space. - static constexpr int kMinFastAdvertisementLength = - kMinAdvertisementLength - kServiceIdHashLength - - BluetoothUtils::kBluetoothMacAddressLength; + static constexpr int kMinFastAdvertisementLength = kMinAdvertisementLength - + kServiceIdHashLength - + kBluetoothMacAddressLength; static constexpr int kMaxEndpointInfoLength = 131; static constexpr int kMaxFastEndpointInfoLength = 17; BleAdvertisement() = default; BleAdvertisement(Version version, Pcp pcp, const std::string& endpoint_id, - const ByteArray& endpoint_info); + const ByteArray& endpoint_info, + const ByteArray& uwb_address); BleAdvertisement(Version version, Pcp pcp, const ByteArray& service_id_hash, const std::string& endpoint_id, const ByteArray& endpoint_info, - const std::string& bluetooth_mac_address); + const std::string& bluetooth_mac_address, + const ByteArray& uwb_address, + WebRtcState web_rtc_state); BleAdvertisement(bool fast_advertisement, const ByteArray& ble_advertisement_bytes); BleAdvertisement(const BleAdvertisement&) = default; @@ -74,21 +83,27 @@ class BleAdvertisement { std::string GetEndpointId() const { return endpoint_id_; } ByteArray GetEndpointInfo() const { return endpoint_info_; } std::string GetBluetoothMacAddress() const { return bluetooth_mac_address_; } + ByteArray GetUwbAddress() const { return uwb_address_; } + WebRtcState GetWebRtcState() const { return web_rtc_state_; } private: void DoInitialize(bool fast_advertisement, Version version, Pcp pcp, const ByteArray& service_id_hash, const std::string& endpoint_id, const ByteArray& endpoint_info, - const std::string& bluetooth_mac_address); + const std::string& bluetooth_mac_address, + const ByteArray& uwb_address, WebRtcState web_rtc_state); bool fast_advertisement_ = false; - Version version_ = Version::kUndefined; - Pcp pcp_ = Pcp::kUnknown; + Version version_{Version::kUndefined}; + Pcp pcp_{Pcp::kUnknown}; ByteArray service_id_hash_; std::string endpoint_id_; ByteArray endpoint_info_; std::string bluetooth_mac_address_; + // TODO(b/169550050): Define UWB address field. + ByteArray uwb_address_; + WebRtcState web_rtc_state_{WebRtcState::kUndefined}; }; } // namespace connections diff --git a/cpp/core_v2/internal/ble_advertisement_test.cc b/cpp/core_v2/internal/ble_advertisement_test.cc index 7ad1d374..42e4b978 100644 --- a/cpp/core_v2/internal/ble_advertisement_test.cc +++ b/cpp/core_v2/internal/ble_advertisement_test.cc @@ -1,5 +1,6 @@ #include "core_v2/internal/ble_advertisement.h" +#include "core_v2/internal/base_pcp_handler.h" #include "gtest/gtest.h" namespace location { @@ -15,14 +16,20 @@ constexpr absl::string_view kEndpointName{ "How much wood can a woodchuck chuck if a wood chuck would chuck wood?"}; constexpr absl::string_view kFastAdvertisementEndpointName{"Fast Advertise"}; constexpr absl::string_view kBluetoothMacAddress{"00:00:E6:88:64:13"}; +constexpr WebRtcState kWebRtcState = WebRtcState::kConnectable; +// TODO(b/169550050): Implement UWBAddress. TEST(BleAdvertisementTest, ConstructionWorks) { ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); @@ -32,12 +39,16 @@ TEST(BleAdvertisementTest, ConstructionWorks) { EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(endpoint_info, ble_advertisement.GetEndpointInfo()); EXPECT_EQ(kBluetoothMacAddress, ble_advertisement.GetBluetoothMacAddress()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionWorksForFastAdvertisement) { ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - fast_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); @@ -45,6 +56,7 @@ TEST(BleAdvertisementTest, ConstructionWorksForFastAdvertisement) { EXPECT_EQ(kPcp, ble_advertisement.GetPcp()); EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(fast_endpoint_info, ble_advertisement.GetEndpointInfo()); + EXPECT_EQ(WebRtcState::kUndefined, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionWorksWithEmptyEndpointInfo) { @@ -56,7 +68,9 @@ TEST(BleAdvertisementTest, ConstructionWorksWithEmptyEndpointInfo) { service_id_hash, std::string(kEndpointId), empty_endpoint_info, - std::string(kBluetoothMacAddress)}; + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); @@ -66,14 +80,18 @@ TEST(BleAdvertisementTest, ConstructionWorksWithEmptyEndpointInfo) { EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(empty_endpoint_info, ble_advertisement.GetEndpointInfo()); EXPECT_EQ(kBluetoothMacAddress, ble_advertisement.GetBluetoothMacAddress()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionWorksWithEmptyEndpointInfoForFastAdvertisement) { ByteArray empty_endpoint_info; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - empty_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + empty_endpoint_info, + ByteArray{}}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); @@ -81,6 +99,7 @@ TEST(BleAdvertisementTest, EXPECT_EQ(kPcp, ble_advertisement.GetPcp()); EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(empty_endpoint_info, ble_advertisement.GetEndpointInfo()); + EXPECT_EQ(WebRtcState::kUndefined, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionWorksWithEmojiEndpointInfo) { @@ -92,7 +111,9 @@ TEST(BleAdvertisementTest, ConstructionWorksWithEmojiEndpointInfo) { service_id_hash, std::string(kEndpointId), emoji_endpoint_info, - std::string(kBluetoothMacAddress)}; + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_FALSE(ble_advertisement.IsFastAdvertisement()); @@ -102,14 +123,18 @@ TEST(BleAdvertisementTest, ConstructionWorksWithEmojiEndpointInfo) { EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(emoji_endpoint_info, ble_advertisement.GetEndpointInfo()); EXPECT_EQ(kBluetoothMacAddress, ble_advertisement.GetBluetoothMacAddress()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionWorksWithEmojiEndpointInfoForFastAdvertisement) { ByteArray emoji_endpoint_info{std::string("\u0001F450 \u0001F450")}; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - emoji_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + emoji_endpoint_info, + ByteArray{}}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_TRUE(ble_advertisement.IsFastAdvertisement()); @@ -117,6 +142,7 @@ TEST(BleAdvertisementTest, EXPECT_EQ(kPcp, ble_advertisement.GetPcp()); EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(emoji_endpoint_info, ble_advertisement.GetEndpointInfo()); + EXPECT_EQ(WebRtcState::kUndefined, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionFailsWithLongEndpointInfo) { @@ -125,10 +151,14 @@ TEST(BleAdvertisementTest, ConstructionFailsWithLongEndpointInfo) { ByteArray long_endpoint_info{long_endpoint_name}; ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - long_endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + long_endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -139,8 +169,11 @@ TEST(BleAdvertisementTest, BleAdvertisement::kMaxFastEndpointInfoLength + 1, 'x'); ByteArray long_endpoint_info{long_endpoint_name}; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - long_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + long_endpoint_info, + ByteArray{}}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -150,10 +183,14 @@ TEST(BleAdvertisementTest, ConstructionFailsWithBadVersion) { ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - bad_version, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{bad_version, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -163,8 +200,11 @@ TEST(BleAdvertisementTest, auto bad_version = static_cast(666); ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement ble_advertisement{ - bad_version, kPcp, std::string(kEndpointId), fast_endpoint_info}; + BleAdvertisement ble_advertisement{bad_version, + kPcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -174,10 +214,14 @@ TEST(BleAdvertisementTest, ConstructionFailsWithBadPCP) { ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, bad_pcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + bad_pcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -186,8 +230,11 @@ TEST(BleAdvertisementTest, ConstructionFailsWithBadPCPForFastAdvertisement) { auto bad_pcp = static_cast(666); ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, bad_pcp, std::string(kEndpointId), fast_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + bad_pcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; EXPECT_FALSE(ble_advertisement.IsValid()); } @@ -197,10 +244,14 @@ TEST(BleAdvertisementTest, ConstructionSucceedsWithEmptyBluetoothMacAddress) { ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, empty_bluetooth_mac_address}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + empty_bluetooth_mac_address, + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(ble_advertisement.IsValid()); } @@ -210,10 +261,14 @@ TEST(BleAdvertisementTest, ConstructionSucceedsWithInvalidBluetoothMacAddress) { ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, bad_bluetooth_mac_address}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + bad_bluetooth_mac_address, + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(ble_advertisement.IsValid()); EXPECT_EQ(kVersion, ble_advertisement.GetVersion()); @@ -222,16 +277,21 @@ TEST(BleAdvertisementTest, ConstructionSucceedsWithInvalidBluetoothMacAddress) { EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(endpoint_info, ble_advertisement.GetEndpointInfo()); EXPECT_TRUE(ble_advertisement.GetBluetoothMacAddress().empty()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionFromBytesWorks) { // Serialize good data into a good Ble Advertisement. ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement org_ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement org_ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; ByteArray ble_advertisement_bytes(org_ble_advertisement); BleAdvertisement ble_advertisement{false, ble_advertisement_bytes}; @@ -244,13 +304,17 @@ TEST(BleAdvertisementTest, ConstructionFromBytesWorks) { EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(endpoint_info, ble_advertisement.GetEndpointInfo()); EXPECT_EQ(kBluetoothMacAddress, ble_advertisement.GetBluetoothMacAddress()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionFromBytesWorksForFastAdvertisement) { // Serialize good data into a good Ble Advertisement. ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement org_ble_advertisement{ - kVersion, kPcp, std::string(kEndpointId), fast_endpoint_info}; + BleAdvertisement org_ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; ByteArray ble_advertisement_bytes(org_ble_advertisement); BleAdvertisement ble_advertisement{true, ble_advertisement_bytes}; @@ -261,6 +325,7 @@ TEST(BleAdvertisementTest, ConstructionFromBytesWorksForFastAdvertisement) { EXPECT_EQ(kPcp, ble_advertisement.GetPcp()); EXPECT_EQ(kEndpointId, ble_advertisement.GetEndpointId()); EXPECT_EQ(fast_endpoint_info, ble_advertisement.GetEndpointInfo()); + EXPECT_EQ(WebRtcState::kUndefined, ble_advertisement.GetWebRtcState()); } // Bytes at the end should be ignored so that they can be used as reserve bytes @@ -269,10 +334,14 @@ TEST(BleAdvertisementTest, ConstructionFromLongLengthBytesWorks) { // Serialize good data into a good Ble Advertisement. ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; ByteArray ble_advertisement_bytes(ble_advertisement); // Add bytes to the end of the valid Ble advertisement. @@ -293,6 +362,7 @@ TEST(BleAdvertisementTest, ConstructionFromLongLengthBytesWorks) { EXPECT_EQ(endpoint_info, long_ble_advertisement.GetEndpointInfo()); EXPECT_EQ(kBluetoothMacAddress, long_ble_advertisement.GetBluetoothMacAddress()); + EXPECT_EQ(kWebRtcState, ble_advertisement.GetWebRtcState()); } TEST(BleAdvertisementTest, ConstructionFromNullBytesFails) { @@ -311,10 +381,14 @@ TEST(BleAdvertisementTest, ConstructionFromShortLengthBytesFails) { // Serialize good data into a good Ble Advertisement. ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; ByteArray ble_advertisement_bytes(ble_advertisement); // Shorten the valid Ble Advertisement. @@ -327,12 +401,16 @@ TEST(BleAdvertisementTest, ConstructionFromShortLengthBytesFails) { EXPECT_FALSE(short_ble_advertisement.IsValid()); } + TEST(BleAdvertisementTest, ConstructionFromShortLengthBytesFailsForFastAdvertisement) { // Serialize good data into a good Ble Advertisement. ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - fast_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; ByteArray ble_advertisement_bytes(ble_advertisement); // Shorten the valid Ble Advertisement. @@ -350,10 +428,14 @@ TEST(BleAdvertisementTest, // Serialize good data into a good Ble Advertisement. ByteArray service_id_hash{std::string(kServiceIdHashBytes)}; ByteArray endpoint_info{std::string(kEndpointName)}; - BleAdvertisement ble_advertisement{ - kVersion, kPcp, - service_id_hash, std::string(kEndpointId), - endpoint_info, std::string(kBluetoothMacAddress)}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + service_id_hash, + std::string(kEndpointId), + endpoint_info, + std::string(kBluetoothMacAddress), + ByteArray{}, + kWebRtcState}; ByteArray ble_advertisement_bytes(ble_advertisement); // Corrupt the EndpointNameLength bits. @@ -371,8 +453,11 @@ TEST(BleAdvertisementTest, ConstructionFromByesWithWrongEndpointInfoLengthFailsForFastAdvertisement) { // Serialize good data into a good Ble Advertisement. ByteArray fast_endpoint_info{std::string(kFastAdvertisementEndpointName)}; - BleAdvertisement ble_advertisement{kVersion, kPcp, std::string(kEndpointId), - fast_endpoint_info}; + BleAdvertisement ble_advertisement{kVersion, + kPcp, + std::string(kEndpointId), + fast_endpoint_info, + ByteArray{}}; ByteArray ble_advertisement_bytes = ByteArray(ble_advertisement); // Corrupt the EndpointInfoLength bits. diff --git a/cpp/core_v2/internal/bluetooth_device_name.cc b/cpp/core_v2/internal/bluetooth_device_name.cc index 48897dc9..374fd186 100644 --- a/cpp/core_v2/internal/bluetooth_device_name.cc +++ b/cpp/core_v2/internal/bluetooth_device_name.cc @@ -18,7 +18,9 @@ namespace connections { BluetoothDeviceName::BluetoothDeviceName(Version version, Pcp pcp, absl::string_view endpoint_id, const ByteArray& service_id_hash, - const ByteArray& endpoint_info) { + const ByteArray& endpoint_info, + const ByteArray& uwb_address, + WebRtcState web_rtc_state) { if (version != Version::kV1 || endpoint_id.empty() || endpoint_id.length() != kEndpointIdLength || service_id_hash.size() != kServiceIdHashLength) { @@ -38,6 +40,8 @@ BluetoothDeviceName::BluetoothDeviceName(Version version, Pcp pcp, endpoint_id_ = std::string(endpoint_id); service_id_hash_ = service_id_hash; endpoint_info_ = endpoint_info; + uwb_address_ = uwb_address; + web_rtc_state_ = web_rtc_state; } BluetoothDeviceName::BluetoothDeviceName( @@ -53,15 +57,6 @@ BluetoothDeviceName::BluetoothDeviceName( return; } - if (bluetooth_device_name_bytes.size() > kMaxBluetoothDeviceNameLength) { - NEARBY_LOG(INFO, - "Cannot deserialize BluetoothDeviceName: expecting max %d raw " - "bytes, got %" PRIu64, - kMaxBluetoothDeviceNameLength, - bluetooth_device_name_bytes.size()); - return; - } - if (bluetooth_device_name_bytes.size() < kMinBluetoothDeviceNameLength) { NEARBY_LOG(INFO, "Cannot deserialize BluetoothDeviceName: expecting min %d raw " @@ -103,11 +98,18 @@ BluetoothDeviceName::BluetoothDeviceName( // The next 3 bytes are supposed to be the service_id_hash. service_id_hash_ = base_input_stream.ReadBytes(kServiceIdHashLength); - // The next 7 bytes are supposed to be reserved, and can be left + + // The next 1 byte is field containning WebRtc state. + auto field_byte = static_cast(base_input_stream.ReadUint8()); + web_rtc_state_ = (field_byte & kWebRtcConnectableFlagBitmask) == 1 + ? WebRtcState::kConnectable + : WebRtcState::kUnconnectable; + + // The next 6 bytes are supposed to be reserved, and can be left // untouched. base_input_stream.ReadBytes(kReservedLength); - // The next 1 byte are supposed to be the length of the endpoint_info. + // The next 1 byte is supposed to be the length of the endpoint_info. std::uint32_t expected_endpoint_info_length = base_input_stream.ReadUint8(); // The rest bytes are supposed to be the endpoint_info @@ -123,6 +125,29 @@ BluetoothDeviceName::BluetoothDeviceName( endpoint_id_.clear(); return; } + + // If the input stream has extra bytes, it's for UWB address. The first byte + // is the address length. It can be 2-byte short address or 8-byte extended + // address. + if (base_input_stream.IsAvailable(1)) { + // The next 1 byte is supposed to be the length of the uwb_address. + std::uint32_t expected_uwb_address_length = base_input_stream.ReadUint8(); + // If the length of usb_address is not zero, then retrieve it. + if (expected_uwb_address_length != 0) { + uwb_address_ = base_input_stream.ReadBytes(expected_uwb_address_length); + if (uwb_address_.Empty() || + uwb_address_.size() != expected_uwb_address_length) { + NEARBY_LOG(INFO, + "Cannot deserialize BluetoothDeviceName: " + "expected uwbAddress size to be %d bytes, got %" PRIu64, + expected_uwb_address_length, uwb_address_.size()); + + // Clear enpoint_id for validadity. + endpoint_id_.clear(); + return; + } + } + } } BluetoothDeviceName::operator std::string() const { @@ -137,6 +162,12 @@ BluetoothDeviceName::operator std::string() const { version_and_pcp_byte |= static_cast(static_cast(pcp_) & kPcpBitmask); + // A byte contains WebRtcState state. + int web_rtc_connectable_flag = + (web_rtc_state_ == WebRtcState::kConnectable) ? 1 : 0; + char field_byte = static_cast(web_rtc_connectable_flag) & + kWebRtcConnectableFlagBitmask; + ByteArray reserved_bytes{kReservedLength}; ByteArray usable_endpoint_info(endpoint_info_); @@ -153,11 +184,18 @@ BluetoothDeviceName::operator std::string() const { std::string out = absl::StrCat(std::string(1, version_and_pcp_byte), endpoint_id_, std::string(service_id_hash_), + std::string(1, field_byte), std::string(reserved_bytes), std::string(1, usable_endpoint_info.size()), std::string(usable_endpoint_info)); // clang-format on + // If UWB address is available, attach it at the end. + if (!uwb_address_.Empty()) { + absl::StrAppend(&out, std::string(1, uwb_address_.size())); + absl::StrAppend(&out, std::string(uwb_address_)); + } + return Base64Utils::Encode(ByteArray{std::move(out)}); } diff --git a/cpp/core_v2/internal/bluetooth_device_name.h b/cpp/core_v2/internal/bluetooth_device_name.h index c5c3f652..77de4f53 100644 --- a/cpp/core_v2/internal/bluetooth_device_name.h +++ b/cpp/core_v2/internal/bluetooth_device_name.h @@ -3,6 +3,7 @@ #include +#include "core_v2/internal/base_pcp_handler.h" #include "core_v2/internal/pcp.h" #include "platform_v2/base/byte_array.h" #include "absl/strings/string_view.h" @@ -30,7 +31,9 @@ class BluetoothDeviceName { BluetoothDeviceName() = default; BluetoothDeviceName(Version version, Pcp pcp, absl::string_view endpoint_id, const ByteArray& service_id_hash, - const ByteArray& endpoint_info); + const ByteArray& endpoint_info, + const ByteArray& uwb_address, + WebRtcState web_rtc_state); explicit BluetoothDeviceName(absl::string_view bluetooth_device_name_string); BluetoothDeviceName(const BluetoothDeviceName&) = default; BluetoothDeviceName& operator=(const BluetoothDeviceName&) = default; @@ -46,24 +49,28 @@ class BluetoothDeviceName { std::string GetEndpointId() const { return endpoint_id_; } ByteArray GetServiceIdHash() const { return service_id_hash_; } ByteArray GetEndpointInfo() const { return endpoint_info_; } + ByteArray GetUwbAddress() const { return uwb_address_; } + WebRtcState GetWebRtcState() const { return web_rtc_state_; } private: - static constexpr int kMaxBluetoothDeviceNameLength = 147; static constexpr int kEndpointIdLength = 4; - static constexpr int kReservedLength = 7; + static constexpr int kReservedLength = 6; static constexpr int kMaxEndpointInfoLength = 131; - static constexpr int kMinBluetoothDeviceNameLength = - kMaxBluetoothDeviceNameLength - kMaxEndpointInfoLength; + static constexpr int kMinBluetoothDeviceNameLength = 16; static constexpr int kVersionBitmask = 0x0E0; static constexpr int kPcpBitmask = 0x01F; static constexpr int kEndpointNameLengthBitmask = 0x0FF; + static constexpr int kWebRtcConnectableFlagBitmask = 0x01; Version version_{Version::kUndefined}; Pcp pcp_{Pcp::kUnknown}; std::string endpoint_id_; ByteArray service_id_hash_; ByteArray endpoint_info_; + // TODO(b/169550050): Define UWB address field. + ByteArray uwb_address_; + WebRtcState web_rtc_state_{WebRtcState::kUndefined}; }; } // namespace connections diff --git a/cpp/core_v2/internal/bluetooth_device_name_test.cc b/cpp/core_v2/internal/bluetooth_device_name_test.cc index d957bb63..a509170e 100644 --- a/cpp/core_v2/internal/bluetooth_device_name_test.cc +++ b/cpp/core_v2/internal/bluetooth_device_name_test.cc @@ -17,12 +17,19 @@ constexpr Pcp kPcp = Pcp::kP2pCluster; constexpr absl::string_view kEndPointID{"AB12"}; constexpr absl::string_view kServiceIDHashBytes{"\x0a\x0b\x0c"}; constexpr absl::string_view kEndPointName{"RAWK + ROWL!"}; +constexpr WebRtcState kWebRtcState = WebRtcState::kConnectable; +// TODO(b/169550050): Implement UWBAddress. TEST(BluetoothDeviceNameTest, ConstructionWorks) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{kVersion, kPcp, kEndPointID, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(bluetooth_device_name.IsValid()); EXPECT_EQ(kVersion, bluetooth_device_name.GetVersion()); @@ -30,14 +37,20 @@ TEST(BluetoothDeviceNameTest, ConstructionWorks) { EXPECT_EQ(kEndPointID, bluetooth_device_name.GetEndpointId()); EXPECT_EQ(service_id_hash, bluetooth_device_name.GetServiceIdHash()); EXPECT_EQ(endpoint_info, bluetooth_device_name.GetEndpointInfo()); + EXPECT_EQ(kWebRtcState, bluetooth_device_name.GetWebRtcState()); } TEST(BluetoothDeviceNameTest, ConstructionWorksWithEmptyEndpointName) { ByteArray empty_endpoint_info; ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; - BluetoothDeviceName bluetooth_device_name{ - kVersion, kPcp, kEndPointID, service_id_hash, empty_endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + kEndPointID, + service_id_hash, + empty_endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(bluetooth_device_name.IsValid()); EXPECT_EQ(kVersion, bluetooth_device_name.GetVersion()); @@ -45,6 +58,7 @@ TEST(BluetoothDeviceNameTest, ConstructionWorksWithEmptyEndpointName) { EXPECT_EQ(kEndPointID, bluetooth_device_name.GetEndpointId()); EXPECT_EQ(service_id_hash, bluetooth_device_name.GetServiceIdHash()); EXPECT_EQ(empty_endpoint_info, bluetooth_device_name.GetEndpointInfo()); + EXPECT_EQ(kWebRtcState, bluetooth_device_name.GetWebRtcState()); } TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadVersion) { @@ -52,8 +66,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadVersion) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{bad_version, kPcp, kEndPointID, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{bad_version, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -63,8 +82,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithBadPcp) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{kVersion, bad_pcp, kEndPointID, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + bad_pcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -74,8 +98,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithShortEndpointId) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{kVersion, kPcp, short_endpoint_id, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + short_endpoint_id, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -85,8 +114,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithLongEndpointId) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{kVersion, kPcp, long_endpoint_id, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + long_endpoint_id, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -96,8 +130,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithShortServiceIdHash) { ByteArray short_service_id_hash{short_service_id_hash_bytes}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{ - kVersion, kPcp, kEndPointID, short_service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + kEndPointID, + short_service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -107,8 +146,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithLongServiceIdHash) { ByteArray long_service_id_hash{long_service_id_hash_bytes}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{ - kVersion, kPcp, kEndPointID, long_service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + kEndPointID, + long_service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(bluetooth_device_name.IsValid()); } @@ -127,8 +171,13 @@ TEST(BluetoothDeviceNameTest, ConstructionFailsWithWrongEndpointNameLength) { // Serialize good data into a good Bluetooth Device Name. ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - BluetoothDeviceName bluetooth_device_name{kVersion, kPcp, kEndPointID, - service_id_hash, endpoint_info}; + BluetoothDeviceName bluetooth_device_name{kVersion, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; auto bluetooth_device_name_string = std::string(bluetooth_device_name); // Base64-decode the good Bluetooth Device Name. @@ -155,8 +204,13 @@ TEST(BluetoothDeviceNameTest, CanParseGeneratedName) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; // Build name1 from scratch. - BluetoothDeviceName name1{kVersion, kPcp, kEndPointID, service_id_hash, - endpoint_info}; + BluetoothDeviceName name1{kVersion, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; // Build name2 from string composed from name1. BluetoothDeviceName name2{std::string(name1)}; EXPECT_TRUE(name1.IsValid()); @@ -166,6 +220,7 @@ TEST(BluetoothDeviceNameTest, CanParseGeneratedName) { EXPECT_EQ(name1.GetEndpointId(), name2.GetEndpointId()); EXPECT_EQ(name1.GetServiceIdHash(), name2.GetServiceIdHash()); EXPECT_EQ(name1.GetEndpointInfo(), name2.GetEndpointInfo()); + EXPECT_EQ(name1.GetWebRtcState(), name2.GetWebRtcState()); } } // namespace diff --git a/cpp/core_v2/internal/bwu_manager.cc b/cpp/core_v2/internal/bwu_manager.cc index ab81e570..cd4c9c38 100644 --- a/cpp/core_v2/internal/bwu_manager.cc +++ b/cpp/core_v2/internal/bwu_manager.cc @@ -1,6 +1,7 @@ #include "core_v2/internal/bwu_manager.h" #include +#include #include "core_v2/internal/bwu_handler.h" #include "core_v2/internal/offline_frames.h" @@ -192,7 +193,7 @@ void BwuManager::OnEndpointDisconnect(ClientProxy* client, handler_->OnEndpointDisconnect(client, endpoint_id); } - auto item = old_channels_.extract(endpoint_id); + auto item = previous_endpoint_channels_.extract(endpoint_id); if (!item.empty()) { auto old_channel = item.mapped(); @@ -260,7 +261,10 @@ void BwuManager::OnBwuNegotiationFrame(ClientProxy* client, } void BwuManager::OnIncomingConnection( - ClientProxy* client, BwuHandler::IncomingSocketConnection* connection) { + ClientProxy* client, + BwuHandler::IncomingSocketConnection* mutable_connection) { + auto connection = std::make_shared( + std::move(*mutable_connection)); RunOnBwuManagerThread([this, client, connection]() { EndpointChannel* channel = connection->channel.get(); if (channel == nullptr) { @@ -329,7 +333,7 @@ void BwuManager::RunUpgradeProtocol( // continue when we receive a corresponding // BANDWIDTH_UPGRADE_NEGOTIATION.LAST_WRITE_TO_PRIOR_CHANNEL OfflineFrame from // the remote device, so for now, just store that previous EndpointChannel. - old_channels_.emplace(endpoint_id, old_channel); + previous_endpoint_channels_.emplace(endpoint_id, old_channel); // If we already read LAST_WRITE on the old endpoint channel, then we can // safely close it now. diff --git a/cpp/core_v2/internal/bwu_manager.h b/cpp/core_v2/internal/bwu_manager.h index b97d7138..ed0252dd 100644 --- a/cpp/core_v2/internal/bwu_manager.h +++ b/cpp/core_v2/internal/bwu_manager.h @@ -156,10 +156,8 @@ class BwuManager : public EndpointManager::FrameProcessor { // Stores each upgraded endpoint's previous EndpointChannel (that was // displaced in favor of a new EndpointChannel) temporarily, until it can // safely be shut down for good in processLastWriteToPriorChannelEvent(). - absl::flat_hash_map> - previous_endpoint_channels_; absl::flat_hash_map> - old_channels_; + previous_endpoint_channels_; absl::flat_hash_set successfully_upgraded_endpoints_; // Maps endpointId -> ClientProxy for which // initiateBwuForEndpoint() has been called but which have not diff --git a/cpp/core_v2/internal/mediums/BUILD b/cpp/core_v2/internal/mediums/BUILD index b2125c5c..49ae79f4 100644 --- a/cpp/core_v2/internal/mediums/BUILD +++ b/cpp/core_v2/internal/mediums/BUILD @@ -25,7 +25,9 @@ cc_library( "//core_v2/internal:__subpackages__", ], deps = [ + ":utils", "//core_v2:core_types", + "//core_v2/internal/mediums/ble_v2", "//core_v2/internal/mediums/webrtc", "//platform_v2/base", "//platform_v2/public:comm", @@ -49,6 +51,7 @@ cc_library( hdrs = ["utils.h"], visibility = [ "//core_v2/internal:__pkg__", + "//core_v2/internal/mediums:__pkg__", "//core_v2/internal/mediums/ble_v2:__pkg__", "//core_v2/internal/mediums/webrtc:__pkg__", ], diff --git a/cpp/core_v2/internal/mediums/ble.cc b/cpp/core_v2/internal/mediums/ble.cc index f8c7cf8f..80622a97 100644 --- a/cpp/core_v2/internal/mediums/ble.cc +++ b/cpp/core_v2/internal/mediums/ble.cc @@ -4,6 +4,9 @@ #include #include +#include "core_v2/internal/mediums/ble_v2/ble_advertisement.h" +#include "core_v2/internal/mediums/utils.h" +#include "platform_v2/base/prng.h" #include "platform_v2/public/logging.h" #include "platform_v2/public/mutex_lock.h" @@ -11,6 +14,15 @@ namespace location { namespace nearby { namespace connections { +ByteArray Ble::GenerateHash(const std::string& source, size_t size) { + return Utils::Sha256Hash(source, size); +} + +ByteArray Ble::GenerateDeviceToken() { + return Utils::Sha256Hash(std::to_string(Prng().NextUint32()), + mediums::BleAdvertisement::kDeviceTokenLength); +} + Ble::Ble(BluetoothRadio& radio) : radio_(radio) {} bool Ble::IsAvailable() const { @@ -63,7 +75,23 @@ bool Ble::StartAdvertising(const std::string& service_id, << ", service id=" << service_id << ", fast advertisement service uuid=" << fast_advertisement_service_uuid; - if (!medium_.StartAdvertising(service_id, advertisement_bytes, + + // Wrap the connections advertisement to the medium advertisement. + const bool fast_advertisement = !fast_advertisement_service_uuid.empty(); + ByteArray service_id_hash{GenerateHash( + service_id, mediums::BleAdvertisement::kServiceIdHashLength)}; + ByteArray medium_advertisement_bytes{mediums::BleAdvertisement{ + mediums::BleAdvertisement::Version::kV2, + mediums::BleAdvertisement::SocketVersion::kV2, + fast_advertisement ? ByteArray{} : service_id_hash, advertisement_bytes, + GenerateDeviceToken()}}; + if (medium_advertisement_bytes.Empty()) { + NEARBY_LOGS(INFO) << "Failed to BLE advertise because we could not " + "create a medium advertisement."; + return false; + } + + if (!medium_.StartAdvertising(service_id, medium_advertisement_bytes, fast_advertisement_service_uuid)) { NEARBY_LOGS(INFO) << "Failed to turn on BLE advertising with advertisement bytes=" @@ -110,6 +138,8 @@ bool Ble::StartScanning(const std::string& service_id, DiscoveredPeripheralCallback callback) { MutexLock lock(&mutex_); + discovered_peripheral_callback_ = std::move(callback); + if (service_id.empty()) { NEARBY_LOGS(INFO) << "Refusing to start BLE scanning with empty service id."; @@ -134,8 +164,29 @@ bool Ble::StartScanning(const std::string& service_id, return false; } - if (!medium_.StartScanning(service_id, fast_advertisement_service_uuid, - callback)) { + if (!medium_.StartScanning( + service_id, fast_advertisement_service_uuid, + { + .peripheral_discovered_cb = + [this](BlePeripheral& peripheral, + const std::string& service_id, + const ByteArray& medium_advertisement_bytes, + bool fast_advertisement) { + // Unwrap connection BleAdvertisement from medium + // BleAdvertisement. + auto connection_advertisement_bytes = + UnwrapAdvertisementBytes(medium_advertisement_bytes); + discovered_peripheral_callback_.peripheral_discovered_cb( + peripheral, service_id, connection_advertisement_bytes, + fast_advertisement); + }, + .peripheral_lost_cb = + [this](BlePeripheral& peripheral, + const std::string& service_id) { + discovered_peripheral_callback_.peripheral_lost_cb( + peripheral, service_id); + }, + })) { NEARBY_LOGS(INFO) << "Failed to start scan of BLE services."; return false; } @@ -272,6 +323,16 @@ BleSocket Ble::Connect(BlePeripheral& peripheral, return socket; } +ByteArray Ble::UnwrapAdvertisementBytes( + const ByteArray& medium_advertisement_data) { + mediums::BleAdvertisement medium_ble_advertisement{medium_advertisement_data}; + if (!medium_ble_advertisement.IsValid()) { + return ByteArray{}; + } + + return medium_ble_advertisement.GetData(); +} + } // namespace connections } // namespace nearby } // namespace location diff --git a/cpp/core_v2/internal/mediums/ble.h b/cpp/core_v2/internal/mediums/ble.h index 1a6b7643..b99c07c0 100644 --- a/cpp/core_v2/internal/mediums/ble.h +++ b/cpp/core_v2/internal/mediums/ble.h @@ -88,8 +88,6 @@ class Ble { ABSL_LOCKS_EXCLUDED(mutex_); private: - static constexpr int kMaxAdvertisementLength = 512; - struct AdvertisingInfo { bool Empty() const { return service_ids.empty(); } void Clear() { service_ids.clear(); } @@ -132,6 +130,11 @@ class Ble { absl::flat_hash_set service_ids; }; + static constexpr int kMaxAdvertisementLength = 512; + + static ByteArray GenerateHash(const std::string& source, size_t size); + static ByteArray GenerateDeviceToken(); + // Same as IsAvailable(), but must be called with mutex_ held. bool IsAvailableLocked() const ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); @@ -147,6 +150,10 @@ class Ble { bool IsAcceptingConnectionsLocked(const std::string& service_id) ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex_); + // Extract connection advertisement from medium advertisement. + ByteArray UnwrapAdvertisementBytes( + const ByteArray& medium_advertisement_data); + mutable Mutex mutex_; BluetoothRadio& radio_ ABSL_GUARDED_BY(mutex_); BluetoothAdapter& adapter_ ABSL_GUARDED_BY(mutex_){ @@ -154,6 +161,7 @@ class Ble { BleMedium medium_ ABSL_GUARDED_BY(mutex_){adapter_}; AdvertisingInfo advertising_info_ ABSL_GUARDED_BY(mutex_); ScanningInfo scanning_info_ ABSL_GUARDED_BY(mutex_); + DiscoveredPeripheralCallback discovered_peripheral_callback_; AcceptingConnectionsInfo accepting_connections_info_ ABSL_GUARDED_BY(mutex_); }; diff --git a/cpp/core_v2/internal/mediums/ble_test.cc b/cpp/core_v2/internal/mediums/ble_test.cc index 15e24d8f..9977d6ac 100644 --- a/cpp/core_v2/internal/mediums/ble_test.cc +++ b/cpp/core_v2/internal/mediums/ble_test.cc @@ -60,12 +60,12 @@ TEST_F(BleTest, CanStartAdvertising) { CountDownLatch found_latch(1); ble_b.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { found_latch.CountDown(); }, }); @@ -95,12 +95,12 @@ TEST_F(BleTest, CanStartDiscovery) { fast_advertisement_service_uuid); EXPECT_TRUE(ble_a.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&accept_latch]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { accept_latch.CountDown(); }, .peripheral_lost_cb = [&lost_latch](BlePeripheral& peripheral, @@ -140,12 +140,12 @@ TEST_F(BleTest, CanStartAcceptingConnectionsAndConnect) { }); BlePeripheral discovered_peripheral; ble_b.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, { .peripheral_discovered_cb = [&found_latch, &discovered_peripheral]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { discovered_peripheral = peripheral; NEARBY_LOG( diff --git a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.cc b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.cc index d988a869..2011d925 100644 --- a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.cc +++ b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.cc @@ -16,16 +16,8 @@ BleAdvertisement::BleAdvertisement(Version version, const ByteArray &service_id_hash, const ByteArray &data, const ByteArray &device_token) { - DoInitialize(/*fast_advertisement=*/false, version, socket_version, - service_id_hash, data, device_token); -} - -BleAdvertisement::BleAdvertisement(Version version, - SocketVersion socket_version, - const ByteArray &data, - const ByteArray &device_token) { - DoInitialize(/*fast_advertisement=*/true, version, socket_version, - {}, data, device_token); + DoInitialize(/*fast_advertisement=*/service_id_hash.Empty(), version, + socket_version, service_id_hash, data, device_token); } void BleAdvertisement::DoInitialize(bool fast_advertisement, Version version, diff --git a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.h b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.h index 203b3614..3b8ad37d 100644 --- a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.h +++ b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement.h @@ -47,8 +47,6 @@ class BleAdvertisement { BleAdvertisement(Version version, SocketVersion socket_version, const ByteArray &service_id_hash, const ByteArray &data, const ByteArray &device_token); - BleAdvertisement(Version version, SocketVersion socket_version, - const ByteArray &data, const ByteArray &device_token); explicit BleAdvertisement(const ByteArray &ble_advertisement_bytes); BleAdvertisement(const BleAdvertisement &) = default; BleAdvertisement &operator=(const BleAdvertisement &) = default; diff --git a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement_test.cc b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement_test.cc index 46a18850..6bbbd196 100644 --- a/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement_test.cc +++ b/cpp/core_v2/internal/mediums/ble_v2/ble_advertisement_test.cc @@ -53,6 +53,7 @@ TEST(BleAdvertisementTest, ConstructionWorksV1ForFastAdvertisement) { BleAdvertisement ble_advertisement{BleAdvertisement::Version::kV1, BleAdvertisement::SocketVersion::kV1, + ByteArray{}, fast_data, device_token}; @@ -83,6 +84,7 @@ TEST(BleAdvertisementTest, ConstructionFailsWithBadVersion) { BleAdvertisement fast_ble_advertisement{bad_version, kSocketVersion, + ByteArray{}, data, device_token}; EXPECT_FALSE(fast_ble_advertisement.IsValid()); @@ -105,6 +107,7 @@ TEST(BleAdvertisementTest, ConstructionFailsWithBadSocketVersion) { BleAdvertisement fast_ble_advertisement{kVersion, bad_socket_version, + ByteArray{}, data, device_token}; EXPECT_FALSE(fast_ble_advertisement.IsValid()); @@ -160,6 +163,7 @@ TEST(BleAdvertisementTest, ConstructionFailsWithLongData) { BleAdvertisement fast_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, bad_data, device_token}; EXPECT_FALSE(fast_ble_advertisement.IsValid()); @@ -191,6 +195,7 @@ TEST(BleAdvertisementTest, BleAdvertisement ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, fast_data, ByteArray{}}; @@ -228,12 +233,14 @@ TEST(BleAdvertisementTest, ConstructionFailsWithWrongSizeofDeviceToken) { BleAdvertisement fast_ble_advertisement_1{kVersion, kSocketVersion, + ByteArray{}, data, bad_device_token_1}; EXPECT_FALSE(fast_ble_advertisement_1.IsValid()); BleAdvertisement fast_ble_advertisement_2{kVersion, kSocketVersion, + ByteArray{}, data, bad_device_token_2}; EXPECT_FALSE(fast_ble_advertisement_2.IsValid()); @@ -270,6 +277,7 @@ TEST(BleAdvertisementTest, BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, fast_data, device_token}; @@ -312,6 +320,7 @@ TEST(BleAdvertisementTest, BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, ByteArray(), device_token}; ByteArray ble_advertisement_bytes{org_ble_advertisement}; @@ -366,6 +375,7 @@ TEST(BleAdvertisementTest, BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, fast_data, device_token}; ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; @@ -424,6 +434,7 @@ TEST(BleAdvertisementTest, BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, fast_data, device_token}; ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; @@ -475,6 +486,7 @@ TEST(BleAdvertisementTest, BleAdvertisement org_ble_advertisement{kVersion, kSocketVersion, + ByteArray{}, fast_data, device_token}; ByteArray org_ble_advertisement_bytes{org_ble_advertisement}; diff --git a/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc b/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc index 86af87ec..3950f8c4 100644 --- a/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc +++ b/cpp/core_v2/internal/mediums/webrtc/connection_flow.cc @@ -231,6 +231,10 @@ bool ConnectionFlow::Close() { bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) { Future success_future; + // CreatePeerConnection callback may be invoked after ConnectionFlow lifetime + // has ended, in case of a timeout. Future is captured by value, and is safe + // to access, but it is not safe to access ConnectionFlow member variables + // unless the Future::Set() returns true. webrtc_medium.CreatePeerConnection( &peer_connection_observer_, [this, success_future](rtc::scoped_refptr @@ -240,6 +244,11 @@ bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) { return; } + // If this fails, means we have already assigned something to + // success_future; it is either: + // 1) this is the 2nd call of this callback (and this is a bug), or + // 2) Get(timeout) has set the future value as exception already. + if (success_future.IsSet()) return; peer_connection_ = peer_connection; success_future.Set(true); }); diff --git a/cpp/core_v2/internal/offline_frames.cc b/cpp/core_v2/internal/offline_frames.cc index 9c7f6314..fd9a6527 100644 --- a/cpp/core_v2/internal/offline_frames.cc +++ b/cpp/core_v2/internal/offline_frames.cc @@ -4,6 +4,7 @@ #include #include "core/internal/message_lite.h" +#include "core_v2/status.h" #include "proto/connections/offline_wire_formats.pb.h" #include "platform_v2/base/byte_array.h" @@ -71,7 +72,14 @@ ByteArray ForConnectionResponse(std::int32_t status) { auto* v1_frame = frame.mutable_v1(); v1_frame->set_type(V1Frame::CONNECTION_RESPONSE); auto* sub_frame = v1_frame->mutable_connection_response(); + + // For backward compatiblility, here still sets both status and response + // parameters until the response feature is roll out in all supported + // devices. sub_frame->set_status(status); + sub_frame->set_response(status == Status::kSuccess + ? ConnectionResponseFrame::ACCEPT + : ConnectionResponseFrame::REJECT); return ToBytes(std::move(frame)); } diff --git a/cpp/core_v2/internal/offline_frames_test.cc b/cpp/core_v2/internal/offline_frames_test.cc index 42dce1f3..8d0a402c 100644 --- a/cpp/core_v2/internal/offline_frames_test.cc +++ b/cpp/core_v2/internal/offline_frames_test.cc @@ -93,7 +93,10 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) { version: V1 v1: < type: CONNECTION_RESPONSE - connection_response: < status: 1 > + connection_response: < + status: 1 + response: REJECT + > >)pb"; ByteArray bytes = ForConnectionResponse(1); auto response = FromBytes(bytes); diff --git a/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc b/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc index 116a04fd..039b7bdc 100644 --- a/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc +++ b/cpp/core_v2/internal/p2p_cluster_pcp_handler.cc @@ -314,9 +314,10 @@ bool P2pClusterPcpHandler::IsRecognizedBleEndpoint( void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler( ClientProxy* client, BlePeripheral& peripheral, - const std::string& service_id, bool fast_advertisement) { + const std::string& service_id, const ByteArray& advertisement_bytes, + bool fast_advertisement) { RunOnPcpHandlerThread([this, client, &peripheral, service_id, - fast_advertisement]() { + advertisement_bytes, fast_advertisement]() { // Make sure we are still discovering before proceeding. if (!client->IsDiscovering()) { NEARBY_LOG(INFO, @@ -327,8 +328,7 @@ void P2pClusterPcpHandler::BlePeripheralDiscoveredHandler( } // Parse the BLE advertisement bytes. - BleAdvertisement advertisement( - fast_advertisement, peripheral.GetAdvertisementBytes(service_id)); + BleAdvertisement advertisement(fast_advertisement, advertisement_bytes); // Make sure the BLE advertisement points to a valid // endpoint we're discovering. @@ -568,6 +568,9 @@ BasePcpHandler::StartOperationResult P2pClusterPcpHandler::StartDiscoveryImpl( .device_discovered_cb = absl::bind_front( &P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler, this, client, service_id), + .device_name_changed_cb = absl::bind_front( + &P2pClusterPcpHandler::BluetoothDeviceDiscoveredHandler, this, + client, service_id), .device_lost_cb = absl::bind_front( &P2pClusterPcpHandler::BluetoothDeviceLostHandler, this, client, service_id), @@ -714,9 +717,11 @@ proto::connections::Medium P2pClusterPcpHandler::StartBluetoothAdvertising( absl::BytesToHexString(service_id_hash.data()).c_str(), absl::BytesToHexString(local_endpoint_info.data()).c_str()); // Generate a BluetoothDeviceName with which to become Bluetooth discoverable. + // TODO(b/169550050): Implement UWBAddress. + // TODO(b/169303359): Implement WebRtcState. std::string device_name(BluetoothDeviceName( kBluetoothDeviceNameVersion, GetPcp(), local_endpoint_id, service_id_hash, - local_endpoint_info)); + local_endpoint_info, ByteArray{}, WebRtcState::kUnconnectable)); if (device_name.empty()) { NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartBluetoothAdvertising: generate " @@ -887,10 +892,11 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising( // Generate a BleAdvertisement. If a fast advertisement service UUID was // provided, create a fast BleAdvertisement. ByteArray advertisement_bytes; + // TODO(b/169550050): Implement UWBAddress. if (fast_advertisement) { - advertisement_bytes = - ByteArray(BleAdvertisement(kBleAdvertisementVersion, GetPcp(), - local_endpoint_id, local_endpoint_info)); + advertisement_bytes = ByteArray( + BleAdvertisement(kBleAdvertisementVersion, GetPcp(), local_endpoint_id, + local_endpoint_info, ByteArray{})); } else { const ByteArray service_id_hash = GenerateHash(service_id, BleAdvertisement::kServiceIdHashLength); @@ -899,9 +905,11 @@ proto::connections::Medium P2pClusterPcpHandler::StartBleAdvertising( ShouldAdvertiseBluetoothMacOverBle(power_level)) bluetooth_mac_address = bluetooth_medium_.GetMacAddress(); + // TODO(b/169303359): Implement WebRtcState. advertisement_bytes = ByteArray(BleAdvertisement( kBleAdvertisementVersion, GetPcp(), service_id_hash, local_endpoint_id, - local_endpoint_info, bluetooth_mac_address)); + local_endpoint_info, bluetooth_mac_address, ByteArray{}, + WebRtcState::kUnconnectable)); } if (advertisement_bytes.Empty()) { NEARBY_LOG(INFO, @@ -1022,9 +1030,11 @@ proto::connections::Medium P2pClusterPcpHandler::StartWifiLanAdvertising( absl::BytesToHexString(service_id_hash.data()).c_str(), absl::BytesToHexString(local_endpoint_info.data()).c_str()); // Generate a WifiLanServiceInfo with which to become WifiLan discoverable. + // TODO(b/169550050): Implement UWBAddress. + // TODO(b/169303359): Implement WebRtcState. std::string service_info_name(WifiLanServiceInfo( kWifiLanServiceInfoVersion, GetPcp(), local_endpoint_id, service_id_hash, - local_endpoint_info)); + local_endpoint_info, ByteArray{}, WebRtcState::kUnconnectable)); if (service_info_name.empty()) { NEARBY_LOG(INFO, "P2pClusterPcpHandler::StartWifiLanAdvertising: generate " diff --git a/cpp/core_v2/internal/p2p_cluster_pcp_handler.h b/cpp/core_v2/internal/p2p_cluster_pcp_handler.h index 687075c4..50ea90ef 100644 --- a/cpp/core_v2/internal/p2p_cluster_pcp_handler.h +++ b/cpp/core_v2/internal/p2p_cluster_pcp_handler.h @@ -151,6 +151,7 @@ class P2pClusterPcpHandler : public BasePcpHandler { void BlePeripheralDiscoveredHandler(ClientProxy* client, BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement); void BlePeripheralLostHandler(ClientProxy* client, BlePeripheral& peripheral, const std::string& service_id); diff --git a/cpp/core_v2/internal/wifi_lan_service_info.cc b/cpp/core_v2/internal/wifi_lan_service_info.cc index 566cf40e..b982a89c 100644 --- a/cpp/core_v2/internal/wifi_lan_service_info.cc +++ b/cpp/core_v2/internal/wifi_lan_service_info.cc @@ -17,7 +17,9 @@ namespace connections { WifiLanServiceInfo::WifiLanServiceInfo(Version version, Pcp pcp, absl::string_view endpoint_id, const ByteArray& service_id_hash, - const ByteArray& endpoint_info) { + const ByteArray& endpoint_info, + const ByteArray& uwb_address, + WebRtcState web_rtc_state) { if (version != Version::kV1 || endpoint_id.empty() || endpoint_id.length() != kEndpointIdLength || service_id_hash.size() != kServiceIdHashLength) { @@ -37,6 +39,8 @@ WifiLanServiceInfo::WifiLanServiceInfo(Version version, Pcp pcp, service_id_hash_ = service_id_hash; endpoint_id_ = std::string(endpoint_id); endpoint_info_ = endpoint_info; + uwb_address_ = uwb_address; + web_rtc_state_ = web_rtc_state; } WifiLanServiceInfo::WifiLanServiceInfo(absl::string_view service_info_string) { @@ -50,14 +54,6 @@ WifiLanServiceInfo::WifiLanServiceInfo(absl::string_view service_info_string) { return; } - if (service_info_bytes.size() > kMaxLanServiceNameLength) { - NEARBY_LOG(INFO, - "Cannot deserialize WifiLanServiceInfo: expecting max %d raw " - "bytes, got %" PRIu64, - kMaxLanServiceNameLength, service_info_bytes.size()); - return; - } - if (service_info_bytes.size() < kMinLanServiceNameLength) { NEARBY_LOG(INFO, "Cannot deserialize WifiLanServiceInfo: expecting min %d raw " @@ -105,6 +101,20 @@ WifiLanServiceInfo::WifiLanServiceInfo(absl::string_view service_info_string) { // The next 3 bytes are supposed to be the service_id_hash. service_id_hash_ = base_input_stream.ReadBytes(kServiceIdHashLength); + // The next 1 byte are supposed to be the length of the UWB address. + std::uint32_t expected_uwb_address_length = base_input_stream.ReadUint8(); + + // The next bytes are supposed to be UWB address if length is not zero. + if (expected_uwb_address_length != 0) { + uwb_address_ = base_input_stream.ReadBytes(expected_uwb_address_length); + } + + // The next 1 byte is extra field. + auto extra_field = static_cast(base_input_stream.ReadUint8()); + web_rtc_state_ = (extra_field & kWebRtcConnectableFlagBitmask) == 1 + ? WebRtcState::kConnectable + : WebRtcState::kUnconnectable; + // The next 1 byte are supposed to be the length of the endpoint_info. std::uint32_t expected_endpoint_info_length = base_input_stream.ReadUint8(); @@ -135,6 +145,12 @@ WifiLanServiceInfo::operator std::string() const { version_and_pcp_byte |= static_cast(static_cast(pcp_) & kPcpBitmask); + // A byte contains WebRtcState state. + int web_rtc_connectable_flag = + (web_rtc_state_ == WebRtcState::kConnectable) ? 1 : 0; + char field_byte = static_cast(web_rtc_connectable_flag) & + kWebRtcConnectableFlagBitmask; + ByteArray usable_endpoint_info(endpoint_info_); if (endpoint_info_.size() > kMaxEndpointInfoLength) { NEARBY_LOG( @@ -146,13 +162,29 @@ WifiLanServiceInfo::operator std::string() const { usable_endpoint_info.SetData(endpoint_info_.data(), kMaxEndpointInfoLength); } - // clang-format off - std::string out = absl::StrCat(std::string(1, version_and_pcp_byte), - endpoint_id_, - std::string(service_id_hash_), - std::string(1, usable_endpoint_info.size()), - std::string(usable_endpoint_info)); - // clang-format on + std::string out; + if (!uwb_address_.Empty()) { + // clang-format off + out = absl::StrCat(std::string(1, version_and_pcp_byte), + endpoint_id_, + std::string(service_id_hash_), + std::string(1, uwb_address_.size()), + std::string(uwb_address_), + std::string(1, field_byte), + std::string(1, usable_endpoint_info.size()), + std::string(usable_endpoint_info)); + // clang-format on + } else { + // clang-format off + out = absl::StrCat(std::string(1, version_and_pcp_byte), + endpoint_id_, + std::string(service_id_hash_), + std::string(1, uwb_address_.size()), + std::string(1, field_byte), + std::string(1, usable_endpoint_info.size()), + std::string(usable_endpoint_info)); + // clang-format on + } return Base64Utils::Encode(ByteArray{std::move(out)}); } diff --git a/cpp/core_v2/internal/wifi_lan_service_info.h b/cpp/core_v2/internal/wifi_lan_service_info.h index 4b6b3897..bc422f08 100644 --- a/cpp/core_v2/internal/wifi_lan_service_info.h +++ b/cpp/core_v2/internal/wifi_lan_service_info.h @@ -3,6 +3,7 @@ #include +#include "core_v2/internal/base_pcp_handler.h" #include "core_v2/internal/pcp.h" #include "platform_v2/base/byte_array.h" #include "absl/strings/string_view.h" @@ -28,7 +29,9 @@ class WifiLanServiceInfo { WifiLanServiceInfo() = default; WifiLanServiceInfo(Version version, Pcp pcp, absl::string_view endpoint_id, const ByteArray& service_id_hash, - const ByteArray& endpoint_info); + const ByteArray& endpoint_info, + const ByteArray& uwb_address, + WebRtcState web_rtc_state); explicit WifiLanServiceInfo(absl::string_view service_info_string); WifiLanServiceInfo(const WifiLanServiceInfo&) = default; WifiLanServiceInfo& operator=(const WifiLanServiceInfo&) = default; @@ -44,31 +47,28 @@ class WifiLanServiceInfo { std::string GetEndpointId() const { return endpoint_id_; } ByteArray GetEndpointInfo() const { return endpoint_info_; } ByteArray GetServiceIdHash() const { return service_id_hash_; } + ByteArray GetUwbAddress() const { return uwb_address_; } + WebRtcState GetWebRtcState() const { return web_rtc_state_; } private: - // The maximum length of encrypted WifiLanServiceInfo string. - static constexpr int kMaxLanServiceNameLength = 47; - // The minimum length of encrypted WifiLanServiceInfo string. static constexpr int kMinLanServiceNameLength = 9; - // The length for endpoint id in encrypted WifiLanServiceInfo string. static constexpr int kEndpointIdLength = 4; - // The maximum length for endpoint id in encrypted WifiLanServiceInfo string. static constexpr int kMaxEndpointInfoLength = 131; + static constexpr int kUwbAddressLengthSize = 1; static constexpr int kVersionBitmask = 0x0E0; static constexpr int kPcpBitmask = 0x01F; static constexpr int kVersionShift = 5; + static constexpr int kWebRtcConnectableFlagBitmask = 0x01; - // WifiLanServiceInfo version. - Version version_ = Version::kUndefined; - // Pre-Connection Protocols version. - Pcp pcp_ = Pcp::kUnknown; - // Connected endpoint id. + Version version_{Version::kUndefined}; + Pcp pcp_{Pcp::kUnknown}; std::string endpoint_id_; - // Connected hash service id. ByteArray service_id_hash_; - // Connected endpoint info. ByteArray endpoint_info_; + // TODO(b/169550050): Define UWB address field. + ByteArray uwb_address_; + WebRtcState web_rtc_state_{WebRtcState::kUndefined}; }; } // namespace connections diff --git a/cpp/core_v2/internal/wifi_lan_service_info_test.cc b/cpp/core_v2/internal/wifi_lan_service_info_test.cc index 90215c06..4eabc78e 100644 --- a/cpp/core_v2/internal/wifi_lan_service_info_test.cc +++ b/cpp/core_v2/internal/wifi_lan_service_info_test.cc @@ -17,12 +17,19 @@ constexpr Pcp kPcp = Pcp::kP2pCluster; constexpr absl::string_view kEndPointID{"AB12"}; constexpr absl::string_view kServiceIDHashBytes{"\x0a\x0b\x0c"}; constexpr absl::string_view kEndPointName{"RAWK + ROWL!"}; +constexpr WebRtcState kWebRtcState = WebRtcState::kConnectable; +// TODO(b/169550050): Implement UWBAddress. TEST(WifiLanServiceInfoTest, ConstructionWorks) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{ - kVersion, kPcp, kEndPointID, service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_TRUE(wifi_lan_service_info.IsValid()); EXPECT_EQ(kPcp, wifi_lan_service_info.GetPcp()); @@ -35,8 +42,13 @@ TEST(WifiLanServiceInfoTest, ConstructionWorks) { TEST(WifiLanServiceInfoTest, ConstructionFromSerializedStringWorks) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo org_wifi_lan_service_info{kVersion, kPcp, kEndPointID, - service_id_hash, endpoint_info}; + WifiLanServiceInfo org_wifi_lan_service_info{kVersion, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; std::string wifi_lan_service_info_string{org_wifi_lan_service_info}; WifiLanServiceInfo wifi_lan_service_info{wifi_lan_service_info_string}; @@ -47,6 +59,7 @@ TEST(WifiLanServiceInfoTest, ConstructionFromSerializedStringWorks) { EXPECT_EQ(kEndPointID, wifi_lan_service_info.GetEndpointId()); EXPECT_EQ(service_id_hash, wifi_lan_service_info.GetServiceIdHash()); EXPECT_EQ(endpoint_info, wifi_lan_service_info.GetEndpointInfo()); + EXPECT_EQ(kWebRtcState, wifi_lan_service_info.GetWebRtcState()); } TEST(WifiLanServiceInfoTest, ConstructionFailsWithBadVersion) { @@ -54,8 +67,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithBadVersion) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{bad_version, kPcp, kEndPointID, - service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{bad_version, + kPcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } @@ -65,8 +83,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithBadPCP) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{kVersion, bad_pcp, kEndPointID, - service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + bad_pcp, + kEndPointID, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } @@ -76,8 +99,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithShortEndpointId) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{kVersion, kPcp, short_endpoint_id, - service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + kPcp, + short_endpoint_id, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } @@ -87,8 +115,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithLongEndpointId) { ByteArray service_id_hash{std::string(kServiceIDHashBytes)}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{kVersion, kPcp, long_endpoint_id, - service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + kPcp, + long_endpoint_id, + service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } @@ -98,8 +131,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithShortServiceIdHash) { ByteArray short_service_id_hash{short_service_id_hash_bytes}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{ - kVersion, kPcp, kEndPointID, short_service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + kPcp, + kEndPointID, + short_service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } @@ -109,8 +147,13 @@ TEST(WifiLanServiceInfoTest, ConstructionFailsWithLongServiceIdHash) { ByteArray long_service_id_hash{long_service_id_hash_bytes}; ByteArray endpoint_info{std::string(kEndPointName)}; - WifiLanServiceInfo wifi_lan_service_info{kVersion, kPcp, kEndPointID, - long_service_id_hash, endpoint_info}; + WifiLanServiceInfo wifi_lan_service_info{kVersion, + kPcp, + kEndPointID, + long_service_id_hash, + endpoint_info, + ByteArray{}, + kWebRtcState}; EXPECT_FALSE(wifi_lan_service_info.IsValid()); } diff --git a/cpp/platform_v2/public/ble.cc b/cpp/platform_v2/public/ble.cc index db8ab6b5..40d8777b 100644 --- a/cpp/platform_v2/public/ble.cc +++ b/cpp/platform_v2/public/ble.cc @@ -51,7 +51,9 @@ bool BleMedium::StartScanning( &context.peripheral, &peripheral, peripheral.GetName().c_str()); discovered_peripheral_callback_.peripheral_discovered_cb( - context.peripheral, service_id, fast_advertisement); + context.peripheral, service_id, + context.peripheral.GetAdvertisementBytes(service_id), + fast_advertisement); } }, .peripheral_lost_cb = diff --git a/cpp/platform_v2/public/ble.h b/cpp/platform_v2/public/ble.h index ca9bedbb..41f5b1b9 100644 --- a/cpp/platform_v2/public/ble.h +++ b/cpp/platform_v2/public/ble.h @@ -71,11 +71,12 @@ class BleMedium final { public: using Platform = api::ImplementationPlatform; struct DiscoveredPeripheralCallback { - std::function peripheral_discovered_cb = - DefaultCallback(); + DefaultCallback(); std::function peripheral_lost_cb = diff --git a/cpp/platform_v2/public/ble_test.cc b/cpp/platform_v2/public/ble_test.cc index 41f6d091..94a5a2b5 100644 --- a/cpp/platform_v2/public/ble_test.cc +++ b/cpp/platform_v2/public/ble_test.cc @@ -58,12 +58,12 @@ TEST_F(BleMediumTest, CanStartAdvertising) { fast_advertisement_service_uuid); EXPECT_TRUE(ble_b.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { found_latch.CountDown(); }, })); EXPECT_TRUE(found_latch.Await(kWaitDuration).result()); @@ -85,12 +85,12 @@ TEST_F(BleMediumTest, CanStartScanning) { CountDownLatch lost_latch(1); ble_a.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { found_latch.CountDown(); }, .peripheral_lost_cb = [&lost_latch](BlePeripheral& peripheral, @@ -120,12 +120,12 @@ TEST_F(BleMediumTest, CanStopDiscovery) { CountDownLatch lost_latch(1); ble_a.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { found_latch.CountDown(); }, .peripheral_lost_cb = [&lost_latch](BlePeripheral& peripheral, @@ -156,12 +156,12 @@ TEST_F(BleMediumTest, CanStartAcceptingConnectionsAndConnect) { BlePeripheral* discovered_peripheral = nullptr; ble_a.StartScanning( - service_id, - fast_advertisement_service_uuid, + service_id, fast_advertisement_service_uuid, DiscoveredPeripheralCallback{ .peripheral_discovered_cb = [&found_latch, &discovered_peripheral]( BlePeripheral& peripheral, const std::string& service_id, + const ByteArray& advertisement_bytes, bool fast_advertisement) { NEARBY_LOG( INFO, diff --git a/cpp/platform_v2/public/future.h b/cpp/platform_v2/public/future.h index df9fcae8..80babc9c 100644 --- a/cpp/platform_v2/public/future.h +++ b/cpp/platform_v2/public/future.h @@ -20,6 +20,9 @@ class Future final { void AddListener(Runnable runnable, api::Executor* executor) { impl_->AddListener(std::move(runnable), executor); } + bool IsSet() const { + return impl_->IsSet(); + } private: // Instance of future implementation is wrapped in shared_ptr<> to make diff --git a/cpp/platform_v2/public/settable_future.h b/cpp/platform_v2/public/settable_future.h index 7649df07..4a45aab0 100644 --- a/cpp/platform_v2/public/settable_future.h +++ b/cpp/platform_v2/public/settable_future.h @@ -25,8 +25,9 @@ class SettableFuture : public api::SettableFuture { exception_ = {Exception::kSuccess}; completed_.Notify(); InvokeAllLocked(); + return true; } - return true; + return false; } void AddListener(Runnable runnable, api::Executor* executor) override { @@ -38,6 +39,11 @@ class SettableFuture : public api::SettableFuture { } } + bool IsSet() const { + MutexLock lock(&mutex_); + return done_; + } + bool SetException(Exception exception) override { MutexLock lock(&mutex_); return SetExceptionLocked(exception); @@ -94,7 +100,7 @@ class SettableFuture : public api::SettableFuture { listeners_.clear(); } - Mutex mutex_; + mutable Mutex mutex_; ConditionVariable completed_{&mutex_}; std::vector>> listeners_; bool done_{false}; diff --git a/script/oss.py b/script/oss.py index 21a70028..b75e78ef 100755 --- a/script/oss.py +++ b/script/oss.py @@ -19,6 +19,7 @@ import argparse import os import re import shutil +import stat import sys copy_header="""Copyright 2020 Google LLC @@ -200,6 +201,7 @@ def post_process_oss_files(path, args): modified = True if modified: + os.chmod(fname, os.stat(fname).st_mode | stat.S_IWRITE) with open(fname, "w") as f: for line in lines: f.write(line)