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(const CreateSdpRecordCallback& callback, |
| 195 uint32_t service_handle) { |
| 196 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 197 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 198 result->status = arc::mojom::BluetoothStatus::SUCCESS; |
| 199 result->service_handle = service_handle; |
| 200 |
| 201 callback.Run(std::move(result)); |
| 202 } |
| 203 |
| 204 void OnCreateServiceRecordError( |
| 205 const CreateSdpRecordCallback& callback, |
| 206 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 207 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 208 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 209 if (error_code == |
| 210 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 211 result->status = arc::mojom::BluetoothStatus::NOT_READY; |
| 212 else |
| 213 result->status = arc::mojom::BluetoothStatus::FAIL; |
| 214 |
| 215 callback.Run(std::move(result)); |
| 216 } |
| 217 |
| 218 void OnRemoveServiceRecordDone(const RemoveSdpRecordCallback& callback) { |
| 219 callback.Run(arc::mojom::BluetoothStatus::SUCCESS); |
| 220 } |
| 221 |
| 222 void OnRemoveServiceRecordError( |
| 223 const RemoveSdpRecordCallback& callback, |
| 224 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 225 arc::mojom::BluetoothStatus status; |
| 226 if (error_code == |
| 227 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 228 status = arc::mojom::BluetoothStatus::NOT_READY; |
| 229 else |
| 230 status = arc::mojom::BluetoothStatus::FAIL; |
| 231 |
| 232 callback.Run(status); |
| 233 } |
| 234 |
187 } // namespace | 235 } // namespace |
188 | 236 |
189 namespace arc { | 237 namespace arc { |
190 | 238 |
191 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 239 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
192 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 240 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
193 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 241 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
194 VLOG(1) << "Registering bluetooth adapter."; | 242 VLOG(1) << "Registering bluetooth adapter."; |
195 BluetoothAdapterFactory::GetAdapter(base::Bind( | 243 BluetoothAdapterFactory::GetAdapter(base::Bind( |
196 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 244 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
886 BluetoothDevice* device = | 934 BluetoothDevice* device = |
887 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 935 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
888 DCHECK(device); | 936 DCHECK(device); |
889 | 937 |
890 if (device->IsConnected()) { | 938 if (device->IsConnected()) { |
891 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( | 939 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( |
892 std::move(remote_addr), true); | 940 std::move(remote_addr), true); |
893 return; | 941 return; |
894 } | 942 } |
895 | 943 |
896 // Also pass disconnect callback in error case | 944 // Also pass disconnect callback in error case since it would be disconnected |
897 // since it would be disconnected anyway. | 945 // anyway. |
898 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); | 946 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
899 device->CreateGattConnection( | 947 device->CreateGattConnection( |
900 base::Bind(&ArcBluetoothBridge::OnGattConnected, | 948 base::Bind(&ArcBluetoothBridge::OnGattConnected, |
901 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), | 949 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), |
902 base::Bind(&ArcBluetoothBridge::OnGattConnectError, | 950 base::Bind(&ArcBluetoothBridge::OnGattConnectError, |
903 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); | 951 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); |
904 } | 952 } |
905 | 953 |
906 void ArcBluetoothBridge::DisconnectLEDevice( | 954 void ArcBluetoothBridge::DisconnectLEDevice( |
907 mojom::BluetoothAddressPtr remote_addr) { | 955 mojom::BluetoothAddressPtr remote_addr) { |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 OnGattOperationDone(callback); | 1433 OnGattOperationDone(callback); |
1386 } | 1434 } |
1387 | 1435 |
1388 void ArcBluetoothBridge::SendIndication( | 1436 void ArcBluetoothBridge::SendIndication( |
1389 int32_t attribute_handle, | 1437 int32_t attribute_handle, |
1390 mojom::BluetoothAddressPtr address, | 1438 mojom::BluetoothAddressPtr address, |
1391 bool confirm, | 1439 bool confirm, |
1392 mojo::Array<uint8_t> value, | 1440 mojo::Array<uint8_t> value, |
1393 const SendIndicationCallback& callback) {} | 1441 const SendIndicationCallback& callback) {} |
1394 | 1442 |
| 1443 void ArcBluetoothBridge::GetSdpRecords(mojom::BluetoothAddressPtr remote_addr, |
| 1444 mojom::BluetoothUUIDPtr target_uuid) { |
| 1445 BluetoothDevice* device = |
| 1446 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 1447 |
| 1448 // Do an early return if there is no device with |remote_addr|. |
| 1449 if (!device) { |
| 1450 OnGetServiceRecordsError(std::move(remote_addr), std::move(target_uuid), |
| 1451 bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1452 ERROR_DEVICE_DISCONNECTED); |
| 1453 return; |
| 1454 } |
| 1455 |
| 1456 bluez::BluetoothDeviceBlueZ* device_bluez = |
| 1457 static_cast<bluez::BluetoothDeviceBlueZ*>(device); |
| 1458 |
| 1459 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 1460 mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone(); |
| 1461 |
| 1462 device_bluez->GetServiceRecords( |
| 1463 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone, |
| 1464 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr), |
| 1465 base::Passed(&target_uuid)), |
| 1466 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError, |
| 1467 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone), |
| 1468 base::Passed(&target_uuid_clone))); |
| 1469 } |
| 1470 |
| 1471 void ArcBluetoothBridge::CreateSdpRecord( |
| 1472 const bluez::BluetoothServiceRecordBlueZ& record, |
| 1473 const CreateSdpRecordCallback& callback) { |
| 1474 std::vector<uint16_t> v = record.GetAttributeIds(); |
| 1475 |
| 1476 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included |
| 1477 // after type conversion, since it is mandatory for creating a service record. |
| 1478 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == |
| 1479 v.end()) { |
| 1480 mojom::BluetoothCreateSdpRecordResultPtr result = |
| 1481 mojom::BluetoothCreateSdpRecordResult::New(); |
| 1482 result->status = mojom::BluetoothStatus::FAIL; |
| 1483 callback.Run(std::move(result)); |
| 1484 return; |
| 1485 } |
| 1486 |
| 1487 bluetooth_adapter_->CreateServiceRecord( |
| 1488 record, base::Bind(&OnCreateServiceRecordDone, callback), |
| 1489 base::Bind(&OnCreateServiceRecordError, callback)); |
| 1490 } |
| 1491 |
| 1492 void ArcBluetoothBridge::RemoveSdpRecord( |
| 1493 uint32_t service_handle, |
| 1494 const RemoveSdpRecordCallback& callback) { |
| 1495 bluetooth_adapter_->RemoveServiceRecord( |
| 1496 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
| 1497 base::Bind(&OnRemoveServiceRecordError, callback)); |
| 1498 } |
| 1499 |
1395 void ArcBluetoothBridge::OnDiscoveryError() { | 1500 void ArcBluetoothBridge::OnDiscoveryError() { |
1396 LOG(WARNING) << "failed to change discovery state"; | 1501 LOG(WARNING) << "failed to change discovery state"; |
1397 } | 1502 } |
1398 | 1503 |
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1504 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
1400 if (!HasBluetoothInstance()) | 1505 if (!HasBluetoothInstance()) |
1401 return; | 1506 return; |
1402 | 1507 |
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( | 1508 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( |
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1509 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) { | 1832 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { |
1728 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 1833 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
1729 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | 1834 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
1730 GetAdvertisingData(device); | 1835 GetAdvertisingData(device); |
1731 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( | 1836 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( |
1732 addr->Clone(), rssi.value_or(mojom::kUnknownPower), | 1837 addr->Clone(), rssi.value_or(mojom::kUnknownPower), |
1733 std::move(adv_data)); | 1838 std::move(adv_data)); |
1734 } | 1839 } |
1735 | 1840 |
1736 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1841 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
1737 // to | 1842 // 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 | 1843 // pair-done event. Otherwise the pair-done event will be dropped as an |
1740 // invalid change of paired status. | 1844 // invalid change of paired status. |
1741 OnPairing(addr->Clone()); | 1845 OnPairing(addr->Clone()); |
1742 OnPairedDone(std::move(addr)); | 1846 OnPairedDone(std::move(addr)); |
1743 } | 1847 } |
1744 } | 1848 } |
1745 | 1849 |
| 1850 void ArcBluetoothBridge::OnGetServiceRecordsDone( |
| 1851 mojom::BluetoothAddressPtr remote_addr, |
| 1852 mojom::BluetoothUUIDPtr target_uuid, |
| 1853 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { |
| 1854 if (!HasBluetoothInstance()) |
| 1855 return; |
| 1856 |
| 1857 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1858 mojom::BluetoothStatus::SUCCESS, std::move(remote_addr), |
| 1859 std::move(target_uuid), records_bluez); |
| 1860 } |
| 1861 |
| 1862 void ArcBluetoothBridge::OnGetServiceRecordsError( |
| 1863 mojom::BluetoothAddressPtr remote_addr, |
| 1864 mojom::BluetoothUUIDPtr target_uuid, |
| 1865 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 1866 mojom::BluetoothStatus status; |
| 1867 |
| 1868 switch (error_code) { |
| 1869 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: |
| 1870 status = mojom::BluetoothStatus::NOT_READY; |
| 1871 break; |
| 1872 case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1873 ERROR_DEVICE_DISCONNECTED: |
| 1874 status = mojom::BluetoothStatus::RMT_DEV_DOWN; |
| 1875 break; |
| 1876 default: |
| 1877 status = mojom::BluetoothStatus::FAIL; |
| 1878 break; |
| 1879 } |
| 1880 |
| 1881 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1882 status, std::move(remote_addr), std::move(target_uuid), |
| 1883 std::vector<bluez::BluetoothServiceRecordBlueZ>()); |
| 1884 } |
| 1885 |
1746 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( | 1886 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( |
1747 uint32_t version_need) const { | 1887 uint32_t version_need) const { |
1748 uint32_t version = arc_bridge_service()->bluetooth()->version(); | 1888 uint32_t version = arc_bridge_service()->bluetooth()->version(); |
1749 if (version >= version_need) | 1889 if (version >= version_need) |
1750 return true; | 1890 return true; |
1751 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1891 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
1752 << ") need version " << version_need; | 1892 << ") need version " << version_need; |
1753 return false; | 1893 return false; |
1754 } | 1894 } |
1755 | 1895 |
1756 bool ArcBluetoothBridge::CalledOnValidThread() { | 1896 bool ArcBluetoothBridge::CalledOnValidThread() { |
1757 return thread_checker_.CalledOnValidThread(); | 1897 return thread_checker_.CalledOnValidThread(); |
1758 } | 1898 } |
1759 | 1899 |
1760 } // namespace arc | 1900 } // namespace arc |
OLD | NEW |