Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" | 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" |
| 6 | 6 |
| 7 #include <bluetooth/bluetooth.h> | 7 #include <bluetooth/bluetooth.h> |
| 8 #include <fcntl.h> | 8 #include <fcntl.h> |
| 9 #include <stddef.h> | 9 #include <stddef.h> |
| 10 #include <sys/socket.h> | 10 #include <sys/socket.h> |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 #include "base/threading/thread_task_runner_handle.h" | 21 #include "base/threading/thread_task_runner_handle.h" |
| 22 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 23 #include "components/arc/arc_bridge_service.h" | 23 #include "components/arc/arc_bridge_service.h" |
| 24 #include "components/arc/bluetooth/bluetooth_type_converters.h" | 24 #include "components/arc/bluetooth/bluetooth_type_converters.h" |
| 25 #include "device/bluetooth/bluetooth_common.h" | 25 #include "device/bluetooth/bluetooth_common.h" |
| 26 #include "device/bluetooth/bluetooth_device.h" | 26 #include "device/bluetooth/bluetooth_device.h" |
| 27 #include "device/bluetooth/bluetooth_gatt_connection.h" | 27 #include "device/bluetooth/bluetooth_gatt_connection.h" |
| 28 #include "device/bluetooth/bluetooth_gatt_notify_session.h" | 28 #include "device/bluetooth/bluetooth_gatt_notify_session.h" |
| 29 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h" | 29 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h" |
| 30 #include "device/bluetooth/bluetooth_local_gatt_descriptor.h" | 30 #include "device/bluetooth/bluetooth_local_gatt_descriptor.h" |
| 31 #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.
| |
| 32 #include "device/bluetooth/bluetooth_remote_gatt_descriptor.h" | |
| 33 #include "device/bluetooth/bluetooth_remote_gatt_service.h" | |
| 34 #include "device/bluetooth/bluez/bluetooth_device_bluez.h" | |
| 31 #include "mojo/edk/embedder/embedder.h" | 35 #include "mojo/edk/embedder/embedder.h" |
| 32 #include "mojo/edk/embedder/scoped_platform_handle.h" | 36 #include "mojo/edk/embedder/scoped_platform_handle.h" |
| 33 | 37 |
| 34 using device::BluetoothAdapter; | 38 using device::BluetoothAdapter; |
| 35 using device::BluetoothAdapterFactory; | 39 using device::BluetoothAdapterFactory; |
| 36 using device::BluetoothAdvertisement; | 40 using device::BluetoothAdvertisement; |
| 37 using device::BluetoothDevice; | 41 using device::BluetoothDevice; |
| 38 using device::BluetoothDiscoveryFilter; | 42 using device::BluetoothDiscoveryFilter; |
| 39 using device::BluetoothDiscoverySession; | 43 using device::BluetoothDiscoverySession; |
| 40 using device::BluetoothGattConnection; | 44 using device::BluetoothGattConnection; |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | | 69 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 66 BluetoothGattCharacteristic::Permission:: | 70 BluetoothGattCharacteristic::Permission:: |
| 67 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; | 71 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 68 constexpr int32_t kInvalidGattAttributeHandle = -1; | 72 constexpr int32_t kInvalidGattAttributeHandle = -1; |
| 69 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 | 73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 |
| 70 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. | 74 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. |
| 71 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 75 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
| 72 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 | 76 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 |
| 73 // The maximum length of an attribute value shall be 512 octets. | 77 // The maximum length of an attribute value shall be 512 octets. |
| 74 constexpr int kMaxGattAttributeLength = 512; | 78 constexpr int kMaxGattAttributeLength = 512; |
| 79 // Bluetooth SDP Service Class ID List Attribute identifier | |
| 80 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; | |
| 75 | 81 |
| 76 using GattStatusCallback = | 82 using GattStatusCallback = |
| 77 base::Callback<void(arc::mojom::BluetoothGattStatus)>; | 83 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
| 78 using GattReadCallback = | 84 using GattReadCallback = |
| 79 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; | 85 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
| 86 using GetSdpRecordsCallback = | |
| 87 base::Callback<void(arc::mojom::BluetoothGetSdpRecordsResultPtr)>; | |
| 88 using CreateSdpRecordCallback = | |
| 89 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; | |
| 90 using RemoveSdpRecordCallback = | |
| 91 base::Callback<void(arc::mojom::BluetoothStatus)>; | |
| 80 | 92 |
| 81 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a | 93 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
| 82 // Convert the last 4 characters of |identifier| to an | 94 // Convert the last 4 characters of |identifier| to an |
| 83 // int, by interpreting them as hexadecimal digits. | 95 // int, by interpreting them as hexadecimal digits. |
| 84 int ConvertGattIdentifierToId(const std::string identifier) { | 96 int ConvertGattIdentifierToId(const std::string identifier) { |
| 85 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); | 97 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); |
| 86 } | 98 } |
| 87 | 99 |
| 88 // Create GattDBElement and fill in common data for | 100 // Create GattDBElement and fill in common data for |
| 89 // Gatt Service/Characteristic/Descriptor. | 101 // Gatt Service/Characteristic/Descriptor. |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 166 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) | 178 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) |
| 167 success_callback.Run(); | 179 success_callback.Run(); |
| 168 else | 180 else |
| 169 error_callback.Run(); | 181 error_callback.Run(); |
| 170 } | 182 } |
| 171 | 183 |
| 172 bool IsGattOffsetValid(int offset) { | 184 bool IsGattOffsetValid(int offset) { |
| 173 return 0 <= offset && offset < kMaxGattAttributeLength; | 185 return 0 <= offset && offset < kMaxGattAttributeLength; |
| 174 } | 186 } |
| 175 | 187 |
| 188 void OnGetServiceRecordsDone( | |
| 189 const GetSdpRecordsCallback& callback, | |
| 190 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records) { | |
| 191 arc::mojom::BluetoothGetSdpRecordsResultPtr result = | |
| 192 arc::mojom::BluetoothGetSdpRecordsResult::New(); | |
| 193 | |
| 194 result->status = arc::mojom::BluetoothStatus::SUCCESS; | |
| 195 | |
| 196 for (auto& rcd : records) { | |
| 197 result->records.push_back( | |
| 198 mojo::ConvertTo<arc::mojom::BluetoothSdpRecordPtr>(rcd)); | |
| 199 } | |
| 200 | |
| 201 callback.Run(std::move(result)); | |
| 202 } | |
| 203 | |
| 204 void OnGetServiceRecordsError( | |
| 205 const GetSdpRecordsCallback& callback, | |
| 206 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { | |
| 207 arc::mojom::BluetoothGetSdpRecordsResultPtr result = | |
| 208 arc::mojom::BluetoothGetSdpRecordsResult::New(); | |
| 209 | |
| 210 switch (error_code) { | |
| 211 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: | |
| 212 result->status = arc::mojom::BluetoothStatus::NOT_READY; | |
| 213 break; | |
| 214 case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: | |
| 215 ERROR_DEVICE_DISCONNECTED: | |
| 216 result->status = arc::mojom::BluetoothStatus::RMT_DEV_DOWN; | |
| 217 break; | |
| 218 default: | |
| 219 result->status = arc::mojom::BluetoothStatus::FAIL; | |
| 220 break; | |
| 221 } | |
| 222 | |
| 223 callback.Run(std::move(result)); | |
| 224 } | |
| 225 | |
| 226 void OnCreateServiceRecordDone( | |
| 227 const CreateSdpRecordCallback& callback, | |
| 228 uint32_t service_handle) { | |
| 229 arc::mojom::BluetoothCreateSdpRecordResultPtr result = | |
| 230 arc::mojom::BluetoothCreateSdpRecordResult::New(); | |
| 231 result->status = arc::mojom::BluetoothStatus::SUCCESS; | |
| 232 result->service_handle = service_handle; | |
| 233 | |
| 234 callback.Run(std::move(result)); | |
| 235 } | |
| 236 | |
| 237 void OnCreateServiceRecordError( | |
| 238 const CreateSdpRecordCallback& callback, | |
| 239 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { | |
| 240 arc::mojom::BluetoothCreateSdpRecordResultPtr result = | |
| 241 arc::mojom::BluetoothCreateSdpRecordResult::New(); | |
| 242 if (error_code == | |
| 243 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) | |
| 244 result->status = arc::mojom::BluetoothStatus::NOT_READY; | |
| 245 else | |
| 246 result->status = arc::mojom::BluetoothStatus::FAIL; | |
| 247 | |
| 248 callback.Run(std::move(result)); | |
| 249 } | |
| 250 | |
| 251 void OnRemoveServiceRecordDone( | |
| 252 const RemoveSdpRecordCallback& callback) { | |
| 253 callback.Run(arc::mojom::BluetoothStatus::SUCCESS); | |
| 254 } | |
| 255 | |
| 256 void OnRemoveServiceRecordError( | |
| 257 const RemoveSdpRecordCallback& callback, | |
| 258 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { | |
| 259 arc::mojom::BluetoothStatus status; | |
| 260 if (error_code == | |
| 261 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) | |
| 262 status = arc::mojom::BluetoothStatus::NOT_READY; | |
| 263 else | |
| 264 status = arc::mojom::BluetoothStatus::FAIL; | |
| 265 | |
| 266 callback.Run(status); | |
| 267 } | |
| 268 | |
| 176 } // namespace | 269 } // namespace |
| 177 | 270 |
| 178 namespace arc { | 271 namespace arc { |
| 179 | 272 |
| 180 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 273 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
| 181 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 274 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
| 182 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 275 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
| 183 VLOG(1) << "registering bluetooth adapter"; | 276 VLOG(1) << "registering bluetooth adapter"; |
| 184 BluetoothAdapterFactory::GetAdapter(base::Bind( | 277 BluetoothAdapterFactory::GetAdapter(base::Bind( |
| 185 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 278 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
| (...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1310 OnGattOperationDone(callback); | 1403 OnGattOperationDone(callback); |
| 1311 } | 1404 } |
| 1312 | 1405 |
| 1313 void ArcBluetoothBridge::SendIndication( | 1406 void ArcBluetoothBridge::SendIndication( |
| 1314 int32_t attribute_handle, | 1407 int32_t attribute_handle, |
| 1315 mojom::BluetoothAddressPtr address, | 1408 mojom::BluetoothAddressPtr address, |
| 1316 bool confirm, | 1409 bool confirm, |
| 1317 mojo::Array<uint8_t> value, | 1410 mojo::Array<uint8_t> value, |
| 1318 const SendIndicationCallback& callback) {} | 1411 const SendIndicationCallback& callback) {} |
| 1319 | 1412 |
| 1413 void ArcBluetoothBridge::GetSdpRecords( | |
| 1414 arc::mojom::BluetoothAddressPtr remote_addr, | |
| 1415 const GetSdpRecordsCallback& callback) { | |
| 1416 BluetoothDevice* device = | |
| 1417 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | |
| 1418 | |
| 1419 // Do an early return if there is no device with |remote_addr|. | |
| 1420 if (!device) { | |
| 1421 arc::mojom::BluetoothGetSdpRecordsResultPtr result = | |
| 1422 arc::mojom::BluetoothGetSdpRecordsResult::New(); | |
| 1423 result->status = arc::mojom::BluetoothStatus::FAIL; | |
| 1424 callback.Run(std::move(result)); | |
| 1425 return; | |
| 1426 } | |
| 1427 | |
| 1428 bluez::BluetoothDeviceBlueZ* device_bluez = | |
| 1429 static_cast<bluez::BluetoothDeviceBlueZ*>(device); | |
| 1430 | |
| 1431 device_bluez->GetServiceRecords( | |
| 1432 base::Bind(&OnGetServiceRecordsDone, callback), | |
| 1433 base::Bind(&OnGetServiceRecordsError, callback)); | |
| 1434 } | |
| 1435 | |
| 1436 void ArcBluetoothBridge::CreateSdpRecord( | |
| 1437 arc::mojom::BluetoothSdpRecordPtr record, | |
| 1438 const CreateSdpRecordCallback& callback) { | |
| 1439 bluez::BluetoothServiceRecordBlueZ rcd_bluez( | |
| 1440 mojo::ConvertTo<bluez::BluetoothServiceRecordBlueZ>(record)); | |
| 1441 | |
| 1442 std::vector<uint16_t> v = rcd_bluez.GetAttributeIds(); | |
| 1443 | |
| 1444 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included | |
| 1445 // after type conversion, since it is mandatory for creating a service record. | |
| 1446 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == | |
| 1447 v.end()) { | |
| 1448 arc::mojom::BluetoothCreateSdpRecordResultPtr result = | |
| 1449 mojom::BluetoothCreateSdpRecordResult::New(); | |
| 1450 result->status = arc::mojom::BluetoothStatus::FAIL; | |
| 1451 callback.Run(std::move(result)); | |
| 1452 return; | |
| 1453 } | |
| 1454 | |
| 1455 bluetooth_adapter_->CreateServiceRecord( | |
| 1456 rcd_bluez, base::Bind(&OnCreateServiceRecordDone, callback), | |
| 1457 base::Bind(&OnCreateServiceRecordError, callback)); | |
| 1458 } | |
| 1459 | |
| 1460 void ArcBluetoothBridge::RemoveSdpRecord( | |
| 1461 uint32_t service_handle, | |
| 1462 const RemoveSdpRecordCallback& callback) { | |
| 1463 bluetooth_adapter_->RemoveServiceRecord( | |
| 1464 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), | |
| 1465 base::Bind(&OnRemoveServiceRecordError, callback)); | |
| 1466 } | |
| 1467 | |
| 1320 void ArcBluetoothBridge::OnDiscoveryError() { | 1468 void ArcBluetoothBridge::OnDiscoveryError() { |
| 1321 LOG(WARNING) << "failed to change discovery state"; | 1469 LOG(WARNING) << "failed to change discovery state"; |
| 1322 } | 1470 } |
| 1323 | 1471 |
| 1324 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1472 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
| 1325 if (!HasBluetoothInstance()) | 1473 if (!HasBluetoothInstance()) |
| 1326 return; | 1474 return; |
| 1327 | 1475 |
| 1328 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( | 1476 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( |
| 1329 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1477 mojom::BluetoothStatus::SUCCESS, std::move(addr), |
| (...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1652 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1800 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
| 1653 << ") need version " << version_need; | 1801 << ") need version " << version_need; |
| 1654 return false; | 1802 return false; |
| 1655 } | 1803 } |
| 1656 | 1804 |
| 1657 bool ArcBluetoothBridge::CalledOnValidThread() { | 1805 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 1658 return thread_checker_.CalledOnValidThread(); | 1806 return thread_checker_.CalledOnValidThread(); |
| 1659 } | 1807 } |
| 1660 | 1808 |
| 1661 } // namespace arc | 1809 } // namespace arc |
| OLD | NEW |