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/bluez/bluetooth_device_bluez.h" |
31 #include "mojo/edk/embedder/embedder.h" | 32 #include "mojo/edk/embedder/embedder.h" |
32 #include "mojo/edk/embedder/scoped_platform_handle.h" | 33 #include "mojo/edk/embedder/scoped_platform_handle.h" |
33 | 34 |
34 using device::BluetoothAdapter; | 35 using device::BluetoothAdapter; |
35 using device::BluetoothAdapterFactory; | 36 using device::BluetoothAdapterFactory; |
36 using device::BluetoothAdvertisement; | 37 using device::BluetoothAdvertisement; |
37 using device::BluetoothDevice; | 38 using device::BluetoothDevice; |
38 using device::BluetoothDiscoveryFilter; | 39 using device::BluetoothDiscoveryFilter; |
39 using device::BluetoothDiscoverySession; | 40 using device::BluetoothDiscoverySession; |
40 using device::BluetoothGattConnection; | 41 using device::BluetoothGattConnection; |
(...skipping 29 matching lines...) Expand all Loading... |
70 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 | 71 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 |
71 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. | 72 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. |
72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 73 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 | 74 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 |
74 // The maximum length of an attribute value shall be 512 octets. | 75 // The maximum length of an attribute value shall be 512 octets. |
75 constexpr int kMaxGattAttributeLength = 512; | 76 constexpr int kMaxGattAttributeLength = 512; |
76 // Copied from Android at system/bt/stack/btm/btm_ble_int.h | 77 // Copied from Android at system/bt/stack/btm/btm_ble_int.h |
77 // https://goo.gl/k7PM6u | 78 // https://goo.gl/k7PM6u |
78 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; | 79 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; |
79 constexpr uint16_t kMaxAdvertisement = 5; | 80 constexpr uint16_t kMaxAdvertisement = 5; |
| 81 // Bluetooth SDP Service Class ID List Attribute identifier |
| 82 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; |
80 | 83 |
81 using GattStatusCallback = | 84 using GattStatusCallback = |
82 base::Callback<void(arc::mojom::BluetoothGattStatus)>; | 85 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
83 using GattReadCallback = | 86 using GattReadCallback = |
84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; | 87 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
| 88 using CreateSdpRecordCallback = |
| 89 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; |
| 90 using RemoveSdpRecordCallback = |
| 91 base::Callback<void(arc::mojom::BluetoothStatus)>; |
85 | 92 |
86 // 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 |
87 // Convert the last 4 characters of |identifier| to an | 94 // Convert the last 4 characters of |identifier| to an |
88 // int, by interpreting them as hexadecimal digits. | 95 // int, by interpreting them as hexadecimal digits. |
89 int ConvertGattIdentifierToId(const std::string identifier) { | 96 int ConvertGattIdentifierToId(const std::string identifier) { |
90 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); | 97 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); |
91 } | 98 } |
92 | 99 |
93 // Create GattDBElement and fill in common data for | 100 // Create GattDBElement and fill in common data for |
94 // Gatt Service/Characteristic/Descriptor. | 101 // Gatt Service/Characteristic/Descriptor. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 bool IsGattOffsetValid(int offset) { | 184 bool IsGattOffsetValid(int offset) { |
178 return 0 <= offset && offset < kMaxGattAttributeLength; | 185 return 0 <= offset && offset < kMaxGattAttributeLength; |
179 } | 186 } |
180 | 187 |
181 // This is needed because Android only support UUID 16 bits in advertising data. | 188 // This is needed because Android only support UUID 16 bits in advertising data. |
182 uint16_t GetUUID16(const BluetoothUUID& uuid) { | 189 uint16_t GetUUID16(const BluetoothUUID& uuid) { |
183 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy | 190 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy |
184 return std::stoi(uuid.canonical_value().substr(4, 4), nullptr, 16); | 191 return std::stoi(uuid.canonical_value().substr(4, 4), nullptr, 16); |
185 } | 192 } |
186 | 193 |
| 194 void OnCreateServiceRecordDone( |
| 195 const CreateSdpRecordCallback& callback, |
| 196 uint32_t service_handle) { |
| 197 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 198 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 199 result->status = arc::mojom::BluetoothStatus::SUCCESS; |
| 200 result->service_handle = service_handle; |
| 201 |
| 202 callback.Run(std::move(result)); |
| 203 } |
| 204 |
| 205 void OnCreateServiceRecordError( |
| 206 const CreateSdpRecordCallback& callback, |
| 207 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 208 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 209 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 210 if (error_code == |
| 211 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 212 result->status = arc::mojom::BluetoothStatus::NOT_READY; |
| 213 else |
| 214 result->status = arc::mojom::BluetoothStatus::FAIL; |
| 215 |
| 216 callback.Run(std::move(result)); |
| 217 } |
| 218 |
| 219 void OnRemoveServiceRecordDone( |
| 220 const RemoveSdpRecordCallback& callback) { |
| 221 callback.Run(arc::mojom::BluetoothStatus::SUCCESS); |
| 222 } |
| 223 |
| 224 void OnRemoveServiceRecordError( |
| 225 const RemoveSdpRecordCallback& callback, |
| 226 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 227 arc::mojom::BluetoothStatus status; |
| 228 if (error_code == |
| 229 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 230 status = arc::mojom::BluetoothStatus::NOT_READY; |
| 231 else |
| 232 status = arc::mojom::BluetoothStatus::FAIL; |
| 233 |
| 234 callback.Run(status); |
| 235 } |
| 236 |
187 } // namespace | 237 } // namespace |
188 | 238 |
189 namespace arc { | 239 namespace arc { |
190 | 240 |
191 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 241 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
192 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 242 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
193 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 243 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
194 VLOG(1) << "Registering bluetooth adapter."; | 244 VLOG(1) << "Registering bluetooth adapter."; |
195 BluetoothAdapterFactory::GetAdapter(base::Bind( | 245 BluetoothAdapterFactory::GetAdapter(base::Bind( |
196 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 246 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 BluetoothDevice* device = | 936 BluetoothDevice* device = |
887 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 937 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
888 DCHECK(device); | 938 DCHECK(device); |
889 | 939 |
890 if (device->IsConnected()) { | 940 if (device->IsConnected()) { |
891 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( | 941 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( |
892 std::move(remote_addr), true); | 942 std::move(remote_addr), true); |
893 return; | 943 return; |
894 } | 944 } |
895 | 945 |
896 // Also pass disconnect callback in error case | 946 // Also pass disconnect callback in error case since it would be disconnected |
897 // since it would be disconnected anyway. | 947 // anyway. |
898 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); | 948 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
899 device->CreateGattConnection( | 949 device->CreateGattConnection( |
900 base::Bind(&ArcBluetoothBridge::OnGattConnected, | 950 base::Bind(&ArcBluetoothBridge::OnGattConnected, |
901 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), | 951 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), |
902 base::Bind(&ArcBluetoothBridge::OnGattConnectError, | 952 base::Bind(&ArcBluetoothBridge::OnGattConnectError, |
903 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); | 953 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); |
904 } | 954 } |
905 | 955 |
906 void ArcBluetoothBridge::DisconnectLEDevice( | 956 void ArcBluetoothBridge::DisconnectLEDevice( |
907 mojom::BluetoothAddressPtr remote_addr) { | 957 mojom::BluetoothAddressPtr remote_addr) { |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 OnGattOperationDone(callback); | 1435 OnGattOperationDone(callback); |
1386 } | 1436 } |
1387 | 1437 |
1388 void ArcBluetoothBridge::SendIndication( | 1438 void ArcBluetoothBridge::SendIndication( |
1389 int32_t attribute_handle, | 1439 int32_t attribute_handle, |
1390 mojom::BluetoothAddressPtr address, | 1440 mojom::BluetoothAddressPtr address, |
1391 bool confirm, | 1441 bool confirm, |
1392 mojo::Array<uint8_t> value, | 1442 mojo::Array<uint8_t> value, |
1393 const SendIndicationCallback& callback) {} | 1443 const SendIndicationCallback& callback) {} |
1394 | 1444 |
| 1445 void ArcBluetoothBridge::GetSdpRecords( |
| 1446 mojom::BluetoothAddressPtr remote_addr, |
| 1447 mojom::BluetoothUUIDPtr target_uuid) { |
| 1448 BluetoothDevice* device = |
| 1449 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 1450 |
| 1451 // Do an early return if there is no device with |remote_addr|. |
| 1452 if (!device) { |
| 1453 OnGetServiceRecordsError(std::move(remote_addr), std::move(target_uuid), |
| 1454 bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1455 ERROR_DEVICE_DISCONNECTED); |
| 1456 return; |
| 1457 } |
| 1458 |
| 1459 bluez::BluetoothDeviceBlueZ* device_bluez = |
| 1460 static_cast<bluez::BluetoothDeviceBlueZ*>(device); |
| 1461 |
| 1462 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 1463 mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone(); |
| 1464 |
| 1465 device_bluez->GetServiceRecords( |
| 1466 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone, |
| 1467 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr), |
| 1468 base::Passed(&target_uuid)), |
| 1469 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError, |
| 1470 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone), |
| 1471 base::Passed(&target_uuid_clone))); |
| 1472 } |
| 1473 |
| 1474 void ArcBluetoothBridge::CreateSdpRecord( |
| 1475 const bluez::BluetoothServiceRecordBlueZ& record, |
| 1476 const CreateSdpRecordCallback& callback) { |
| 1477 std::vector<uint16_t> v = record.GetAttributeIds(); |
| 1478 |
| 1479 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included |
| 1480 // after type conversion, since it is mandatory for creating a service record. |
| 1481 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == |
| 1482 v.end()) { |
| 1483 mojom::BluetoothCreateSdpRecordResultPtr result = |
| 1484 mojom::BluetoothCreateSdpRecordResult::New(); |
| 1485 result->status = mojom::BluetoothStatus::FAIL; |
| 1486 callback.Run(std::move(result)); |
| 1487 return; |
| 1488 } |
| 1489 |
| 1490 bluetooth_adapter_->CreateServiceRecord( |
| 1491 record, base::Bind(&OnCreateServiceRecordDone, callback), |
| 1492 base::Bind(&OnCreateServiceRecordError, callback)); |
| 1493 } |
| 1494 |
| 1495 void ArcBluetoothBridge::RemoveSdpRecord( |
| 1496 uint32_t service_handle, |
| 1497 const RemoveSdpRecordCallback& callback) { |
| 1498 bluetooth_adapter_->RemoveServiceRecord( |
| 1499 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
| 1500 base::Bind(&OnRemoveServiceRecordError, callback)); |
| 1501 } |
| 1502 |
1395 void ArcBluetoothBridge::OnDiscoveryError() { | 1503 void ArcBluetoothBridge::OnDiscoveryError() { |
1396 LOG(WARNING) << "failed to change discovery state"; | 1504 LOG(WARNING) << "failed to change discovery state"; |
1397 } | 1505 } |
1398 | 1506 |
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1507 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
1400 if (!HasBluetoothInstance()) | 1508 if (!HasBluetoothInstance()) |
1401 return; | 1509 return; |
1402 | 1510 |
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( | 1511 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( |
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1512 mojom::BluetoothStatus::SUCCESS, std::move(addr), |
(...skipping 322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1727 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { | 1835 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { |
1728 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 1836 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
1729 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | 1837 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
1730 GetAdvertisingData(device); | 1838 GetAdvertisingData(device); |
1731 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( | 1839 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( |
1732 addr->Clone(), rssi.value_or(mojom::kUnknownPower), | 1840 addr->Clone(), rssi.value_or(mojom::kUnknownPower), |
1733 std::move(adv_data)); | 1841 std::move(adv_data)); |
1734 } | 1842 } |
1735 | 1843 |
1736 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1844 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
1737 // to | 1845 // to make sure the bond state machine on Android is ready to take the |
1738 // make sure the bond state machine on Android is ready to take the | |
1739 // pair-done event. Otherwise the pair-done event will be dropped as an | 1846 // pair-done event. Otherwise the pair-done event will be dropped as an |
1740 // invalid change of paired status. | 1847 // invalid change of paired status. |
1741 OnPairing(addr->Clone()); | 1848 OnPairing(addr->Clone()); |
1742 OnPairedDone(std::move(addr)); | 1849 OnPairedDone(std::move(addr)); |
1743 } | 1850 } |
1744 } | 1851 } |
1745 | 1852 |
| 1853 void ArcBluetoothBridge::OnGetServiceRecordsDone( |
| 1854 mojom::BluetoothAddressPtr remote_addr, |
| 1855 mojom::BluetoothUUIDPtr target_uuid, |
| 1856 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { |
| 1857 if (!HasBluetoothInstance()) |
| 1858 return; |
| 1859 |
| 1860 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1861 mojom::BluetoothStatus::SUCCESS, std::move(remote_addr), |
| 1862 std::move(target_uuid), records_bluez); |
| 1863 } |
| 1864 |
| 1865 void ArcBluetoothBridge::OnGetServiceRecordsError( |
| 1866 mojom::BluetoothAddressPtr remote_addr, |
| 1867 mojom::BluetoothUUIDPtr target_uuid, |
| 1868 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 1869 mojom::BluetoothStatus status; |
| 1870 |
| 1871 switch (error_code) { |
| 1872 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: |
| 1873 status = mojom::BluetoothStatus::NOT_READY; |
| 1874 break; |
| 1875 case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1876 ERROR_DEVICE_DISCONNECTED: |
| 1877 status = mojom::BluetoothStatus::RMT_DEV_DOWN; |
| 1878 break; |
| 1879 default: |
| 1880 status = mojom::BluetoothStatus::FAIL; |
| 1881 break; |
| 1882 } |
| 1883 |
| 1884 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1885 status, std::move(remote_addr), std::move(target_uuid), |
| 1886 std::vector<bluez::BluetoothServiceRecordBlueZ>()); |
| 1887 } |
| 1888 |
1746 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( | 1889 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( |
1747 uint32_t version_need) const { | 1890 uint32_t version_need) const { |
1748 uint32_t version = arc_bridge_service()->bluetooth()->version(); | 1891 uint32_t version = arc_bridge_service()->bluetooth()->version(); |
1749 if (version >= version_need) | 1892 if (version >= version_need) |
1750 return true; | 1893 return true; |
1751 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1894 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
1752 << ") need version " << version_need; | 1895 << ") need version " << version_need; |
1753 return false; | 1896 return false; |
1754 } | 1897 } |
1755 | 1898 |
1756 bool ArcBluetoothBridge::CalledOnValidThread() { | 1899 bool ArcBluetoothBridge::CalledOnValidThread() { |
1757 return thread_checker_.CalledOnValidThread(); | 1900 return thread_checker_.CalledOnValidThread(); |
1758 } | 1901 } |
1759 | 1902 |
1760 } // namespace arc | 1903 } // namespace arc |
OLD | NEW |