| 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 BluetoothGattCharacteristic::Permission::PERMISSION_READ | | 62 BluetoothGattCharacteristic::Permission::PERMISSION_READ | |
| 63 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | | 63 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | |
| 64 BluetoothGattCharacteristic::Permission:: | 64 BluetoothGattCharacteristic::Permission:: |
| 65 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; | 65 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; |
| 66 constexpr uint32_t kGattWritePermission = | 66 constexpr uint32_t kGattWritePermission = |
| 67 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | | 67 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | |
| 68 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | | 68 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 69 BluetoothGattCharacteristic::Permission:: | 69 BluetoothGattCharacteristic::Permission:: |
| 70 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; | 70 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 71 constexpr int32_t kInvalidGattAttributeHandle = -1; | 71 constexpr int32_t kInvalidGattAttributeHandle = -1; |
| 72 constexpr int32_t kInvalidAdvertisementHandle = -1; |
| 72 // 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 |
| 73 // 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. |
| 74 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; | 75 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
| 75 // 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 |
| 76 // The maximum length of an attribute value shall be 512 octets. | 77 // The maximum length of an attribute value shall be 512 octets. |
| 77 constexpr int kMaxGattAttributeLength = 512; | 78 constexpr int kMaxGattAttributeLength = 512; |
| 78 // Copied from Android at system/bt/stack/btm/btm_ble_int.h | 79 // Copied from Android at system/bt/stack/btm/btm_ble_int.h |
| 79 // https://goo.gl/k7PM6u | 80 // https://goo.gl/k7PM6u |
| 80 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; | 81 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; |
| 81 constexpr uint16_t kMaxAdvertisement = 5; | |
| 82 // Bluetooth SDP Service Class ID List Attribute identifier | 82 // Bluetooth SDP Service Class ID List Attribute identifier |
| 83 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; | 83 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001; |
| 84 // Timeout for Bluetooth Discovery (scan) | 84 // Timeout for Bluetooth Discovery (scan) |
| 85 // 120 seconds is used here as the upper bound of the time need to do device | 85 // 120 seconds is used here as the upper bound of the time need to do device |
| 86 // discovery once, 20 seconds for inquiry scan and 100 seconds for page scan | 86 // discovery once, 20 seconds for inquiry scan and 100 seconds for page scan |
| 87 // for 100 new devices. | 87 // for 100 new devices. |
| 88 constexpr base::TimeDelta kDiscoveryTimeout = base::TimeDelta::FromSeconds(120); | 88 constexpr base::TimeDelta kDiscoveryTimeout = base::TimeDelta::FromSeconds(120); |
| 89 // From https://www.bluetooth.com/specifications/assigned-numbers/baseband | 89 // From https://www.bluetooth.com/specifications/assigned-numbers/baseband |
| 90 // The Class of Device for generic computer. | 90 // The Class of Device for generic computer. |
| 91 constexpr uint32_t kBluetoothComputerClass = 0x100; | 91 constexpr uint32_t kBluetoothComputerClass = 0x100; |
| (...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1620 } | 1620 } |
| 1621 | 1621 |
| 1622 void ArcBluetoothBridge::RemoveSdpRecord( | 1622 void ArcBluetoothBridge::RemoveSdpRecord( |
| 1623 uint32_t service_handle, | 1623 uint32_t service_handle, |
| 1624 const RemoveSdpRecordCallback& callback) { | 1624 const RemoveSdpRecordCallback& callback) { |
| 1625 bluetooth_adapter_->RemoveServiceRecord( | 1625 bluetooth_adapter_->RemoveServiceRecord( |
| 1626 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), | 1626 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
| 1627 base::Bind(&OnRemoveServiceRecordError, callback)); | 1627 base::Bind(&OnRemoveServiceRecordError, callback)); |
| 1628 } | 1628 } |
| 1629 | 1629 |
| 1630 bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) { |
| 1631 for (int i = 0; i < kMaxAdvertisements; i++) { |
| 1632 if (advertisements_.find(i) == advertisements_.end()) { |
| 1633 *adv_handle = i; |
| 1634 return true; |
| 1635 } |
| 1636 } |
| 1637 return false; |
| 1638 } |
| 1639 |
| 1640 void ArcBluetoothBridge::ReserveAdvertisementHandle( |
| 1641 const ReserveAdvertisementHandleCallback& callback) { |
| 1642 DCHECK(CalledOnValidThread()); |
| 1643 // Find an empty advertisement slot. |
| 1644 int32_t adv_handle; |
| 1645 if (!GetAdvertisementHandle(&adv_handle)) { |
| 1646 LOG(WARNING) << "Out of space for advertisement data"; |
| 1647 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE, |
| 1648 kInvalidAdvertisementHandle); |
| 1649 return; |
| 1650 } |
| 1651 |
| 1652 // We have a handle. Put an entry in the map to reserve it. |
| 1653 advertisements_[adv_handle] = nullptr; |
| 1654 |
| 1655 // The advertisement will be registered when we get the call |
| 1656 // to SetAdvertisingData. For now, just return the adv_handle. |
| 1657 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle); |
| 1658 } |
| 1659 |
| 1660 void ArcBluetoothBridge::BroadcastAdvertisement( |
| 1661 int32_t adv_handle, |
| 1662 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, |
| 1663 const BroadcastAdvertisementCallback& callback) { |
| 1664 DCHECK(CalledOnValidThread()); |
| 1665 if (advertisements_.find(adv_handle) == advertisements_.end()) { |
| 1666 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1667 return; |
| 1668 } |
| 1669 |
| 1670 if (!advertisements_[adv_handle]) { |
| 1671 OnReadyToRegisterAdvertisement(callback, adv_handle, |
| 1672 std::move(advertisement)); |
| 1673 return; |
| 1674 } |
| 1675 |
| 1676 advertisements_[adv_handle]->Unregister( |
| 1677 base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement, |
| 1678 weak_factory_.GetWeakPtr(), callback, adv_handle, |
| 1679 base::Passed(std::move(advertisement))), |
| 1680 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError, |
| 1681 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1682 } |
| 1683 |
| 1684 void ArcBluetoothBridge::ReleaseAdvertisementHandle( |
| 1685 int32_t adv_handle, |
| 1686 const ReleaseAdvertisementHandleCallback& callback) { |
| 1687 DCHECK(CalledOnValidThread()); |
| 1688 if (advertisements_.find(adv_handle) == advertisements_.end()) { |
| 1689 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1690 return; |
| 1691 } |
| 1692 |
| 1693 if (!advertisements_[adv_handle]) { |
| 1694 advertisements_.erase(adv_handle); |
| 1695 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1696 return; |
| 1697 } |
| 1698 |
| 1699 advertisements_[adv_handle]->Unregister( |
| 1700 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone, |
| 1701 weak_factory_.GetWeakPtr(), callback, adv_handle), |
| 1702 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError, |
| 1703 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1704 } |
| 1705 |
| 1706 void ArcBluetoothBridge::OnReadyToRegisterAdvertisement( |
| 1707 const BroadcastAdvertisementCallback& callback, |
| 1708 int32_t adv_handle, |
| 1709 std::unique_ptr<device::BluetoothAdvertisement::Data> data) { |
| 1710 DCHECK(CalledOnValidThread()); |
| 1711 bluetooth_adapter_->RegisterAdvertisement( |
| 1712 std::move(data), |
| 1713 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone, |
| 1714 weak_factory_.GetWeakPtr(), callback, adv_handle), |
| 1715 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError, |
| 1716 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1717 } |
| 1718 |
| 1719 void ArcBluetoothBridge::OnRegisterAdvertisementDone( |
| 1720 const BroadcastAdvertisementCallback& callback, |
| 1721 int32_t adv_handle, |
| 1722 scoped_refptr<BluetoothAdvertisement> advertisement) { |
| 1723 DCHECK(CalledOnValidThread()); |
| 1724 advertisements_[adv_handle] = std::move(advertisement); |
| 1725 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1726 } |
| 1727 |
| 1728 void ArcBluetoothBridge::OnRegisterAdvertisementError( |
| 1729 const BroadcastAdvertisementCallback& callback, |
| 1730 int32_t adv_handle, |
| 1731 BluetoothAdvertisement::ErrorCode error_code) { |
| 1732 DCHECK(CalledOnValidThread()); |
| 1733 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle |
| 1734 << ", error code = " << error_code; |
| 1735 advertisements_[adv_handle] = nullptr; |
| 1736 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1737 } |
| 1738 |
| 1739 void ArcBluetoothBridge::OnUnregisterAdvertisementDone( |
| 1740 const ReleaseAdvertisementHandleCallback& callback, |
| 1741 int32_t adv_handle) { |
| 1742 DCHECK(CalledOnValidThread()); |
| 1743 advertisements_.erase(adv_handle); |
| 1744 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1745 } |
| 1746 |
| 1747 void ArcBluetoothBridge::OnUnregisterAdvertisementError( |
| 1748 const ReleaseAdvertisementHandleCallback& callback, |
| 1749 int32_t adv_handle, |
| 1750 BluetoothAdvertisement::ErrorCode error_code) { |
| 1751 DCHECK(CalledOnValidThread()); |
| 1752 LOG(WARNING) << "Failed to unregister advertisement for handle " << adv_handle |
| 1753 << ", error code = " << error_code; |
| 1754 advertisements_.erase(adv_handle); |
| 1755 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1756 } |
| 1757 |
| 1630 void ArcBluetoothBridge::OnDiscoveryError() { | 1758 void ArcBluetoothBridge::OnDiscoveryError() { |
| 1631 LOG(WARNING) << "failed to change discovery state"; | 1759 LOG(WARNING) << "failed to change discovery state"; |
| 1632 } | 1760 } |
| 1633 | 1761 |
| 1634 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1762 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
| 1635 auto* bluetooth_instance = | 1763 auto* bluetooth_instance = |
| 1636 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 1764 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
| 1637 "OnBondStateChanged"); | 1765 "OnBondStateChanged"); |
| 1638 if (!bluetooth_instance) | 1766 if (!bluetooth_instance) |
| 1639 return; | 1767 return; |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1834 properties.push_back(std::move(btp)); | 1962 properties.push_back(std::move(btp)); |
| 1835 } | 1963 } |
| 1836 if (type == mojom::BluetoothPropertyType::ALL || | 1964 if (type == mojom::BluetoothPropertyType::ALL || |
| 1837 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { | 1965 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { |
| 1838 // TODO(crbug.com/637171) Investigate all the le_features. | 1966 // TODO(crbug.com/637171) Investigate all the le_features. |
| 1839 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1967 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
| 1840 mojom::BluetoothLocalLEFeaturesPtr le_features = | 1968 mojom::BluetoothLocalLEFeaturesPtr le_features = |
| 1841 mojom::BluetoothLocalLEFeatures::New(); | 1969 mojom::BluetoothLocalLEFeatures::New(); |
| 1842 le_features->version_supported = kAndroidMBluetoothVersionNumber; | 1970 le_features->version_supported = kAndroidMBluetoothVersionNumber; |
| 1843 le_features->local_privacy_enabled = 0; | 1971 le_features->local_privacy_enabled = 0; |
| 1844 le_features->max_adv_instance = kMaxAdvertisement; | 1972 le_features->max_adv_instance = kMaxAdvertisements; |
| 1845 le_features->rpa_offload_supported = 0; | 1973 le_features->rpa_offload_supported = 0; |
| 1846 le_features->max_irk_list_size = 0; | 1974 le_features->max_irk_list_size = 0; |
| 1847 le_features->max_adv_filter_supported = 0; | 1975 le_features->max_adv_filter_supported = 0; |
| 1848 le_features->activity_energy_info_supported = 0; | 1976 le_features->activity_energy_info_supported = 0; |
| 1849 le_features->scan_result_storage_size = 0; | 1977 le_features->scan_result_storage_size = 0; |
| 1850 le_features->total_trackable_advertisers = 0; | 1978 le_features->total_trackable_advertisers = 0; |
| 1851 le_features->extended_scan_support = false; | 1979 le_features->extended_scan_support = false; |
| 1852 le_features->debug_logging_supported = false; | 1980 le_features->debug_logging_supported = false; |
| 1853 btp->set_local_le_features(std::move(le_features)); | 1981 btp->set_local_le_features(std::move(le_features)); |
| 1854 properties.push_back(std::move(btp)); | 1982 properties.push_back(std::move(btp)); |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2026 sdp_bluetooth_instance->OnGetSdpRecords( | 2154 sdp_bluetooth_instance->OnGetSdpRecords( |
| 2027 status, std::move(remote_addr), target_uuid, | 2155 status, std::move(remote_addr), target_uuid, |
| 2028 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2156 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
| 2029 } | 2157 } |
| 2030 | 2158 |
| 2031 bool ArcBluetoothBridge::CalledOnValidThread() { | 2159 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 2032 return thread_checker_.CalledOnValidThread(); | 2160 return thread_checker_.CalledOnValidThread(); |
| 2033 } | 2161 } |
| 2034 | 2162 |
| 2035 } // namespace arc | 2163 } // namespace arc |
| OLD | NEW |