Roll forward to cl/336363104

Signed-off-by: hai007 <hais@google.com>
This commit is contained in:
hai007
2020-10-09 14:14:41 -07:00
parent bcc3f21da2
commit 0738d06b0a
31 changed files with 728 additions and 254 deletions
+41 -29
View File
@@ -321,19 +321,19 @@ Status BasePcpHandler::RequestConnection(ClientProxy* client,
OnEndpointFound(client, webrtc_endpoint);
}
auto discovered_endpoints = GetDiscoveredEndpoints(endpoint_id);
std::unique_ptr<EndpointChannel> 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<EndpointChannel> 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::DiscoveredEndpoint>
BasePcpHandler::GetRemoteBluetoothMacAddressEndpoint(
std::string endpoint_id, std::string remote_bluetooth_mac_address,
std::vector<DiscoveredEndpoint*> 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>(BluetoothEndpoint{
std::make_shared<BluetoothEndpoint>(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,
+12 -4
View File
@@ -70,6 +70,13 @@ Swapper<T> MakeSwapper(T* value) {
return Swapper<T>(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<proto::connections::Medium>& supported_mediums);
std::unique_ptr<BasePcpHandler::DiscoveredEndpoint>
GetRemoteBluetoothMacAddressEndpoint(
std::string endpoint_id, std::string remote_bluetooth_mac_address,
std::vector<DiscoveredEndpoint*> 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,
+73 -15
View File
@@ -2,6 +2,7 @@
#include <inttypes.h>
#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<char>(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<char>(web_rtc_connectable_flag) &
kWebRtcConnectableFlagBitmask;
absl::StrAppend(&out, std::string(1, extra_field_byte));
}
return ByteArray(std::move(out));
}
+25 -10
View File
@@ -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.
//
// <p>[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]
//
// <p>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
+145 -60
View File
@@ -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<BleAdvertisement::Version>(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<Pcp>(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.
+50 -12
View File
@@ -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<char>(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<char>(static_cast<uint32_t>(pcp_) & kPcpBitmask);
// A byte contains WebRtcState state.
int web_rtc_connectable_flag =
(web_rtc_state_ == WebRtcState::kConnectable) ? 1 : 0;
char field_byte = static_cast<char>(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)});
}
+12 -5
View File
@@ -3,6 +3,7 @@
#include <cstdint>
#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
@@ -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
+7 -3
View File
@@ -1,6 +1,7 @@
#include "core_v2/internal/bwu_manager.h"
#include <algorithm>
#include <memory>
#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<BwuHandler::IncomingSocketConnection>(
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.
+1 -3
View File
@@ -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<std::string, std::unique_ptr<EndpointChannel>>
previous_endpoint_channels_;
absl::flat_hash_map<std::string, std::shared_ptr<EndpointChannel>>
old_channels_;
previous_endpoint_channels_;
absl::flat_hash_set<std::string> successfully_upgraded_endpoints_;
// Maps endpointId -> ClientProxy for which
// initiateBwuForEndpoint() has been called but which have not
+3
View File
@@ -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__",
],
+64 -3
View File
@@ -4,6 +4,9 @@
#include <string>
#include <utility>
#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
+10 -2
View File
@@ -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<std::string> 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_);
};
+6 -6
View File
@@ -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(
@@ -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,
@@ -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;
@@ -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};
@@ -231,6 +231,10 @@ bool ConnectionFlow::Close() {
bool ConnectionFlow::InitPeerConnection(WebRtcMedium& webrtc_medium) {
Future<bool> 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<webrtc::PeerConnectionInterface>
@@ -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);
});
+8
View File
@@ -4,6 +4,7 @@
#include <utility>
#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));
}
+4 -1
View File
@@ -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);
+20 -10
View File
@@ -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 "
@@ -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);
+48 -16
View File
@@ -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<char>(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<char>(static_cast<uint32_t>(pcp_) & kPcpBitmask);
// A byte contains WebRtcState state.
int web_rtc_connectable_flag =
(web_rtc_state_ == WebRtcState::kConnectable) ? 1 : 0;
char field_byte = static_cast<char>(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)});
}
+13 -13
View File
@@ -3,6 +3,7 @@
#include <cstdint>
#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
@@ -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());
}
+3 -1
View File
@@ -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 =
+4 -3
View File
@@ -71,11 +71,12 @@ class BleMedium final {
public:
using Platform = api::ImplementationPlatform;
struct DiscoveredPeripheralCallback {
std::function<void(BlePeripheral& peripheral,
const std::string& service_id,
std::function<void(BlePeripheral& peripheral, const std::string& service_id,
const ByteArray& advertisement_bytes,
bool fast_advertisement)>
peripheral_discovered_cb =
DefaultCallback<BlePeripheral&, const std::string&, bool>();
DefaultCallback<BlePeripheral&, const std::string&,
const ByteArray&, bool>();
std::function<void(BlePeripheral& peripheral,
const std::string& service_id)>
peripheral_lost_cb =
+8 -8
View File
@@ -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,
+3
View File
@@ -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
+8 -2
View File
@@ -25,8 +25,9 @@ class SettableFuture : public api::SettableFuture<T> {
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<T> {
}
}
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<T> {
listeners_.clear();
}
Mutex mutex_;
mutable Mutex mutex_;
ConditionVariable completed_{&mutex_};
std::vector<std::pair<api::Executor*, std::function<void()>>> listeners_;
bool done_{false};
+2
View File
@@ -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)