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 ...@@ -62,6 +62,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
using UUIDList = std::vector<std::string>; using UUIDList = std::vector<std::string>;
using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>; using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
using ServiceData = std::map<std::string, 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. // Structure that holds the data for an advertisement.
class DEVICE_BLUETOOTH_EXPORT Data { class DEVICE_BLUETOOTH_EXPORT Data {
...@@ -82,6 +83,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement ...@@ -82,6 +83,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
std::unique_ptr<ServiceData> service_data() { std::unique_ptr<ServiceData> service_data() {
return std::move(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) { void set_service_uuids(std::unique_ptr<UUIDList> service_uuids) {
service_uuids_ = std::move(service_uuids); service_uuids_ = std::move(service_uuids);
...@@ -96,6 +100,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement ...@@ -96,6 +100,10 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
void set_service_data(std::unique_ptr<ServiceData> service_data) { void set_service_data(std::unique_ptr<ServiceData> service_data) {
service_data_ = std::move(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) { void set_include_tx_power(bool include_tx_power) {
include_tx_power_ = include_tx_power; include_tx_power_ = include_tx_power;
...@@ -109,6 +117,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement ...@@ -109,6 +117,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdvertisement
std::unique_ptr<ManufacturerData> manufacturer_data_; std::unique_ptr<ManufacturerData> manufacturer_data_;
std::unique_ptr<UUIDList> solicit_uuids_; 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_;
bool include_tx_power_; bool include_tx_power_;
DISALLOW_COPY_AND_ASSIGN(Data); DISALLOW_COPY_AND_ASSIGN(Data);
......
...@@ -26,6 +26,10 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) { ...@@ -26,6 +26,10 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) {
BluetoothAdvertisement::ServiceData service_data; BluetoothAdvertisement::ServiceData service_data;
service_data["1234"] = std::vector<uint8_t>(5, 0); 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::Data data(
BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST); BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
ASSERT_EQ(data.type(), BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST); ASSERT_EQ(data.type(), BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST);
...@@ -70,6 +74,17 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) { ...@@ -70,6 +74,17 @@ TEST(BluetoothAdvertisementTest, DataMembersAreAssignedCorrectly) {
ASSERT_EQ(*data.service_data(), service_data); ASSERT_EQ(*data.service_data(), service_data);
// Retrieve again. // Retrieve again.
ASSERT_FALSE(data.service_data().get()); 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 } // namespace
......
...@@ -89,7 +89,7 @@ BluetoothAdvertisementBlueZ::BluetoothAdvertisementBlueZ( ...@@ -89,7 +89,7 @@ BluetoothAdvertisementBlueZ::BluetoothAdvertisementBlueZ(
bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>( bluez::BluetoothLEAdvertisementServiceProvider::AdvertisementType>(
data->type()), data->type()),
data->service_uuids(), data->manufacturer_data(), data->solicit_uuids(), data->service_uuids(), data->manufacturer_data(), data->solicit_uuids(),
data->service_data()); data->service_data(), data->scan_response_data());
} }
void BluetoothAdvertisementBlueZ::Register( void BluetoothAdvertisementBlueZ::Register(
......
...@@ -82,6 +82,8 @@ class BluetoothAdvertisementBlueZTest : public testing::Test { ...@@ -82,6 +82,8 @@ class BluetoothAdvertisementBlueZTest : public testing::Test {
std::make_unique<BluetoothAdvertisement::UUIDList>()); std::make_unique<BluetoothAdvertisement::UUIDList>());
data->set_service_data( data->set_service_data(
std::make_unique<BluetoothAdvertisement::ServiceData>()); std::make_unique<BluetoothAdvertisement::ServiceData>());
data->set_scan_response_data(
std::make_unique<BluetoothAdvertisement::ScanResponseData>());
return data; return data;
} }
......
...@@ -37,7 +37,8 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -37,7 +37,8 @@ class BluetoothAdvertisementServiceProviderImpl
std::unique_ptr<UUIDList> service_uuids, std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data, std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids, 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()), : origin_thread_id_(base::PlatformThread::CurrentId()),
bus_(bus), bus_(bus),
delegate_(delegate), delegate_(delegate),
...@@ -45,7 +46,8 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -45,7 +46,8 @@ class BluetoothAdvertisementServiceProviderImpl
service_uuids_(std::move(service_uuids)), service_uuids_(std::move(service_uuids)),
manufacturer_data_(std::move(manufacturer_data)), manufacturer_data_(std::move(manufacturer_data)),
solicit_uuids_(std::move(solicit_uuids)), 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(bus);
DCHECK(delegate); DCHECK(delegate);
...@@ -166,6 +168,11 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -166,6 +168,11 @@ class BluetoothAdvertisementServiceProviderImpl
service_data_) { service_data_) {
writer.OpenVariant("o", &variant_writer); writer.OpenVariant("o", &variant_writer);
AppendServiceDataVariant(&variant_writer); AppendServiceDataVariant(&variant_writer);
} else if ((property_name ==
bluetooth_advertisement::kScanResponseDataProperty) &&
scan_response_data_) {
writer.OpenVariant("o", &variant_writer);
AppendScanResponseDataVariant(&variant_writer);
} else { } else {
std::unique_ptr<dbus::ErrorResponse> error_response = std::unique_ptr<dbus::ErrorResponse> error_response =
dbus::ErrorResponse::FromMethodCall( dbus::ErrorResponse::FromMethodCall(
...@@ -239,6 +246,7 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -239,6 +246,7 @@ class BluetoothAdvertisementServiceProviderImpl
AppendManufacturerData(&array_writer); AppendManufacturerData(&array_writer);
AppendSolicitUUIDs(&array_writer); AppendSolicitUUIDs(&array_writer);
AppendServiceData(&array_writer); AppendServiceData(&array_writer);
AppendScanResponseData(&array_writer);
writer.CloseContainer(&array_writer); writer.CloseContainer(&array_writer);
return response; return response;
...@@ -332,6 +340,20 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -332,6 +340,20 @@ class BluetoothAdvertisementServiceProviderImpl
array_writer->CloseContainer(&dict_entry_writer); 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) { void AppendManufacturerDataVariant(dbus::MessageWriter* writer) {
DCHECK(manufacturer_data_); DCHECK(manufacturer_data_);
dbus::MessageWriter array_writer(NULL); dbus::MessageWriter array_writer(NULL);
...@@ -372,6 +394,26 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -372,6 +394,26 @@ class BluetoothAdvertisementServiceProviderImpl
writer->CloseContainer(&array_writer); 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). // Origin thread (i.e. the UI thread in production).
base::PlatformThreadId origin_thread_id_; base::PlatformThreadId origin_thread_id_;
...@@ -390,6 +432,7 @@ class BluetoothAdvertisementServiceProviderImpl ...@@ -390,6 +432,7 @@ class BluetoothAdvertisementServiceProviderImpl
std::unique_ptr<ManufacturerData> manufacturer_data_; std::unique_ptr<ManufacturerData> manufacturer_data_;
std::unique_ptr<UUIDList> solicit_uuids_; 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_;
// D-Bus object we are exporting, owned by this object. // D-Bus object we are exporting, owned by this object.
scoped_refptr<dbus::ExportedObject> exported_object_; scoped_refptr<dbus::ExportedObject> exported_object_;
...@@ -420,12 +463,13 @@ BluetoothLEAdvertisementServiceProvider::Create( ...@@ -420,12 +463,13 @@ BluetoothLEAdvertisementServiceProvider::Create(
std::unique_ptr<UUIDList> service_uuids, std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data, std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids, 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()) { if (!bluez::BluezDBusManager::Get()->IsUsingFakes()) {
return std::make_unique<BluetoothAdvertisementServiceProviderImpl>( return std::make_unique<BluetoothAdvertisementServiceProviderImpl>(
bus, object_path, delegate, type, std::move(service_uuids), bus, object_path, delegate, type, std::move(service_uuids),
std::move(manufacturer_data), std::move(solicit_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) #if defined(USE_REAL_DBUS_CLIENTS)
LOG(FATAL) << "Fake is unavailable if USE_REAL_DBUS_CLIENTS is defined."; LOG(FATAL) << "Fake is unavailable if USE_REAL_DBUS_CLIENTS is defined.";
......
...@@ -27,6 +27,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider { ...@@ -27,6 +27,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider {
using UUIDList = std::vector<std::string>; using UUIDList = std::vector<std::string>;
using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>; using ManufacturerData = std::map<uint16_t, std::vector<uint8_t>>;
using ServiceData = std::map<std::string, 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. // Type of advertisement.
enum AdvertisementType { enum AdvertisementType {
...@@ -63,7 +64,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider { ...@@ -63,7 +64,8 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLEAdvertisementServiceProvider {
std::unique_ptr<UUIDList> service_uuids, std::unique_ptr<UUIDList> service_uuids,
std::unique_ptr<ManufacturerData> manufacturer_data, std::unique_ptr<ManufacturerData> manufacturer_data,
std::unique_ptr<UUIDList> solicit_uuids, 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: protected:
BluetoothLEAdvertisementServiceProvider(); 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