| 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 24 matching lines...) Expand all Loading... |
| 65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | | 66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 66 BluetoothGattCharacteristic::Permission:: | 67 BluetoothGattCharacteristic::Permission:: |
| 67 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; | 68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 68 constexpr int32_t kInvalidGattAttributeHandle = -1; | 69 constexpr int32_t kInvalidGattAttributeHandle = -1; |
| 69 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 | 70 // 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. | 71 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. |
| 71 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
| 72 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 | 73 // 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. | 74 // The maximum length of an attribute value shall be 512 octets. |
| 74 constexpr int kMaxGattAttributeLength = 512; | 75 constexpr int kMaxGattAttributeLength = 512; |
| 76 // Bluetooth SDP Service Class ID List Attribute identifier |
| 77 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; |
| 75 | 78 |
| 76 using GattStatusCallback = | 79 using GattStatusCallback = |
| 77 base::Callback<void(arc::mojom::BluetoothGattStatus)>; | 80 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
| 78 using GattReadCallback = | 81 using GattReadCallback = |
| 79 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; | 82 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
| 83 using CreateSdpRecordCallback = |
| 84 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; |
| 85 using RemoveSdpRecordCallback = |
| 86 base::Callback<void(arc::mojom::BluetoothStatus)>; |
| 80 | 87 |
| 81 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a | 88 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
| 82 // Convert the last 4 characters of |identifier| to an | 89 // Convert the last 4 characters of |identifier| to an |
| 83 // int, by interpreting them as hexadecimal digits. | 90 // int, by interpreting them as hexadecimal digits. |
| 84 int ConvertGattIdentifierToId(const std::string identifier) { | 91 int ConvertGattIdentifierToId(const std::string identifier) { |
| 85 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); | 92 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); |
| 86 } | 93 } |
| 87 | 94 |
| 88 // Create GattDBElement and fill in common data for | 95 // Create GattDBElement and fill in common data for |
| 89 // Gatt Service/Characteristic/Descriptor. | 96 // 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) | 173 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) |
| 167 success_callback.Run(); | 174 success_callback.Run(); |
| 168 else | 175 else |
| 169 error_callback.Run(); | 176 error_callback.Run(); |
| 170 } | 177 } |
| 171 | 178 |
| 172 bool IsGattOffsetValid(int offset) { | 179 bool IsGattOffsetValid(int offset) { |
| 173 return 0 <= offset && offset < kMaxGattAttributeLength; | 180 return 0 <= offset && offset < kMaxGattAttributeLength; |
| 174 } | 181 } |
| 175 | 182 |
| 183 void OnCreateServiceRecordDone( |
| 184 const CreateSdpRecordCallback& callback, |
| 185 uint32_t service_handle) { |
| 186 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 187 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 188 result->status = arc::mojom::BluetoothStatus::SUCCESS; |
| 189 result->service_handle = service_handle; |
| 190 |
| 191 callback.Run(std::move(result)); |
| 192 } |
| 193 |
| 194 void OnCreateServiceRecordError( |
| 195 const CreateSdpRecordCallback& callback, |
| 196 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 197 arc::mojom::BluetoothCreateSdpRecordResultPtr result = |
| 198 arc::mojom::BluetoothCreateSdpRecordResult::New(); |
| 199 if (error_code == |
| 200 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 201 result->status = arc::mojom::BluetoothStatus::NOT_READY; |
| 202 else |
| 203 result->status = arc::mojom::BluetoothStatus::FAIL; |
| 204 |
| 205 callback.Run(std::move(result)); |
| 206 } |
| 207 |
| 208 void OnRemoveServiceRecordDone( |
| 209 const RemoveSdpRecordCallback& callback) { |
| 210 callback.Run(arc::mojom::BluetoothStatus::SUCCESS); |
| 211 } |
| 212 |
| 213 void OnRemoveServiceRecordError( |
| 214 const RemoveSdpRecordCallback& callback, |
| 215 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 216 arc::mojom::BluetoothStatus status; |
| 217 if (error_code == |
| 218 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY) |
| 219 status = arc::mojom::BluetoothStatus::NOT_READY; |
| 220 else |
| 221 status = arc::mojom::BluetoothStatus::FAIL; |
| 222 |
| 223 callback.Run(status); |
| 224 } |
| 225 |
| 176 } // namespace | 226 } // namespace |
| 177 | 227 |
| 178 namespace arc { | 228 namespace arc { |
| 179 | 229 |
| 180 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 230 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
| 181 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 231 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
| 182 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 232 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
| 183 VLOG(1) << "registering bluetooth adapter"; | 233 VLOG(1) << "registering bluetooth adapter"; |
| 184 BluetoothAdapterFactory::GetAdapter(base::Bind( | 234 BluetoothAdapterFactory::GetAdapter(base::Bind( |
| 185 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 235 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 BluetoothDevice* device = | 851 BluetoothDevice* device = |
| 802 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 852 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 803 DCHECK(device); | 853 DCHECK(device); |
| 804 | 854 |
| 805 if (device->IsConnected()) { | 855 if (device->IsConnected()) { |
| 806 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( | 856 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( |
| 807 std::move(remote_addr), true); | 857 std::move(remote_addr), true); |
| 808 return; | 858 return; |
| 809 } | 859 } |
| 810 | 860 |
| 811 // Also pass disconnect callback in error case | 861 // Also pass disconnect callback in error case since it would be disconnected |
| 812 // since it would be disconnected anyway. | 862 // anyway. |
| 813 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); | 863 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 814 device->CreateGattConnection( | 864 device->CreateGattConnection( |
| 815 base::Bind(&ArcBluetoothBridge::OnGattConnected, | 865 base::Bind(&ArcBluetoothBridge::OnGattConnected, |
| 816 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), | 866 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), |
| 817 base::Bind(&ArcBluetoothBridge::OnGattConnectError, | 867 base::Bind(&ArcBluetoothBridge::OnGattConnectError, |
| 818 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); | 868 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); |
| 819 } | 869 } |
| 820 | 870 |
| 821 void ArcBluetoothBridge::DisconnectLEDevice( | 871 void ArcBluetoothBridge::DisconnectLEDevice( |
| 822 mojom::BluetoothAddressPtr remote_addr) { | 872 mojom::BluetoothAddressPtr remote_addr) { |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1300 OnGattOperationDone(callback); | 1350 OnGattOperationDone(callback); |
| 1301 } | 1351 } |
| 1302 | 1352 |
| 1303 void ArcBluetoothBridge::SendIndication( | 1353 void ArcBluetoothBridge::SendIndication( |
| 1304 int32_t attribute_handle, | 1354 int32_t attribute_handle, |
| 1305 mojom::BluetoothAddressPtr address, | 1355 mojom::BluetoothAddressPtr address, |
| 1306 bool confirm, | 1356 bool confirm, |
| 1307 mojo::Array<uint8_t> value, | 1357 mojo::Array<uint8_t> value, |
| 1308 const SendIndicationCallback& callback) {} | 1358 const SendIndicationCallback& callback) {} |
| 1309 | 1359 |
| 1360 void ArcBluetoothBridge::GetSdpRecords( |
| 1361 mojom::BluetoothAddressPtr remote_addr, |
| 1362 mojom::BluetoothUUIDPtr target_uuid) { |
| 1363 BluetoothDevice* device = |
| 1364 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 1365 |
| 1366 // Do an early return if there is no device with |remote_addr|. |
| 1367 if (!device) { |
| 1368 OnGetServiceRecordsError(std::move(remote_addr), std::move(target_uuid), |
| 1369 bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1370 ERROR_DEVICE_DISCONNECTED); |
| 1371 return; |
| 1372 } |
| 1373 |
| 1374 bluez::BluetoothDeviceBlueZ* device_bluez = |
| 1375 static_cast<bluez::BluetoothDeviceBlueZ*>(device); |
| 1376 |
| 1377 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); |
| 1378 mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone(); |
| 1379 |
| 1380 device_bluez->GetServiceRecords( |
| 1381 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone, |
| 1382 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr), |
| 1383 base::Passed(&target_uuid)), |
| 1384 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError, |
| 1385 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone), |
| 1386 base::Passed(&target_uuid_clone))); |
| 1387 } |
| 1388 |
| 1389 void ArcBluetoothBridge::CreateSdpRecord( |
| 1390 mojom::BluetoothSdpRecordPtr record, |
| 1391 const CreateSdpRecordCallback& callback) { |
| 1392 bluez::BluetoothServiceRecordBlueZ record_bluez( |
| 1393 mojo::ConvertTo<bluez::BluetoothServiceRecordBlueZ>(record)); |
| 1394 |
| 1395 std::vector<uint16_t> v = record_bluez.GetAttributeIds(); |
| 1396 |
| 1397 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included |
| 1398 // after type conversion, since it is mandatory for creating a service record. |
| 1399 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) == |
| 1400 v.end()) { |
| 1401 mojom::BluetoothCreateSdpRecordResultPtr result = |
| 1402 mojom::BluetoothCreateSdpRecordResult::New(); |
| 1403 result->status = mojom::BluetoothStatus::FAIL; |
| 1404 callback.Run(std::move(result)); |
| 1405 return; |
| 1406 } |
| 1407 |
| 1408 bluetooth_adapter_->CreateServiceRecord( |
| 1409 record_bluez, base::Bind(&OnCreateServiceRecordDone, callback), |
| 1410 base::Bind(&OnCreateServiceRecordError, callback)); |
| 1411 } |
| 1412 |
| 1413 void ArcBluetoothBridge::RemoveSdpRecord( |
| 1414 uint32_t service_handle, |
| 1415 const RemoveSdpRecordCallback& callback) { |
| 1416 bluetooth_adapter_->RemoveServiceRecord( |
| 1417 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
| 1418 base::Bind(&OnRemoveServiceRecordError, callback)); |
| 1419 } |
| 1420 |
| 1310 void ArcBluetoothBridge::OnDiscoveryError() { | 1421 void ArcBluetoothBridge::OnDiscoveryError() { |
| 1311 LOG(WARNING) << "failed to change discovery state"; | 1422 LOG(WARNING) << "failed to change discovery state"; |
| 1312 } | 1423 } |
| 1313 | 1424 |
| 1314 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1425 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
| 1315 if (!HasBluetoothInstance()) | 1426 if (!HasBluetoothInstance()) |
| 1316 return; | 1427 return; |
| 1317 | 1428 |
| 1318 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( | 1429 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( |
| 1319 mojom::BluetoothStatus::SUCCESS, std::move(addr), | 1430 mojom::BluetoothStatus::SUCCESS, std::move(addr), |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 | 1727 |
| 1617 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { | 1728 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { |
| 1618 int rssi = device->GetInquiryRSSI(); | 1729 int rssi = device->GetInquiryRSSI(); |
| 1619 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = | 1730 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = |
| 1620 GetAdvertisingData(device); | 1731 GetAdvertisingData(device); |
| 1621 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( | 1732 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( |
| 1622 addr->Clone(), rssi, std::move(adv_data)); | 1733 addr->Clone(), rssi, std::move(adv_data)); |
| 1623 } | 1734 } |
| 1624 | 1735 |
| 1625 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING | 1736 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING |
| 1626 // to | 1737 // to make sure the bond state machine on Android is ready to take the |
| 1627 // make sure the bond state machine on Android is ready to take the | |
| 1628 // pair-done event. Otherwise the pair-done event will be dropped as an | 1738 // pair-done event. Otherwise the pair-done event will be dropped as an |
| 1629 // invalid change of paired status. | 1739 // invalid change of paired status. |
| 1630 OnPairing(addr->Clone()); | 1740 OnPairing(addr->Clone()); |
| 1631 OnPairedDone(std::move(addr)); | 1741 OnPairedDone(std::move(addr)); |
| 1632 } | 1742 } |
| 1633 } | 1743 } |
| 1634 | 1744 |
| 1745 void ArcBluetoothBridge::OnGetServiceRecordsDone( |
| 1746 mojom::BluetoothAddressPtr remote_addr, |
| 1747 mojom::BluetoothUUIDPtr target_uuid, |
| 1748 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) { |
| 1749 if (!HasBluetoothInstance()) |
| 1750 return; |
| 1751 |
| 1752 mojo::Array<mojom::BluetoothSdpRecordPtr> records; |
| 1753 for (auto& record : records_bluez) |
| 1754 records.push_back(mojo::ConvertTo<mojom::BluetoothSdpRecordPtr>(record)); |
| 1755 |
| 1756 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1757 mojom::BluetoothStatus::SUCCESS, std::move(remote_addr), |
| 1758 std::move(target_uuid), std::move(records)); |
| 1759 } |
| 1760 |
| 1761 void ArcBluetoothBridge::OnGetServiceRecordsError( |
| 1762 mojom::BluetoothAddressPtr remote_addr, |
| 1763 mojom::BluetoothUUIDPtr target_uuid, |
| 1764 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) { |
| 1765 mojom::BluetoothStatus status; |
| 1766 |
| 1767 switch (error_code) { |
| 1768 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY: |
| 1769 status = mojom::BluetoothStatus::NOT_READY; |
| 1770 break; |
| 1771 case bluez::BluetoothServiceRecordBlueZ::ErrorCode:: |
| 1772 ERROR_DEVICE_DISCONNECTED: |
| 1773 status = mojom::BluetoothStatus::RMT_DEV_DOWN; |
| 1774 break; |
| 1775 default: |
| 1776 status = mojom::BluetoothStatus::FAIL; |
| 1777 break; |
| 1778 } |
| 1779 |
| 1780 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords( |
| 1781 status, std::move(remote_addr), std::move(target_uuid), |
| 1782 mojo::Array<mojom::BluetoothSdpRecordPtr>()); |
| 1783 } |
| 1784 |
| 1635 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( | 1785 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( |
| 1636 uint32_t version_need) const { | 1786 uint32_t version_need) const { |
| 1637 uint32_t version = arc_bridge_service()->bluetooth()->version(); | 1787 uint32_t version = arc_bridge_service()->bluetooth()->version(); |
| 1638 if (version >= version_need) | 1788 if (version >= version_need) |
| 1639 return true; | 1789 return true; |
| 1640 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1790 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
| 1641 << ") need version " << version_need; | 1791 << ") need version " << version_need; |
| 1642 return false; | 1792 return false; |
| 1643 } | 1793 } |
| 1644 | 1794 |
| 1645 bool ArcBluetoothBridge::CalledOnValidThread() { | 1795 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 1646 return thread_checker_.CalledOnValidThread(); | 1796 return thread_checker_.CalledOnValidThread(); |
| 1647 } | 1797 } |
| 1648 | 1798 |
| 1649 } // namespace arc | 1799 } // namespace arc |
| OLD | NEW |