Skip to content

Commit

Permalink
internal fix
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 723242250
  • Loading branch information
ggli-google authored and copybara-github committed Feb 5, 2025
1 parent c6c8c23 commit 16020b2
Show file tree
Hide file tree
Showing 13 changed files with 395 additions and 183 deletions.
1 change: 1 addition & 0 deletions connections/implementation/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ cc_test(
"//internal/platform/implementation/g3", # build_cleaner: keep
"@com_github_protobuf_matchers//protobuf-matchers",
"@com_google_absl//absl/status",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
Expand Down
83 changes: 62 additions & 21 deletions connections/implementation/ble_advertisement.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@

#include "connections/implementation/ble_advertisement.h"

#include <inttypes.h>
#include <optional>
#include <string>
#include <utility>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/pcp.h"
Expand Down Expand Up @@ -114,17 +115,22 @@ absl::StatusOr<BleAdvertisement> BleAdvertisement::CreateBleAdvertisement(
ByteArray advertisement_bytes{ble_advertisement_bytes};
BaseInputStream base_input_stream{advertisement_bytes};
// The first 1 byte is supposed to be the version and pcp.
auto version_and_pcp_byte = static_cast<char>(base_input_stream.ReadUint8());
auto version_and_pcp_byte = base_input_stream.ReadUint8();
if (!version_and_pcp_byte.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: version_and_pcp.");
}

// The upper 3 bits are supposed to be the version.
Version version =
static_cast<Version>((version_and_pcp_byte & kVersionBitmask) >> 5);
static_cast<Version>((*version_and_pcp_byte & kVersionBitmask) >> 5);
if (version != Version::kV1) {
return absl::InvalidArgumentError(absl::StrCat(
"Cannot deserialize BleAdvertisement: unsupported Version: ", version));
}

// The lower 5 bits are supposed to be the Pcp.
Pcp pcp = static_cast<Pcp>(version_and_pcp_byte & kPcpBitmask);
Pcp pcp = static_cast<Pcp>(*version_and_pcp_byte & kPcpBitmask);
switch (pcp) {
case Pcp::kP2pCluster: // Fall through
case Pcp::kP2pStar: // Fall through
Expand All @@ -139,20 +145,43 @@ absl::StatusOr<BleAdvertisement> BleAdvertisement::CreateBleAdvertisement(
// advertisement.
ByteArray service_id_hash;
if (!fast_advertisement) {
service_id_hash = base_input_stream.ReadBytes(kServiceIdHashLength);
auto service_id_hash_bytes =
base_input_stream.ReadBytes(kServiceIdHashLength);
if (!service_id_hash_bytes.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: service_id_hash.");
}

service_id_hash = *service_id_hash_bytes;
}

// The next 4 bytes are supposed to be the endpoint_id.
std::string endpoint_id =
std::string{base_input_stream.ReadBytes(kEndpointIdLength)};
auto endpoint_id_bytes = base_input_stream.ReadBytes(kEndpointIdLength);
if (!endpoint_id_bytes.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: endpoint_id.");
}

std::string endpoint_id = std::string{*endpoint_id_bytes};

// The next 1 byte is supposed to be the length of the endpoint_info.
auto expected_endpoint_info_length = base_input_stream.ReadUint8();
if (!expected_endpoint_info_length.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: endpoint_info_length.");
}

// The next x bytes are the endpoint info. (Max length is 131 bytes or 17
// bytes as fast_advertisement being true).
auto endpoint_info =
base_input_stream.ReadBytes(expected_endpoint_info_length);
auto endpoint_info_bytes =
base_input_stream.ReadBytes(*expected_endpoint_info_length);
if (!endpoint_info_bytes.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: endpoint_info.");
}

ByteArray endpoint_info = *endpoint_info_bytes;

const int max_endpoint_info_length =
fast_advertisement ? kMaxFastEndpointInfoLength : kMaxEndpointInfoLength;
if (endpoint_info.Empty() ||
Expand All @@ -161,16 +190,20 @@ absl::StatusOr<BleAdvertisement> BleAdvertisement::CreateBleAdvertisement(
return absl::InvalidArgumentError(absl::StrCat(
"Cannot deserialize BleAdvertisement(fast advertisement=",
fast_advertisement, "): expected endpointInfo to be ",
expected_endpoint_info_length, " bytes, got ", endpoint_info.size()));
*expected_endpoint_info_length, " bytes, got ", endpoint_info.size()));
}

// The next 6 bytes are the bluetooth mac address if not fast advertisement.
std::string bluetooth_mac_address;
if (!fast_advertisement) {
auto bluetooth_mac_address_bytes =
base_input_stream.ReadBytes(BluetoothUtils::kBluetoothMacAddressLength);
if (!bluetooth_mac_address_bytes.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: bluetooth_mac_address.");
}
bluetooth_mac_address =
BluetoothUtils::ToString(bluetooth_mac_address_bytes);
BluetoothUtils::ToString(*bluetooth_mac_address_bytes);
}

// The next 1 byte is supposed to be the length of the uwb_address. If the
Expand All @@ -180,24 +213,32 @@ absl::StatusOr<BleAdvertisement> BleAdvertisement::CreateBleAdvertisement(
BleAdvertisement ble_advertisement;
if (base_input_stream.IsAvailable(1)) {
auto expected_uwb_address_length = base_input_stream.ReadUint8();
if (!expected_uwb_address_length.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: uwb_address_length.");
}
// 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) {
return absl::InvalidArgumentError(absl::StrCat(
"Cannot deserialize BleAdvertisement: expected uwbAddress size to "
"be ",
expected_uwb_address_length, " bytes, got ", uwb_address.size()));
auto uwb_address_bytes =
base_input_stream.ReadBytes(*expected_uwb_address_length);

if (!uwb_address_bytes.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: uwb_address.");
}
uwb_address = *uwb_address_bytes;
}

// The next 1 byte is extra field.
if (!fast_advertisement) {
if (base_input_stream.IsAvailable(kExtraFieldLength)) {
auto extra_field = static_cast<char>(base_input_stream.ReadUint8());
auto extra_field = base_input_stream.ReadUint8();
if (!extra_field.has_value()) {
return absl::InvalidArgumentError(
"Cannot deserialize BleAdvertisement: extra_field.");
}
ble_advertisement.web_rtc_state_ =
(extra_field & kWebRtcConnectableFlagBitmask) == 1
(*extra_field & kWebRtcConnectableFlagBitmask) == 1
? WebRtcState::kConnectable
: WebRtcState::kUnconnectable;
}
Expand Down
5 changes: 5 additions & 0 deletions connections/implementation/ble_advertisement_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@

#include "connections/implementation/ble_advertisement.h"

#include <cstring>
#include <string>

#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/pcp.h"
#include "internal/platform/byte_array.h"

namespace nearby {
Expand Down
117 changes: 72 additions & 45 deletions connections/implementation/bluetooth_device_name.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,18 @@

#include "connections/implementation/bluetooth_device_name.h"

#include <inttypes.h>

#include <cstring>
#include <cstdint>
#include <string>
#include <utility>

#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/base_pcp_handler.h"
#include "connections/implementation/pcp.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/base_input_stream.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/logging.h"

namespace nearby {
Expand Down Expand Up @@ -66,48 +69,67 @@ BluetoothDeviceName::BluetoothDeviceName(
}

if (bluetooth_device_name_bytes.size() < kMinBluetoothDeviceNameLength) {
NEARBY_LOGS(INFO)
<< "Cannot deserialize BluetoothDeviceName: expecting min "
<< kMinBluetoothDeviceNameLength << " raw bytes, got "
<< bluetooth_device_name_bytes.size();
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: expecting min "
<< kMinBluetoothDeviceNameLength << " raw bytes, got "
<< bluetooth_device_name_bytes.size();
return;
}

BaseInputStream base_input_stream{bluetooth_device_name_bytes};
// The first 1 byte is supposed to be the version and pcp.
auto version_and_pcp_byte = static_cast<char>(base_input_stream.ReadUint8());
auto version_and_pcp_byte = base_input_stream.ReadUint8();
if (!version_and_pcp_byte.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: version_and_pcp.";
return;
}
// The upper 3 bits are supposed to be the version.
version_ =
static_cast<Version>((version_and_pcp_byte & kVersionBitmask) >> 5);
static_cast<Version>((*version_and_pcp_byte & kVersionBitmask) >> 5);
if (version_ != Version::kV1) {
NEARBY_LOGS(INFO)
<< "Cannot deserialize BluetoothDeviceName: unsupported version="
<< static_cast<int>(version_);
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: unsupported version="
<< static_cast<int>(version_);
return;
}
// The lower 5 bits are supposed to be the Pcp.
pcp_ = static_cast<Pcp>(version_and_pcp_byte & kPcpBitmask);
pcp_ = static_cast<Pcp>(*version_and_pcp_byte & kPcpBitmask);
switch (pcp_) {
case Pcp::kP2pCluster: // Fall through
case Pcp::kP2pStar: // Fall through
case Pcp::kP2pPointToPoint:
break;
default:
NEARBY_LOGS(INFO)
<< "Cannot deserialize BluetoothDeviceName: unsupported V1 PCP "
<< static_cast<int>(pcp_);
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: unsupported V1 PCP "
<< static_cast<int>(pcp_);
return;
}

// The next 4 bytes are supposed to be the endpoint_id.
endpoint_id_ = std::string{base_input_stream.ReadBytes(kEndpointIdLength)};
auto endpoint_id_bytes = base_input_stream.ReadBytes(kEndpointIdLength);
if (!endpoint_id_bytes.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: endpoint_id.";
return;
}
endpoint_id_ = std::string{*endpoint_id_bytes};

// The next 3 bytes are supposed to be the service_id_hash.
service_id_hash_ = base_input_stream.ReadBytes(kServiceIdHashLength);
auto service_id_hash_bytes =
base_input_stream.ReadBytes(kServiceIdHashLength);
if (!service_id_hash_bytes.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: service_id_hash.";
endpoint_id_.clear();
return;
}

service_id_hash_ = *service_id_hash_bytes;

// The next 1 byte is field containing WebRtc state.
auto field_byte = static_cast<char>(base_input_stream.ReadUint8());
web_rtc_state_ = (field_byte & kWebRtcConnectableFlagBitmask) == 1
auto field_byte = base_input_stream.ReadUint8();
if (!field_byte.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: extra_field.";
endpoint_id_.clear();
return;
}
web_rtc_state_ = (*field_byte & kWebRtcConnectableFlagBitmask) == 1
? WebRtcState::kConnectable
: WebRtcState::kUnconnectable;

Expand All @@ -116,42 +138,48 @@ BluetoothDeviceName::BluetoothDeviceName(
base_input_stream.ReadBytes(kReservedLength);

// 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();
auto expected_endpoint_info_length = base_input_stream.ReadUint8();
if (!expected_endpoint_info_length.has_value()) {
LOG(INFO)
<< "Cannot deserialize BluetoothDeviceName: endpoint_info_length.";
endpoint_id_.clear();
return;
}

// The rest bytes are supposed to be the endpoint_info
endpoint_info_ = base_input_stream.ReadBytes(expected_endpoint_info_length);
if (endpoint_info_.Empty() ||
endpoint_info_.size() != expected_endpoint_info_length) {
NEARBY_LOGS(INFO) << "Cannot deserialize BluetoothDeviceName: expected "
"endpoint info to be "
<< expected_endpoint_info_length << " bytes, got "
<< endpoint_info_.size();

// Clear endpoint_id for validity.
auto endpoint_info_bytes =
base_input_stream.ReadBytes(*expected_endpoint_info_length);
if (!endpoint_info_bytes.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: endpoint_info.";
endpoint_id_.clear();
return;
}
endpoint_info_ = *endpoint_info_bytes;

// 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();
auto expected_uwb_address_length = base_input_stream.ReadUint8();
if (!expected_uwb_address_length.has_value()) {
LOG(INFO)
<< "Cannot deserialize BluetoothDeviceName: uwb_address_length.";
endpoint_id_.clear();
return;
}

// 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_LOGS(INFO) << "Cannot deserialize BluetoothDeviceName: expected "
"uwbAddress size to be "
<< expected_uwb_address_length << " bytes, got "
<< uwb_address_.size();

// Clear endpoint_id for validity.
auto uwb_address_bytes =
base_input_stream.ReadBytes(*expected_uwb_address_length);
if (!uwb_address_bytes.has_value()) {
LOG(INFO) << "Cannot deserialize BluetoothDeviceName: uwb_address.";
endpoint_id_.clear();
return;
}

uwb_address_ = *uwb_address_bytes;
}
}
}
Expand All @@ -178,11 +206,10 @@ BluetoothDeviceName::operator std::string() const {

ByteArray usable_endpoint_info(endpoint_info_);
if (endpoint_info_.size() > kMaxEndpointInfoLength) {
NEARBY_LOGS(INFO)
<< "While serializing Advertisement, truncating Endpoint Name "
<< absl::BytesToHexString(endpoint_info_.data()) << " ("
<< endpoint_info_.size() << " bytes) down to " << kMaxEndpointInfoLength
<< " bytes";
LOG(INFO) << "While serializing Advertisement, truncating Endpoint Name "
<< absl::BytesToHexString(endpoint_info_.data()) << " ("
<< endpoint_info_.size() << " bytes) down to "
<< kMaxEndpointInfoLength << " bytes";
usable_endpoint_info.SetData(endpoint_info_.data(), kMaxEndpointInfoLength);
}

Expand Down
2 changes: 1 addition & 1 deletion connections/implementation/bluetooth_device_name.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#ifndef CORE_INTERNAL_BLUETOOTH_DEVICE_NAME_H_
#define CORE_INTERNAL_BLUETOOTH_DEVICE_NAME_H_

#include <cstdint>
#include <string>

#include "absl/strings/string_view.h"
#include "connections/implementation/base_pcp_handler.h"
Expand Down
2 changes: 2 additions & 0 deletions connections/implementation/bluetooth_device_name_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@

#include <cstring>
#include <memory>
#include <string>

#include "gtest/gtest.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/byte_array.h"

namespace nearby {
namespace connections {
Expand Down
Loading

0 comments on commit 16020b2

Please sign in to comment.