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 29b92d8ec94873772774a9f6a54966bd295babc2..0f8e19b392acbc65aa1eb40d207d6a104cadce8e 100644 |
--- a/components/arc/bluetooth/arc_bluetooth_bridge.cc |
+++ b/components/arc/bluetooth/arc_bluetooth_bridge.cc |
@@ -28,6 +28,10 @@ |
#include "device/bluetooth/bluetooth_gatt_notify_session.h" |
#include "device/bluetooth/bluetooth_local_gatt_characteristic.h" |
#include "device/bluetooth/bluetooth_local_gatt_descriptor.h" |
+#include "device/bluetooth/bluetooth_remote_gatt_characteristic.h" |
rkc
2016/07/27 01:34:56
Not needed?
This and the remote_gatt includes belo
Miao
2016/08/10 15:32:20
Done.
|
+#include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" |
+#include "device/bluetooth/bluetooth_remote_gatt_service.h" |
+#include "device/bluetooth/bluez/bluetooth_device_bluez.h" |
#include "mojo/edk/embedder/embedder.h" |
#include "mojo/edk/embedder/scoped_platform_handle.h" |
@@ -72,11 +76,19 @@ constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
// Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 |
// The maximum length of an attribute value shall be 512 octets. |
constexpr int kMaxGattAttributeLength = 512; |
+// Bluetooth SDP Service Class ID List Attribute identifier |
+constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; |
using GattStatusCallback = |
base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
using GattReadCallback = |
base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
+using GetSdpRecordsCallback = |
+ base::Callback<void(arc::mojom::BluetoothGetSdpRecordsResultPtr)>; |
+using CreateSdpRecordCallback = |
+ base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; |
+using RemoveSdpRecordCallback = |
+ base::Callback<void(arc::mojom::BluetoothStatus)>; |
// Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
// Convert the last 4 characters of |identifier| to an |
@@ -173,6 +185,87 @@ bool IsGattOffsetValid(int offset) { |
return 0 <= offset && offset < kMaxGattAttributeLength; |
} |
+void OnGetServiceRecordsDone( |
+ const GetSdpRecordsCallback& callback, |
+ const std::vector<bluez::BluetoothServiceRecordBlueZ>& records) { |
+ arc::mojom::BluetoothGetSdpRecordsResultPtr result = |
+ arc::mojom::BluetoothGetSdpRecordsResult::New(); |
+ |
+ result->status = arc::mojom::BluetoothStatus::SUCCESS; |
+ |
+ for (auto& rcd : records) { |
+ result->records.push_back( |
+ mojo::ConvertTo<arc::mojom::BluetoothSdpRecordPtr>(rcd)); |
+ } |
+ |
+ callback.Run(std::move(result)); |
+} |
+ |
+void OnGetServiceRecordsError( |
+ const GetSdpRecordsCallback& callback, |
+ bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
+ arc::mojom::BluetoothGetSdpRecordsResultPtr result = |
+ arc::mojom::BluetoothGetSdpRecordsResult::New(); |
+ |
+ switch (error_code) { |
+ case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: |
+ result->status = arc::mojom::BluetoothStatus::NOT_READY; |
+ break; |
+ case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
+ ERROR_DEVICE_DISCONNECTED: |
+ result->status = arc::mojom::BluetoothStatus::RMT_DEV_DOWN; |
+ break; |
+ default: |
+ result->status = arc::mojom::BluetoothStatus::FAIL; |
+ break; |
+ } |
+ |
+ callback.Run(std::move(result)); |
+} |
+ |
+void OnCreateServiceRecordDone( |
+ const CreateSdpRecordCallback& callback, |
+ uint32_t service_handle) { |
+ arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
+ arc::mojom::BluetoothCreateSdpRecordResult::New(); |
+ result->status = arc::mojom::BluetoothStatus::SUCCESS; |
+ result->service_handle = service_handle; |
+ |
+ callback.Run(std::move(result)); |
+} |
+ |
+void OnCreateServiceRecordError( |
+ const CreateSdpRecordCallback& callback, |
+ bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
+ arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
+ arc::mojom::BluetoothCreateSdpRecordResult::New(); |
+ if (error_code == |
+ bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
+ result->status = arc::mojom::BluetoothStatus::NOT_READY; |
+ else |
+ result->status = arc::mojom::BluetoothStatus::FAIL; |
+ |
+ callback.Run(std::move(result)); |
+} |
+ |
+void OnRemoveServiceRecordDone( |
+ const RemoveSdpRecordCallback& callback) { |
+ callback.Run(arc::mojom::BluetoothStatus::SUCCESS); |
+} |
+ |
+void OnRemoveServiceRecordError( |
+ const RemoveSdpRecordCallback& callback, |
+ bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
+ arc::mojom::BluetoothStatus status; |
+ if (error_code == |
+ bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
+ status = arc::mojom::BluetoothStatus::NOT_READY; |
+ else |
+ status = arc::mojom::BluetoothStatus::FAIL; |
+ |
+ callback.Run(status); |
+} |
+ |
} // namespace |
namespace arc { |
@@ -1317,6 +1410,61 @@ void ArcBluetoothBridge::SendIndication( |
mojo::Array<uint8_t> value, |
const SendIndicationCallback& callback) {} |
+void ArcBluetoothBridge::GetSdpRecords( |
+ arc::mojom::BluetoothAddressPtr remote_addr, |
+ const GetSdpRecordsCallback& callback) { |
+ BluetoothDevice* device = |
+ bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
+ |
+ // Do an early return if there is no device with |remote_addr|. |
+ if (!device) { |
+ arc::mojom::BluetoothGetSdpRecordsResultPtr result = |
+ arc::mojom::BluetoothGetSdpRecordsResult::New(); |
+ result->status = arc::mojom::BluetoothStatus::FAIL; |
+ callback.Run(std::move(result)); |
+ return; |
+ } |
+ |
+ bluez::BluetoothDeviceBlueZ* device_bluez = |
+ static_cast<bluez::BluetoothDeviceBlueZ*>(device); |
+ |
+ device_bluez->GetServiceRecords( |
+ base::Bind(&OnGetServiceRecordsDone, callback), |
+ base::Bind(&OnGetServiceRecordsError, callback)); |
+} |
+ |
+void ArcBluetoothBridge::CreateSdpRecord( |
+ arc::mojom::BluetoothSdpRecordPtr record, |
+ const CreateSdpRecordCallback& callback) { |
+ bluez::BluetoothServiceRecordBlueZ rcd_bluez( |
+ mojo::ConvertTo<bluez::BluetoothServiceRecordBlueZ>(record)); |
+ |
+ std::vector<uint16_t> v = rcd_bluez.GetAttributeIds(); |
+ |
+ // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included |
+ // after type conversion, since it is mandatory for creating a service record. |
+ if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == |
+ v.end()) { |
+ arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
+ mojom::BluetoothCreateSdpRecordResult::New(); |
+ result->status = arc::mojom::BluetoothStatus::FAIL; |
+ callback.Run(std::move(result)); |
+ return; |
+ } |
+ |
+ bluetooth_adapter_->CreateServiceRecord( |
+ rcd_bluez, base::Bind(&OnCreateServiceRecordDone, callback), |
+ base::Bind(&OnCreateServiceRecordError, callback)); |
+} |
+ |
+void ArcBluetoothBridge::RemoveSdpRecord( |
+ uint32_t service_handle, |
+ const RemoveSdpRecordCallback& callback) { |
+ bluetooth_adapter_->RemoveServiceRecord( |
+ service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
+ base::Bind(&OnRemoveServiceRecordError, callback)); |
+} |
+ |
void ArcBluetoothBridge::OnDiscoveryError() { |
LOG(WARNING) << "failed to change discovery state"; |
} |