Commit 85b2daf9 authored by James Vecore's avatar James Vecore Committed by Commit Bot

[Bluetooth] Add ScanResponseData to BLE Adv D-Bus API

This is a temporary change to support scan response data in BLE
advertisements for Nearby Share. Once the final API lands in bluez
upstream we will need to revert this change (tracked here:
https://crbug.com/1136920).

This allows a map of byte (BLE type) to byte array (payload) to be
supplied as the scan response for a BLE advertisement. Currently only a
single type 0x16 is allowed in the map by bluez.

The corresponding bluez change is here: https://crrev.com/c/2458306.

A follow up CL will supply the scan response for Nearby Share.

Bug: 1135699
Change-Id: I3e2c8098a7cfca2025f0c7cd5c6b631156e77de0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2459250
Commit-Queue: James Vecore <vecore@google.com>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Reviewed-by: default avatarMiao-chen Chou <mcchou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#816037}
parent 62d2d5bb
......@@ -62,6 +62,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
using UUIDList = std::vector<std::string>;
using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
using ServiceData = std::map<std::string, std::vector<uint8_t>>;
using ScanResponseData = std::map<uint8_t, std::vector<uint8_t>>;
// Structure that holds the data for an advertisement.
class DEVICE_BLUETOOTH_EXPORT Data {
......@@ -82,6 +83,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
std::unique_ptr<ServiceData> service_data() {
return std::move(service_data_);
}
std::unique_ptr<ScanResponseData> scan_response_data() {
return std::move(scan_response_data_);
}
void set_service_uuids(std::unique_ptr<UUIDList> service_uuids) {
service_uuids_ = std::move(service_uuids);
......@@ -96,6 +100,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
void set_service_data(std::unique_ptr<ServiceData> service_data) {
service_data_ = std::move(service_data);
}
void set_scan_response_data(
std::unique_ptr<ScanResponseData> scan_response_data) {
scan_response_data_ = std::move(scan_response_data);
}
void set_include_tx_power(bool include_tx_power) {
include_tx_power_ = include_tx_power;
......@@ -109,6 +117,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
std::unique_ptr<ManufacturerData> manufacturer_data_;
std::unique_ptr<UUIDList> solicit_uuids_;
std::unique_ptr<ServiceData> service_data_;
std::unique_ptr<ScanResponseData> scan_response_data_;
bool include_tx_power_;
DISALLOW_COPY_AND_ASSIGN(Data);
......
......@@ -26,6 +26,10 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) {
BluetoothAdvertisement::ServiceData service_data;
service_data["1234"] = std::vector<uint8_t>(5, 0);
// Sample Scan Response Data.
BluetoothAdvertisement::ScanResponseData scan_response_data;
scan_response_data[0x16] = std::vector<uint8_t>(5, 0);
BluetoothAdvertisement::Data data(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
ASSERT_EQ(data.type(), BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
......@@ -70,6 +74,17 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) {
ASSERT_EQ(*data.service_data(), service_data);
// Retrieve again.
ASSERT_FALSE(data.service_data().get());
// Try without assigning Scan Response Data.
ASSERT_FALSE(data.scan_response_data().get());
// Assign Service Data.
data.set_scan_response_data(
std::make_unique<BluetoothAdvertisement::ScanResponseData>(
scan_response_data));
// Retrieve Service Data.
ASSERT_EQ(*data.scan_response_data(), scan_response_data);
// Retrieve again.
ASSERT_FALSE(data.scan_response_data().get());
}
} // namespace
......
......@@ -89,7 +89,7 @@ BluetoothAdvertisementBlueZ::BluetoothAdvertisementBlueZ(
bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
data->type()),
data->service_uuids(), data->manufacturer_data(), data->solicit_uuids(),
data->service_data());
data->service_data(), data->scan_response_data());
}
void BluetoothAdvertisementBlueZ::Register(
......
......@@ -82,6 +82,8 @@ class BluetoothAdvertisementBlueZTest : public testing::Test {
std::make_unique<BluetoothAdvertisement::UUIDList>());
data->set_service_data(
std::make_unique<BluetoothAdvertisement::ServiceData>());
data->set_scan_response_data(
std::make_unique<BluetoothAdvertisement::ScanResponseData>());
return data;
}
......
......@@ -37,7 +37,8 @@ class BluetoothAdvertisementServiceProviderImpl
std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids,
std::unique_ptr<ServiceData> service_data)
std::unique_ptr<ServiceData> service_data,
std::unique_ptr<ScanResponseData> scan_response_data)
: origin_thread_id_(base::PlatformThread::CurrentId()),
bus_(bus),
delegate_(delegate),
......@@ -45,7 +46,8 @@ class BluetoothAdvertisementServiceProviderImpl
service_uuids_(std::move(service_uuids)),
manufacturer_data_(std::move(manufacturer_data)),
solicit_uuids_(std::move(solicit_uuids)),
service_data_(std::move(service_data)) {
service_data_(std::move(service_data)),
scan_response_data_(std::move(scan_response_data)) {
DCHECK(bus);
DCHECK(delegate);
......@@ -166,6 +168,11 @@ class BluetoothAdvertisementServiceProviderImpl
service_data_) {
writer.OpenVariant("o", &variant_writer);
AppendServiceDataVariant(&variant_writer);
} else if ((property_name ==
bluetooth_advertisement::kScanResponseDataProperty) &&
scan_response_data_) {
writer.OpenVariant("o", &variant_writer);
AppendScanResponseDataVariant(&variant_writer);
} else {
std::unique_ptr<dbus::ErrorResponse> error_response =
dbus::ErrorResponse::FromMethodCall(
......@@ -239,6 +246,7 @@ class BluetoothAdvertisementServiceProviderImpl
AppendManufacturerData(&array_writer);
AppendSolicitUUIDs(&array_writer);
AppendServiceData(&array_writer);
AppendScanResponseData(&array_writer);
writer.CloseContainer(&array_writer);
return response;
......@@ -332,6 +340,20 @@ class BluetoothAdvertisementServiceProviderImpl
array_writer->CloseContainer(&dict_entry_writer);
}
void AppendScanResponseData(dbus::MessageWriter* array_writer) {
if (!scan_response_data_)
return;
dbus::MessageWriter dict_entry_writer(nullptr);
array_writer->OpenDictEntry(&dict_entry_writer);
dict_entry_writer.AppendString(
bluetooth_advertisement::kScanResponseDataProperty);
dbus::MessageWriter variant_writer(nullptr);
dict_entry_writer.OpenVariant("a{yv}", &variant_writer);
AppendScanResponseDataVariant(&variant_writer);
dict_entry_writer.CloseContainer(&variant_writer);
array_writer->CloseContainer(&dict_entry_writer);
}
void AppendManufacturerDataVariant(dbus::MessageWriter* writer) {
DCHECK(manufacturer_data_);
dbus::MessageWriter array_writer(NULL);
......@@ -372,6 +394,26 @@ class BluetoothAdvertisementServiceProviderImpl
writer->CloseContainer(&array_writer);
}
void AppendScanResponseDataVariant(dbus::MessageWriter* writer) {
DCHECK(scan_response_data_);
dbus::MessageWriter array_writer(nullptr);
writer->OpenArray("{yv}", &array_writer);
for (const auto& m : *scan_response_data_) {
dbus::MessageWriter entry_writer(nullptr);
array_writer.OpenDictEntry(&entry_writer);
entry_writer.AppendByte(m.first);
dbus::MessageWriter variant_writer(nullptr);
entry_writer.OpenVariant("ay", &variant_writer);
variant_writer.AppendArrayOfBytes(m.second.data(), m.second.size());
entry_writer.CloseContainer(&variant_writer);
array_writer.CloseContainer(&entry_writer);
}
writer->CloseContainer(&array_writer);
}
// Origin thread (i.e. the UI thread in production).
base::PlatformThreadId origin_thread_id_;
......@@ -390,6 +432,7 @@ class BluetoothAdvertisementServiceProviderImpl
std::unique_ptr<ManufacturerData> manufacturer_data_;
std::unique_ptr<UUIDList> solicit_uuids_;
std::unique_ptr<ServiceData> service_data_;
std::unique_ptr<ScanResponseData> scan_response_data_;
// D-Bus object we are exporting, owned by this object.
scoped_refptr<dbus::ExportedObject> exported_object_;
......@@ -420,12 +463,13 @@ BluetoothLEAdvertisementServiceProvider::Create(
std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids,
std::unique_ptr<ServiceData> service_data) {
std::unique_ptr<ServiceData> service_data,
std::unique_ptr<ScanResponseData> scan_response_data) {
if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) {
return std::make_unique<BluetoothAdvertisementServiceProviderImpl>(
bus, object_path, delegate, type, std::move(service_uuids),
std::move(manufacturer_data), std::move(solicit_uuids),
std::move(service_data));
std::move(service_data), std::move(scan_response_data));
}
#if defined(USE_REAL_DBUS_CLIENTS)
LOG(FATAL) << "Fake is unavailable if USE_REAL_DBUS_CLIENTS is defined.";
......
......@@ -27,6 +27,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider {
using UUIDList = std::vector<std::string>;
using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
using ServiceData = std::map<std::string, std::vector<uint8_t>>;
using ScanResponseData = std::map<uint8_t, std::vector<uint8_t>>;
// Type of advertisement.
enum AdvertisementType {
......@@ -63,7 +64,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider {
std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids,
std::unique_ptr<ServiceData> service_data);
std::unique_ptr<ServiceData> service_data,
std::unique_ptr<ScanResponseData> scan_response_data);
protected:
BluetoothLEAdvertisementServiceProvider();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment