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

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

Issue 1927803002: arc: bluetooth: Add gatt client functionality (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add more code comment Created 4 years, 7 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 ce593d7a5751760db19f3154595da4ee98f24bdf..6992f9b798c7f77fe5b17a155871fc9e25e8cc4e 100644
--- a/components/arc/bluetooth/arc_bluetooth_bridge.cc
+++ b/components/arc/bluetooth/arc_bluetooth_bridge.cc
@@ -21,17 +21,27 @@
#include "components/arc/bluetooth/bluetooth_type_converters.h"
#include "device/bluetooth/bluetooth_adapter_factory.h"
#include "device/bluetooth/bluetooth_device.h"
+#include "device/bluetooth/bluetooth_gatt_connection.h"
+#include "device/bluetooth/bluetooth_gatt_notify_session.h"
#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
#include "device/bluetooth/bluetooth_remote_gatt_descriptor.h"
#include "device/bluetooth/bluetooth_remote_gatt_service.h"
using device::BluetoothAdapter;
using device::BluetoothAdapterFactory;
+using device::BluetoothAdvertisement;
using device::BluetoothDevice;
+using device::BluetoothDiscoveryFilter;
using device::BluetoothDiscoverySession;
+using device::BluetoothGattConnection;
+using device::BluetoothGattNotifySession;
+using device::BluetoothGattCharacteristic;
+using device::BluetoothGattDescriptor;
+using device::BluetoothGattService;
using device::BluetoothRemoteGattCharacteristic;
using device::BluetoothRemoteGattDescriptor;
using device::BluetoothRemoteGattService;
+using device::BluetoothUUID;
namespace arc {
@@ -105,6 +115,14 @@ void ArcBluetoothBridge::DeviceAdded(BluetoothAdapter* adapter,
arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
std::move(properties));
+
+ mojom::BluetoothAddressPtr addr =
+ mojom::BluetoothAddress::From(device->GetAddress());
+ int rssi = device->GetInquiryRSSI();
+ mojo::Array<uint8_t> adv_data = GetAdvData(device);
+
+ arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
Luis Héctor Chávez 2016/06/01 21:12:03 Version check? Same with all other calls you intro
+ std::move(addr), rssi, std::move(adv_data));
}
void ArcBluetoothBridge::DeviceChanged(BluetoothAdapter* adapter,
@@ -164,7 +182,14 @@ void ArcBluetoothBridge::GattServiceRemoved(
void ArcBluetoothBridge::GattServicesDiscovered(BluetoothAdapter* adapter,
BluetoothDevice* device) {
- // Placeholder for GATT client functionality
+ if (!HasBluetoothInstance())
+ return;
+
+ mojom::BluetoothAddressPtr addr =
+ mojom::BluetoothAddress::From(device->GetAddress());
+
+ arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
+ std::move(addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
}
void ArcBluetoothBridge::GattDiscoveryCompleteForService(
@@ -461,6 +486,512 @@ void ArcBluetoothBridge::GetConnectionState(
callback.Run(device->IsConnected());
}
+void ArcBluetoothBridge::StartLEScan() {
+ DCHECK(bluetooth_adapter_);
+ if (discovery_session_) {
+ LOG(ERROR) << "Discovery session already running; leaving alone";
+ SendCachedDevicesFound();
+ return;
+ }
+ BluetoothDiscoveryFilter* df = new BluetoothDiscoveryFilter(
+ BluetoothDiscoveryFilter::Transport::TRANSPORT_LE);
+ std::unique_ptr<BluetoothDiscoveryFilter> discovery_filter(df);
+ bluetooth_adapter_->StartDiscoverySessionWithFilter(
+ std::move(discovery_filter),
+ base::Bind(&ArcBluetoothBridge::OnDiscoveryStarted,
+ weak_factory_.GetWeakPtr()),
+ base::Bind(&ArcBluetoothBridge::OnDiscoveryError,
+ weak_factory_.GetWeakPtr()));
+}
+
+void ArcBluetoothBridge::StopLEScan() {
+ CancelDiscovery();
+}
+
+void ArcBluetoothBridge::OnGattConnected(
+ mojom::BluetoothAddressPtr addr,
+ std::unique_ptr<BluetoothGattConnection> connection) const {
+ if (!HasBluetoothInstance())
+ return;
+
+ DCHECK(addr);
+
+ arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
+ std::move(addr), true);
+}
+
+void ArcBluetoothBridge::OnGattConnectError(
+ mojom::BluetoothAddressPtr addr,
+ BluetoothDevice::ConnectErrorCode error_code) const {
+ if (!HasBluetoothInstance())
+ return;
+
+ DCHECK(addr);
+
+ arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
+ std::move(addr), false);
+}
+
+void ArcBluetoothBridge::OnGattDisconnected(
+ mojom::BluetoothAddressPtr addr) const {
+ if (!HasBluetoothInstance())
+ return;
+
+ DCHECK(addr);
+
+ arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
+ std::move(addr), false);
+}
+
+void ArcBluetoothBridge::ConnectLEDevice(
+ mojom::BluetoothAddressPtr remote_addr) {
+ if (!HasBluetoothInstance())
+ return;
+
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+
+ if (device->IsConnected()) {
+ arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
+ std::move(remote_addr), true);
+ return;
+ }
+
+ // Also pass disconnect callback in error case
+ // since it would be disconnected anyway.
+ mojom::BluetoothAddressPtr remote_addr1 = remote_addr.Clone();
+ device->CreateGattConnection(
+ base::Bind(&ArcBluetoothBridge::OnGattConnected,
+ weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
+ base::Bind(&ArcBluetoothBridge::OnGattConnectError,
+ weak_factory_.GetWeakPtr(), base::Passed(&remote_addr1)));
+}
+
+void ArcBluetoothBridge::DisconnectLEDevice(
+ mojom::BluetoothAddressPtr remote_addr) {
+ if (!HasBluetoothInstance())
+ return;
+
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+
+ if (!device->IsConnected()) {
+ arc_bridge_service()->bluetooth_instance()->OnLEConnectionStateChange(
+ std::move(remote_addr), false);
+ return;
+ }
+
+ mojom::BluetoothAddressPtr remote_addr1 = remote_addr.Clone();
+ device->Disconnect(
+ base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
+ weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
+ base::Bind(&ArcBluetoothBridge::OnGattDisconnected,
+ weak_factory_.GetWeakPtr(), base::Passed(&remote_addr1)));
+}
+
+void ArcBluetoothBridge::SearchService(mojom::BluetoothAddressPtr remote_addr) {
+ if (!HasBluetoothInstance())
+ return;
+
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+
+ // Call the callback if discovery is completed
+ if (device->IsGattServicesDiscoveryComplete()) {
+ arc_bridge_service()->bluetooth_instance()->OnSearchComplete(
+ std::move(remote_addr), mojom::BluetoothGattStatus::GATT_SUCCESS);
+ return;
+ }
+
+ // Discard result. Will call the callback when discovery is completed.
+ device->GetGattServices();
+}
+
+void ArcBluetoothBridge::OnStartLEListenDone(
+ const StartLEListenCallback& callback,
+ scoped_refptr<BluetoothAdvertisement> adv) {
+ advertisment_ = adv;
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnStartLEListenError(
+ const StartLEListenCallback& callback,
+ BluetoothAdvertisement::ErrorCode error_code) {
+ advertisment_ = nullptr;
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+}
+
+void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) {
+ std::unique_ptr<BluetoothAdvertisement::Data> adv_data =
+ base::WrapUnique(new BluetoothAdvertisement::Data(
+ BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST));
+ adv_data->set_service_uuids(
+ base::WrapUnique(new BluetoothAdvertisement::UUIDList()));
+ adv_data->set_manufacturer_data(
+ base::WrapUnique(new BluetoothAdvertisement::ManufacturerData()));
+ adv_data->set_solicit_uuids(
+ base::WrapUnique(new BluetoothAdvertisement::UUIDList()));
+ adv_data->set_service_data(
+ base::WrapUnique(new BluetoothAdvertisement::ServiceData()));
+ bluetooth_adapter_->RegisterAdvertisement(
+ std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnStartLEListenError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::OnStopLEListenDone(
+ const StopLEListenCallback& callback) {
+ advertisment_ = nullptr;
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnStopLEListenError(
+ const StopLEListenCallback& callback,
+ BluetoothAdvertisement::ErrorCode error_code) {
+ advertisment_ = nullptr;
+ callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
+}
+
+void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) {
+ if (!advertisment_) {
+ OnStopLEListenError(
+ callback,
+ BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
+ return;
+ }
+ advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
+ if (!HasBluetoothInstance())
+ return;
+
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+ mojo::Array<mojom::BluetoothGattDBElementPtr> db;
+ for (auto& service : device->GetGattServices()) {
+ mojom::BluetoothGattDBElementPtr element =
+ mojom::BluetoothGattDBElement::New();
+
+ // Example: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
+ std::string id_str = service->GetIdentifier();
+
+ // Convert last digit of service id to int in base 16
+ int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
+
+ element->id = id;
+ element->uuid = mojom::BluetoothUUID::From(service->GetUUID());
+ if (service->IsPrimary()) {
+ element->type =
+ mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE;
+ } else {
+ element->type =
+ mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE;
+ }
+ element->attribute_handle = id;
+ std::vector<BluetoothRemoteGattCharacteristic*> characteristics =
+ service->GetCharacteristics();
+ if (characteristics.size() > 0) {
+ std::string first_id_str = characteristics.front()->GetIdentifier();
+ int first_id =
+ std::stoi(first_id_str.substr(first_id_str.size() - 4), nullptr, 16);
+ std::string last_id_str = characteristics.back()->GetIdentifier();
+ int last_id =
+ std::stoi(last_id_str.substr(last_id_str.size() - 4), nullptr, 16);
+ element->start_handle = first_id;
+ element->end_handle = last_id;
+ }
+ db.push_back(std::move(element));
+
+ for (auto& characteristic : characteristics) {
+ mojom::BluetoothGattDBElementPtr element =
+ mojom::BluetoothGattDBElement::New();
+ std::string id_str = characteristic->GetIdentifier();
+ int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
+ element->id = id;
+ element->uuid = mojom::BluetoothUUID::From(characteristic->GetUUID());
+ element->type =
+ mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC;
+ element->attribute_handle = id;
+ element->properties = characteristic->GetProperties();
+ db.push_back(std::move(element));
+
+ for (auto& descriptor : characteristic->GetDescriptors()) {
+ mojom::BluetoothGattDBElementPtr element =
+ mojom::BluetoothGattDBElement::New();
+ std::string id_str = descriptor->GetIdentifier();
+ int id = std::stoi(id_str.substr(id_str.size() - 4), nullptr, 16);
+ element->id = id;
+ element->uuid = mojom::BluetoothUUID::From(descriptor->GetUUID());
+ element->type =
+ mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR;
+ element->attribute_handle = id;
+ db.push_back(std::move(element));
+ }
+ }
+ }
+
+ arc_bridge_service()->bluetooth_instance()->OnGetGattDB(
+ std::move(remote_addr), std::move(db));
+}
+
+BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id) const {
+ DCHECK(remote_addr);
+ DCHECK(service_id);
+ DCHECK(char_id);
+
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+ if (!device)
+ return nullptr;
+
+ BluetoothUUID serv_uuid = service_id->id->uuid.To<BluetoothUUID>();
+
+ BluetoothRemoteGattService* service = nullptr;
+ for (auto& s : device->GetGattServices()) {
+ if (s->GetUUID() == serv_uuid) {
+ service = s;
+ break;
+ }
+ }
+ if (!service)
+ return nullptr;
+
+ BluetoothUUID char_uuid = char_id->uuid.To<BluetoothUUID>();
+
+ for (auto& c : service->GetCharacteristics()) {
+ if (c->GetUUID() == char_uuid) {
+ return c;
+ }
+ }
+ return nullptr;
+}
+
+BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ mojom::BluetoothGattIDPtr desc_id) const {
+ BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
+ std::move(remote_addr), std::move(service_id), std::move(char_id));
+
+ if (!characteristic)
+ return nullptr;
+
+ BluetoothUUID desc_uuid = desc_id->uuid.To<BluetoothUUID>();
+ for (auto& d : characteristic->GetDescriptors()) {
+ if (d->GetUUID() == desc_uuid) {
+ return d;
+ }
+ }
+ return nullptr;
+}
+
+// same callback for both ReadGattCharacteristic and ReadGattDescriptor
+void ArcBluetoothBridge::OnGattReadDone(
+ const GattReadCallback& callback,
+ const std::vector<uint8_t>& result) const {
+ mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
+ gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS;
+ gattValue->len = result.size();
+ gattValue->type = 0;
+ gattValue->value = mojo::Array<uint8_t>::From(result);
+ callback.Run(std::move(gattValue));
+}
+
+void ArcBluetoothBridge::OnGattReadError(
+ const GattReadCallback& callback,
+ BluetoothGattService::GattErrorCode error_code) const {
+ mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New();
+ gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code);
+ gattValue->len = 0;
+ gattValue->type = 0;
+ gattValue->value = nullptr;
+
+ callback.Run(std::move(gattValue));
+}
+
+// same callback for both WriteGattCharacteristic and WriteGattDescriptor
+void ArcBluetoothBridge::OnGattWriteDone(
+ const GattWriteCallback& callback) const {
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnGattWriteError(
+ const GattWriteCallback& callback,
+ BluetoothGattService::GattErrorCode error_code) const {
+ callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
+}
+
+void ArcBluetoothBridge::ReadGattCharacteristic(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ const ReadGattCharacteristicCallback& callback) {
+ BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
+ std::move(remote_addr), std::move(service_id), std::move(char_id));
+
+ DCHECK(characteristic);
+
+ DCHECK(characteristic->GetPermissions() &&
+ BluetoothGattCharacteristic::Permission::PERMISSION_READ);
+
+ characteristic->ReadRemoteCharacteristic(
+ base::Bind(&ArcBluetoothBridge::OnGattReadDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnGattReadError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::WriteGattCharacteristic(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ mojom::BluetoothGattValuePtr value,
+ const WriteGattCharacteristicCallback& callback) {
+ BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
+ std::move(remote_addr), std::move(service_id), std::move(char_id));
+
+ DCHECK(characteristic);
+
+ DCHECK(characteristic->GetPermissions() &&
+ BluetoothGattCharacteristic::Permission::PERMISSION_WRITE);
+
+ std::vector<uint8_t> new_value = value->value.To<std::vector<uint8_t>>();
+
+ characteristic->WriteRemoteCharacteristic(
+ new_value, base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnGattWriteError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::ReadGattDescriptor(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ mojom::BluetoothGattIDPtr desc_id,
+ const ReadGattDescriptorCallback& callback) {
+ BluetoothRemoteGattDescriptor* descriptor =
+ FindGattDescriptor(std::move(remote_addr), std::move(service_id),
+ std::move(char_id), std::move(desc_id));
+ DCHECK(descriptor);
+
+ DCHECK(descriptor->GetPermissions() &&
+ BluetoothGattCharacteristic::Permission::PERMISSION_READ);
+
+ descriptor->ReadRemoteDescriptor(
+ base::Bind(&ArcBluetoothBridge::OnGattReadDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnGattReadError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::WriteGattDescriptor(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ mojom::BluetoothGattIDPtr desc_id,
+ mojom::BluetoothGattValuePtr value,
+ const WriteGattDescriptorCallback& callback) {
+ BluetoothRemoteGattDescriptor* descriptor =
+ FindGattDescriptor(std::move(remote_addr), std::move(service_id),
+ std::move(char_id), std::move(desc_id));
+ DCHECK(descriptor);
+
+ DCHECK(descriptor->GetPermissions() &&
+ BluetoothGattCharacteristic::Permission::PERMISSION_WRITE);
+
+ std::vector<uint8_t> new_value = value->value.To<std::vector<uint8_t>>();
+
+ descriptor->WriteRemoteDescriptor(
+ new_value, base::Bind(&ArcBluetoothBridge::OnGattWriteDone,
+ weak_factory_.GetWeakPtr(), callback),
+ base::Bind(&ArcBluetoothBridge::OnGattWriteError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::OnGattNotifyStartDone(
+ const RegisterForGattNotificationCallback& callback,
+ const std::string char_string_id,
+ std::unique_ptr<BluetoothGattNotifySession> notify_session) {
+ notification_session_[char_string_id] = std::move(notify_session);
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::OnGattNotifyStartError(
+ const RegisterForGattNotificationCallback& callback,
+ BluetoothGattService::GattErrorCode error_code) const {
+ callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code));
+}
+
+void ArcBluetoothBridge::OnGattNotifyStopDone(
+ const DeregisterForGattNotificationCallback& callback) const {
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+}
+
+void ArcBluetoothBridge::RegisterForGattNotification(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ const RegisterForGattNotificationCallback& callback) {
+ BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
+ std::move(remote_addr), std::move(service_id), std::move(char_id));
+
+ DCHECK(characteristic);
+
+ if (characteristic->IsNotifying()) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+ return;
+ }
+
+ characteristic->StartNotifySession(
+ base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
+ weak_factory_.GetWeakPtr(), callback,
+ characteristic->GetIdentifier()),
+ base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::DeregisterForGattNotification(
+ mojom::BluetoothAddressPtr remote_addr,
+ mojom::BluetoothGattServiceIDPtr service_id,
+ mojom::BluetoothGattIDPtr char_id,
+ const DeregisterForGattNotificationCallback& callback) {
+ BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
+ std::move(remote_addr), std::move(service_id), std::move(char_id));
+
+ DCHECK(characteristic);
+
+ if (!characteristic->IsNotifying()) {
+ callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
+ return;
+ }
+
+ std::string char_id_str = characteristic->GetIdentifier();
+ std::unique_ptr<BluetoothGattNotifySession> notify =
+ std::move(notification_session_[char_id_str]);
+ notification_session_.erase(char_id_str);
+ notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone,
+ weak_factory_.GetWeakPtr(), callback));
+}
+
+void ArcBluetoothBridge::ReadRemoteRssi(
+ mojom::BluetoothAddressPtr remote_addr,
+ const ReadRemoteRssiCallback& callback) {
+ BluetoothDevice* device =
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
+ int rssi = device->GetInquiryRSSI();
+ callback.Run(rssi);
+}
+
void ArcBluetoothBridge::OnDiscoveryError() {
LOG(WARNING) << "failed to change discovery state";
}
@@ -541,12 +1072,12 @@ ArcBluetoothBridge::GetDeviceProperties(mojom::BluetoothPropertyType type,
if (type == mojom::BluetoothPropertyType::ALL ||
type == mojom::BluetoothPropertyType::UUIDS) {
mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
- std::vector<device::BluetoothUUID> uuids = device->GetUUIDs();
+ std::vector<BluetoothUUID> uuids = device->GetUUIDs();
mojo::Array<mojom::BluetoothUUIDPtr> uuid_results =
mojo::Array<mojom::BluetoothUUIDPtr>::New(0);
- for (size_t i = 0; i < uuids.size(); i++) {
- uuid_results.push_back(mojom::BluetoothUUID::From(uuids[i]));
+ for (auto& uuid : uuids) {
+ uuid_results.push_back(mojom::BluetoothUUID::From(uuid));
}
btp->set_uuids(std::move(uuid_results));
@@ -638,12 +1169,12 @@ ArcBluetoothBridge::GetAdapterProperties(
mojo::Array<mojom::BluetoothAddressPtr> bonded_devices =
mojo::Array<mojom::BluetoothAddressPtr>::New(0);
- for (size_t i = 0; i < devices.size(); i++) {
- if (!devices[i]->IsPaired())
+ for (auto& device : devices) {
+ if (device->IsPaired())
continue;
mojom::BluetoothAddressPtr addr =
- mojom::BluetoothAddress::From(devices[i]->GetAddress());
+ mojom::BluetoothAddress::From(device->GetAddress());
bonded_devices.push_back(std::move(addr));
}
@@ -660,21 +1191,106 @@ ArcBluetoothBridge::GetAdapterProperties(
return properties;
}
+mojo::Array<uint8_t> ArcBluetoothBridge::GetAdvData(
Luis Héctor Chávez 2016/06/01 21:12:03 eek, sending a blob. Is there absolutely no way to
+ BluetoothDevice* device) const {
+ std::vector<uint8_t> vec = std::vector<uint8_t>();
+ int field_length;
+
+ // const int DATA_TYPE_FLAGS = 0x01;
+ const int DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE = 0x07;
+ const int DATA_TYPE_LOCAL_NAME_COMPLETE = 0x09;
+ const int DATA_TYPE_TX_POWER_LEVEL = 0x0A;
+ const int DATA_TYPE_SERVICE_DATA = 0x16;
+ // const int DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF;
+
+ // AdvertiseFlag
+ // Flags Advertising Data Type
+ // Bit0 – Indicates LE Limited Discoverable Mode
+ // Bit1 – Indicates LE General Discoverable Mode
+ // Bit2 – Indicates whether BR/EDR is supported.
+ // Bit3 – Indicates whether LE and BR/EDR Controller operates simultaneously
+ // Bit4 – Indicates whether LE and BR/EDR Host operates simultaneously
+ // No need? Chrome do not expose this.
+
+ // ServiceUuid
+ BluetoothDevice::UUIDList uuid_list = device->GetServiceDataUUIDs();
+ if (uuid_list.size() > 0) {
+ field_length = uuid_list.size() * 16 + 2;
+ vec.push_back(field_length);
+ vec.push_back(DATA_TYPE_SERVICE_UUIDS_128_BIT_COMPLETE);
+
+ for (auto& uuid : uuid_list) {
+ std::string str = uuid.canonical_value();
+ for (auto& c : str) {
+ if (c == '-')
+ continue;
+ vec.push_back(c);
+ }
+ }
+ }
+
+ // LocalName
+ std::string name = base::UTF16ToUTF8(device->GetName());
+ field_length = name.size() + 2;
+ vec.push_back(field_length);
+ vec.push_back(DATA_TYPE_LOCAL_NAME_COMPLETE);
+ for (auto& c : name) {
+ vec.push_back(c);
+ }
+
+ // txPowerLevel
+ vec.push_back(3);
+ vec.push_back(DATA_TYPE_TX_POWER_LEVEL);
+ vec.push_back(device->GetInquiryTxPower());
+
+ // Service data
+ for (auto& uuid : uuid_list) {
+ base::BinaryValue* data = device->GetServiceData(uuid);
+ if (data->GetSize() == 0)
+ continue;
+ std::string data_str;
+ if (!data->GetAsString(&data_str))
+ continue;
+
+ vec.push_back(2 + data->GetSize());
+ vec.push_back(DATA_TYPE_SERVICE_DATA);
+ for (auto& c : data_str) {
+ vec.push_back(c);
+ }
+ }
+
+ // ManufactureData
+ // No need? Chrome do not expose this.
+
+ vec.push_back(0);
+
+ return mojo::Array<uint8_t>::From(vec);
+}
+
void ArcBluetoothBridge::SendCachedDevicesFound() const {
// Send devices that have already been discovered, but aren't connected.
if (!HasBluetoothInstance())
return;
BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
- for (size_t i = 0; i < devices.size(); i++) {
- if (devices[i]->IsPaired())
+ for (auto& device : devices) {
+ if (device->IsPaired())
continue;
mojo::Array<mojom::BluetoothPropertyPtr> properties =
- GetDeviceProperties(mojom::BluetoothPropertyType::ALL, devices[i]);
+ GetDeviceProperties(mojom::BluetoothPropertyType::ALL, device);
arc_bridge_service()->bluetooth_instance()->OnDeviceFound(
std::move(properties));
+
+ mojom::BluetoothAddressPtr addr =
+ mojom::BluetoothAddress::From(device->GetAddress());
+ int rssi = device->GetInquiryRSSI();
+
+ mojo::Array<uint8_t> adv_data = GetAdvData(device);
+
+ arc_bridge_service()->bluetooth_instance()->OnLEDeviceFound(
+ std::move(addr), rssi, std::move(adv_data));
}
}
@@ -689,9 +1305,11 @@ bool ArcBluetoothBridge::HasBluetoothInstance() const {
void ArcBluetoothBridge::SendCachedPairedDevices() const {
DCHECK(bluetooth_adapter_);
+ if (!HasBluetoothInstance())
+ return;
BluetoothAdapter::DeviceList devices = bluetooth_adapter_->GetDevices();
- for (BluetoothDevice* device : devices) {
+ for (auto& device : devices) {
if (!device->IsPaired())
continue;

Powered by Google App Engine
This is Rietveld 408576698