mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-16 15:36:12 -04:00
Add Extended Advertising support in Nearby Connections layer
PiperOrigin-RevId: 452112156
This commit is contained in:
committed by
Copybara-Service
parent
93bc497872
commit
b4b74ca5b4
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user