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 mojom::BluetoothSdpRecordPtr record_mojo, | |
1473 const CreateSdpRecordCallback& callback) { | |
1474 auto record = record_mojo.To<bluez::BluetoothServiceRecordBlueZ>(); | |
1475 | |
1476 std::vector<uint16_t> v = record.GetAttributeIds(); | |
rickyz (no longer on Chrome)
2016/08/29 00:48:06
Wouldn't it be better to extend bluez::BluetoothSe
Miao
2016/09/01 18:45:37
Please see https://codereview.chromium.org/2302963
| |
1477 | |
1478 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included | |
1479 // after type conversion, since it is mandatory for creating a service record. | |
1480 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == | |
1481 v.end()) { | |
1482 mojom::BluetoothCreateSdpRecordResultPtr result = | |
1483 mojom::BluetoothCreateSdpRecordResult::New(); | |
1484 result->status = mojom::BluetoothStatus::FAIL; | |
1485 callback.Run(std::move(result)); | |
1486 return; | |
1487 } | |
1488 | |
1489 bluetooth_adapter_->CreateServiceRecord( | |
1490 record, base::Bind(&OnCreateServiceRecordDone, callback), | |
1491 base::Bind(&OnCreateServiceRecordError, callback)); | |
1492 } | |
1493 | |
1494 void ArcBluetoothBridge::RemoveSdpRecord( | |
1495 uint32_t service_handle, | |
1496 const RemoveSdpRecordCallback& callback) { | |
1497 bluetooth_adapter_->RemoveServiceRecord( | |
1498 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), | |
1499 base::Bind(&OnRemoveServiceRecordError, callback)); | |
1500 } | |
1501 | |
1395 void ArcBluetoothBridge::OnDiscoveryError() { | 1502 void ArcBluetoothBridge::OnDiscoveryError() { |
1396 LOG(WARNING) << "failed to change discovery state"; | 1503 LOG(WARNING) << "failed to change discovery state"; |
1397 } | 1504 } |
1398 | 1505 |
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1506 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
1400 if (!HasBluetoothInstance()) | 1507 if (!HasBluetoothInstance()) |
1401 return; | 1508 return; |
1402 | 1509 |
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( | 1510 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( |
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1511 mojom::BluetoothStatus::SUCCESS, std::move(addr), |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1728 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { | 1835 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { |
1729 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); | 1836 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); |
1730 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | 1837 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
1731 GetAdvertisingData(device); | 1838 GetAdvertisingData(device); |
1732 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( | 1839 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( |
1733 addr->Clone(), rssi.value_or(mojom::kUnknownPower), | 1840 addr->Clone(), rssi.value_or(mojom::kUnknownPower), |
1734 std::move(adv_data)); | 1841 std::move(adv_data)); |
1735 } | 1842 } |
1736 | 1843 |
1737 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1844 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
1738 // to | 1845 // to make sure the bond state machine on Android is ready to take the |
1739 // make sure the bond state machine on Android is ready to take the | |
1740 // 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 |
1741 // invalid change of paired status. | 1847 // invalid change of paired status. |
1742 OnPairing(addr->Clone()); | 1848 OnPairing(addr->Clone()); |
1743 OnPairedDone(std::move(addr)); | 1849 OnPairedDone(std::move(addr)); |
1744 } | 1850 } |
1745 } | 1851 } |
1746 | 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), | |
1863 mojo::Array<mojom::BluetoothSdpRecordPtr>::From(records_bluez)); | |
1864 } | |
1865 | |
1866 void ArcBluetoothBridge::OnGetServiceRecordsError( | |
1867 mojom::BluetoothAddressPtr remote_addr, | |
1868 mojom::BluetoothUUIDPtr target_uuid, | |
1869 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { | |
1870 mojom::BluetoothStatus status; | |
1871 | |
1872 switch (error_code) { | |
1873 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: | |
1874 status = mojom::BluetoothStatus::NOT_READY; | |
1875 break; | |
1876 case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: | |
1877 ERROR_DEVICE_DISCONNECTED: | |
1878 status = mojom::BluetoothStatus::RMT_DEV_DOWN; | |
1879 break; | |
1880 default: | |
1881 status = mojom::BluetoothStatus::FAIL; | |
1882 break; | |
1883 } | |
1884 | |
1885 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( | |
1886 status, std::move(remote_addr), std::move(target_uuid), | |
1887 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | |
1888 } | |
1889 | |
1747 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( | 1890 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( |
1748 uint32_t version_need) const { | 1891 uint32_t version_need) const { |
1749 uint32_t version = arc_bridge_service()->bluetooth()->version(); | 1892 uint32_t version = arc_bridge_service()->bluetooth()->version(); |
1750 if (version >= version_need) | 1893 if (version >= version_need) |
1751 return true; | 1894 return true; |
1752 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1895 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
1753 << ") need version " << version_need; | 1896 << ") need version " << version_need; |
1754 return false; | 1897 return false; |
1755 } | 1898 } |
1756 | 1899 |
1757 bool ArcBluetoothBridge::CalledOnValidThread() { | 1900 bool ArcBluetoothBridge::CalledOnValidThread() { |
1758 return thread_checker_.CalledOnValidThread(); | 1901 return thread_checker_.CalledOnValidThread(); |
1759 } | 1902 } |
1760 | 1903 |
1761 } // namespace arc | 1904 } // namespace arc |
OLD | NEW |