Add Extended Advertising support in Nearby Connections layer

PiperOrigin-RevId: 452112156
This commit is contained in:
aaronyujiaze
2022-05-31 12:29:18 -07:00
committed by Copybara-Service
parent 93bc497872
commit b4b74ca5b4
2 changed files with 162 additions and 11 deletions
@@ -77,6 +77,11 @@ bool BleMedium::StartAdvertising(
DataWriter data_writer;
// TODO(b/234229562): Add parsing logic for fast_advertisement_service_uuid
// and insert into the 0x16 Service Data field in the BLE advertisement when
// Fast Advertisement is enabled. For Extended Advertising, use the same
// hardcoded Copresence service uuid 0xFEF3.
// Copresence Service UUID 0xfef3 (little-endian)
data_writer.WriteUInt16(kCopresenceServiceUuid);
@@ -93,19 +98,48 @@ bool BleMedium::StartAdvertising(
data_sections.Append(service_data);
advertisement_.DataSections() = data_sections;
publisher_ = BluetoothLEAdvertisementPublisher(advertisement_);
// Use Extended Advertising if Fast Advertisement Service Uuid is empty string
// because the long format advertisement will be used
if (fast_advertisement_service_uuid.empty()) {
publisher_ = BluetoothLEAdvertisementPublisher(advertisement_);
publisher_.UseExtendedAdvertisement(true);
publisher_token_ =
publisher_.StatusChanged({this, &BleMedium::PublisherHandler});
publisher_token_ =
publisher_.StatusChanged({this, &BleMedium::PublisherHandler});
publisher_started_promise_ = std::promise<PublisherState>();
publisher_started_promise_ = std::promise<PublisherState>();
std::future<PublisherState> publisher_state_future =
publisher_started_promise_.get_future();
std::future<PublisherState> publisher_state_future =
publisher_started_promise_.get_future();
publisher_.Start();
publisher_.Start();
return publisher_state_future.get() == PublisherState::kStarted;
return publisher_state_future.get() == PublisherState::kStarted;
} else {
// Extended Advertisement not supported, must make sure advertisement_bytes
// is less than 27 bytes
if (advertisement_bytes.size() <= 27) {
publisher_ = BluetoothLEAdvertisementPublisher(advertisement_);
publisher_.UseExtendedAdvertisement(false);
publisher_token_ =
publisher_.StatusChanged({this, &BleMedium::PublisherHandler});
publisher_started_promise_ = std::promise<PublisherState>();
std::future<PublisherState> publisher_state_future =
publisher_started_promise_.get_future();
publisher_.Start();
return publisher_state_future.get() == PublisherState::kStarted;
} else {
// otherwise no-op
NEARBY_LOGS(INFO) << "Everyone Mode unavailable for hardware that does "
"not support Extended Advertising.";
return false;
}
}
}
bool BleMedium::StopAdvertising(const std::string& service_id) {
@@ -123,6 +157,7 @@ bool BleMedium::StopAdvertising(const std::string& service_id) {
return publisher_state_future.get() == PublisherState::kStopped;
}
// TODO(b/234229557): Add BlePeripheral discovery logic
bool BleMedium::StartScanning(
const std::string& service_id,
const std::string& fast_advertisement_service_uuid,
@@ -158,7 +193,6 @@ bool BleMedium::StartScanning(
bool BleMedium::StopScanning(const std::string& service_id) {
absl::MutexLock lock(&mutex_);
NEARBY_LOGS(INFO) << "Windows Ble StopScanning: service_id=" << service_id;
watcher_stopped_promise_ = std::promise<WatcherState>();
@@ -36,7 +36,7 @@ constexpr uint8_t kFastAdvertisementFlagBitmask = 0x02;
constexpr uint8_t kPcpBitmask = 0x1F;
constexpr uint8_t kVisibilityBitmask = 0x01;
TEST(BleMedium, DISABLED_StartAdvertising) {
TEST(BleMedium, DISABLED_StartAdvertising_FastAdvertisement) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
@@ -61,7 +61,7 @@ TEST(BleMedium, DISABLED_StartAdvertising) {
// (1 byte) body_length
advertising_data_byte_array.at(1) = static_cast<unsigned char>(
0x19); // always 25 bytes for Fast Advertisement
0x17); // always 23 bytes for Fast Advertisement
// (1 byte) Nearby Connection version [3-bits] + pcp [5-bits]
uint8_t ble_connections_version =
@@ -117,6 +117,123 @@ TEST(BleMedium, DISABLED_StartAdvertising) {
ble_medium.StartAdvertising("NearbyShare", advertising_data, "\xfe\xf3"));
}
TEST(BleMedium, DISABLED_StartAdvertising_ExtendedAdvertising) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);
std::array<char, 167> advertising_data_byte_array;
// (1 byte) version [3-bits] + socket_version [3-bits] +
// fast_advertisement_flag [1-bit] + reserved [1-bit]
uint8_t ble_medium_version = 0x02; // mediums::BleAdvertisement::Version::kV2
uint8_t socket_version =
0x02; // mediums::BleAdvertisement::SocketVersion::kV2
bool fast_advertisement = false; // Is Fast Advertisement
uint8_t ble_medium_advertisement_metadata_byte =
(ble_medium_version << 5) & kVersionBitmask;
ble_medium_advertisement_metadata_byte |=
(socket_version << 2) & kSocketVersionBitmask;
ble_medium_advertisement_metadata_byte |=
((fast_advertisement ? 1 : 0) << 1) & kFastAdvertisementFlagBitmask;
advertising_data_byte_array.at(0) =
static_cast<unsigned char>(ble_medium_advertisement_metadata_byte);
// (3 bytes) service_id_hash
for (int i = 0; i < 3; ++i) {
advertising_data_byte_array.at(1 + i) = static_cast<unsigned char>(0x00);
}
// (4 bytes) body_length
advertising_data_byte_array.at(7) = static_cast<unsigned char>(
0x9C); // max 156 bytes for Extended Advertising
// (1 byte) Nearby Connection version [3-bits] + pcp [5-bits]
uint8_t ble_connections_version =
0x01; // connections::BleAdvertisement::Version::kV1
uint8_t pcp = 0x02; // connections::Pcp::kP2pCluster
uint8_t ble_connections_advertisement_metadata_byte =
(ble_connections_version << 5) & kVersionBitmask;
ble_connections_advertisement_metadata_byte |= pcp & kPcpBitmask;
advertising_data_byte_array.at(8) =
static_cast<unsigned char>(ble_connections_advertisement_metadata_byte);
// (3 bytes) service_id_hash
for (int i = 0; i < 3; ++i) {
advertising_data_byte_array.at(9 + i) = static_cast<unsigned char>(0x00);
}
// (4 bytes) endpoint_id
for (int i = 0; i < 4; ++i) {
advertising_data_byte_array.at(12 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) endpoint_info_size
advertising_data_byte_array.at(16) = static_cast<unsigned char>(
0x83); // max 131-bytes for Extended Advertising
// =========endpoint_info [Max 131-bytes]============
// (1 byte) Nearby Share version [3-bits] + visibility [1-bit] + reserved
// [4-bits]
uint8_t nearby_share_version = 0x00; // nearby share v1
uint8_t visibility = 0x00; // [placeholder] sharing::Visibility::kAllContacts
uint8_t nearby_share_metadata_byte =
(nearby_share_version << 5) & kVersionBitmask;
nearby_share_metadata_byte |= ((visibility & kVisibilityBitmask) << 4);
advertising_data_byte_array.at(17) = static_cast<unsigned char>(0x00);
// (2 bytes) salt
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(18 + i) = static_cast<unsigned char>(0x00);
}
// (14 bytes) encrypted_metadata_key
for (int i = 0; i < 14; ++i) {
advertising_data_byte_array.at(20 + i) = static_cast<unsigned char>(0x00);
}
// [optional]
// (1 byte) human_readable_name_size
advertising_data_byte_array.at(34) = static_cast<unsigned char>(0x72);
// [optional]
// (max 114 bytes) human_readable_name
for (int i = 0; i < 114; ++i) {
advertising_data_byte_array.at(35 + i) = static_cast<unsigned char>(0x00);
}
// =========endpoint_info [131-bytes]============
// (6 bytes) bluetooth_mac_address
for (int i = 0; i < 6; ++i) {
advertising_data_byte_array.at(149 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) uwb_address_size
advertising_data_byte_array.at(155) = static_cast<unsigned char>(0x72);
// (8 bytes) uwb_address
for (int i = 0; i < 6; ++i) {
advertising_data_byte_array.at(156 + i) = static_cast<unsigned char>(0x00);
}
// (1 byte) extra_field [web_rtc_connectable]
advertising_data_byte_array.at(164) = static_cast<unsigned char>(0x72);
// (2 bytes) device_token
for (int i = 0; i < 2; ++i) {
advertising_data_byte_array.at(165 + i) = static_cast<unsigned char>(0x00);
}
ByteArray advertising_data(advertising_data_byte_array);
EXPECT_TRUE(
ble_medium.StartAdvertising("NearbyShare", advertising_data, ""));
}
TEST(BleMedium, DISABLED_StopAdvertising) {
BluetoothAdapter bluetoothAdapter;
BleMedium ble_medium(bluetoothAdapter);