Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(229)

Unified Diff: components/arc/bluetooth/arc_bluetooth_bridge.cc

Issue 2256003002: components/arc: implement multi advertising (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@plumb-incoming-connections
Patch Set: Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/arc/bluetooth/arc_bluetooth_bridge.cc
diff --git a/components/arc/bluetooth/arc_bluetooth_bridge.cc b/components/arc/bluetooth/arc_bluetooth_bridge.cc
index ba97d46403beb9e2fa4d16031ccc4b4f58cca2d2..88b32e6c9499bf34a43d2960fcc784a00b394f88 100644
--- a/components/arc/bluetooth/arc_bluetooth_bridge.cc
+++ b/components/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -17,6 +17,7 @@
#include "base/logging.h"
#include "base/posix/eintr_wrapper.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
@@ -56,6 +57,7 @@ constexpr int32_t kMinBtleVersion = 1;
constexpr int32_t kMinBtleNotifyVersion = 2;
constexpr int32_t kMinGattServerVersion = 3;
constexpr int32_t kMinAddrChangeVersion = 4;
+constexpr int32_t kMinMultiAdvertisementVersion = 5;
constexpr uint32_t kGattReadPermission =
BluetoothGattCharacteristic::Permission::PERMISSION_READ |
BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
@@ -67,6 +69,7 @@ constexpr uint32_t kGattWritePermission =
BluetoothGattCharacteristic::Permission::
PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
constexpr int32_t kInvalidGattAttributeHandle = -1;
+constexpr int32_t kInvalidAdvertisementHandle = -1;
// Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2
// An attribute handle of value 0xFFFF is known as the maximum attribute handle.
constexpr int32_t kMaxGattAttributeHandle = 0xFFFF;
@@ -76,7 +79,6 @@ constexpr int kMaxGattAttributeLength = 512;
// Copied from Android at system/bt/stack/btm/btm_ble_int.h
// https://goo.gl/k7PM6u
constexpr uint16_t kAndroidMBluetoothVersionNumber = 95;
-constexpr uint16_t kMaxAdvertisement = 5;
using GattStatusCallback =
base::Callback<void(arc::mojom::BluetoothGattStatus)>;
@@ -1392,6 +1394,173 @@ void ArcBluetoothBridge::SendIndication(
mojo::Array<uint8_t> value,
const SendIndicationCallback& callback) {}
+void ArcBluetoothBridge::EnableAdvertising(
+ int32_t min_interval,
+ int32_t max_interval,
+ BluetoothAdvertisement::AdvertisementType adv_type,
+ int32_t channel_map,
+ int32_t tx_power,
+ int32_t timeout_s,
+ const EnableAdvertisingCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
+ kInvalidAdvertisementHandle);
+ return;
+ }
+
+ // Find an empty advertisement slot.
+ int adv_handle = -1;
+ for (int i = 0; i < kMaxAdvertisement; i++)
Luis Héctor Chávez 2016/08/18 04:29:12 nit: this needs braces
+ if (!advertisements_[i].in_use)
+ adv_handle = i;
Luis Héctor Chávez 2016/08/18 04:29:12 break;?
+
+ if (adv_handle == -1) {
+ LOG(WARNING) << "Out of space for advertisement data";
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
+ kInvalidAdvertisementHandle);
+ return;
+ }
+
+ // We have a handle. Mark the advertisement record in-use and
+ // record the advertisement type.
+ advertisements_[adv_handle].in_use = true;
+ advertisements_[adv_handle].adv_type = adv_type;
+
+ // The advertisement will be registered when we get the call
+ // to SetAdvertisingData. For now, just return the adv_handle.
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle);
+}
+
+void ArcBluetoothBridge::SetAdvertisingData(
+ int32_t adv_handle,
+ bool include_name,
+ bool include_tx_power,
+ int32_t appearance,
+ mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data,
+ const SetAdvertisingDataCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+ return;
+ }
+
+ if (adv_handle < 0 || adv_handle > kMaxAdvertisement ||
puthik_chromium 2016/08/17 23:22:04 adv_handle >= kMaxAdvertisement
Luis Héctor Chávez 2016/08/18 04:29:12 Actually you're repeating the same snippet several
+ !advertisements_[adv_handle].in_use) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+ return;
+ }
+
+ // Create BluetoothAdvertisement::Data using the adv_type we got when
puthik_chromium 2016/08/17 23:27:11 Should this in the type_converter?
rkc 2016/08/18 00:06:09 What Opal said. This should be in a type converter
+ // advertising was enabled, and the data in adv_data.
+ std::unique_ptr<BluetoothAdvertisement::Data> data = base::WrapUnique(
Luis Héctor Chávez 2016/08/18 04:29:12 base::WrapUnique(new T(...)) is being deprecated.
+ new BluetoothAdvertisement::Data(advertisements_[adv_handle].adv_type));
+ for (const auto& adv_entry : adv_data) {
+ if (adv_entry->is_service_uuids()) {
+ std::vector<BluetoothUUID> adv_uuids =
+ adv_entry->get_service_uuids().To<std::vector<BluetoothUUID>>();
+
+ std::unique_ptr<std::vector<std::string>> uuid_list =
+ base::WrapUnique(new std::vector<std::string>());
+ for (const auto& uuid : adv_uuids) {
+ uuid_list->push_back(uuid.value());
+ }
+ data->set_service_uuids(std::move(uuid_list));
+ } else if (adv_entry->is_service_data()) {
+ std::string service_uuid =
+ base::StringPrintf("%04x", adv_entry->get_service_data()->uuid_16bit);
+ std::vector<uint8_t> service_data =
+ adv_entry->get_service_data()->data.To<std::vector<uint8_t>>();
+
+ data->set_service_data(
+ base::WrapUnique(new std::map<std::string, std::vector<uint8_t>>{
+ {service_uuid, service_data}}));
+ } else if (adv_entry->is_manufacturer_data()) {
+ // We get manufacturer data as a big blob. The first two bytes
+ // should be a company identifier code in little-endian.
+ std::vector<uint8_t> blob =
+ adv_entry->get_manufacturer_data().To<std::vector<uint8_t>>();
+ if (blob.size() < 2) {
Luis Héctor Chávez 2016/08/18 04:29:13 nit: s/2/sizeof(uint16_t)/
+ LOG(WARNING) << "Received malformed manufacturer data for handle "
+ << adv_handle;
+ advertisements_[adv_handle].Clear();
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+ return;
+ }
+
+ uint16_t cic = blob[0] << 8 | blob[1];
Luis Héctor Chávez 2016/08/18 04:29:12 Please add the same comment about the endianness h
+ blob.erase(blob.begin(), blob.begin() + 2);
+ data->set_manufacturer_data(base::WrapUnique(
+ new std::map<uint16_t, std::vector<uint8_t>>{{cic, blob}}));
+ }
+ }
+ data->set_include_tx_power(include_tx_power);
+
+ bluetooth_adapter_->RegisterAdvertisement(
+ std::move(data),
+ base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone,
+ weak_factory_.GetWeakPtr(), callback, adv_handle),
+ base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
+ weak_factory_.GetWeakPtr(), callback, adv_handle));
+}
+
+void ArcBluetoothBridge::OnRegisterAdvertisementDone(
+ const SetAdvertisingDataCallback& callback,
+ int32_t adv_handle,
+ scoped_refptr<BluetoothAdvertisement> advertisement) {
+ advertisements_[adv_handle].advertisement = advertisement;
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnRegisterAdvertisementError(
+ const SetAdvertisingDataCallback& callback,
+ int32_t adv_handle,
+ BluetoothAdvertisement::ErrorCode error_code) {
+ LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle
+ << ", error code = " << error_code;
+ advertisements_[adv_handle].Clear();
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+}
+
+void ArcBluetoothBridge::DisableAdvertising(
+ int32_t adv_handle,
+ const DisableAdvertisingCallback& callback) {
+ DCHECK(CalledOnValidThread());
+ if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+ return;
+ }
+
+ if (adv_handle < 0 || adv_handle > kMaxAdvertisement ||
rkc 2016/08/18 00:06:09 adv_handle >= kMaxAdvertisement
+ !advertisements_[adv_handle].in_use) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+ return;
+ }
+
+ advertisements_[adv_handle].advertisement->Unregister(
+ base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone,
+ weak_factory_.GetWeakPtr(), callback, adv_handle),
+ base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError,
+ weak_factory_.GetWeakPtr(), callback, adv_handle));
+}
+
+void ArcBluetoothBridge::OnUnregisterAdvertisementDone(
+ const DisableAdvertisingCallback& callback,
+ int32_t adv_handle) {
+ advertisements_[adv_handle].Clear();
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnUnregisterAdvertisementError(
+ const DisableAdvertisingCallback& callback,
+ int32_t adv_handle,
+ BluetoothAdvertisement::ErrorCode error_code) {
+ LOG(WARNING) << "Failed to disable advertising for handle " << adv_handle
+ << ", error code = " << error_code;
+ advertisements_[adv_handle].Clear();
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+}
+
void ArcBluetoothBridge::OnDiscoveryError() {
LOG(WARNING) << "failed to change discovery state";
}

Powered by Google App Engine
This is Rietveld 408576698