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 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 } | 1624 } |
1625 | 1625 |
1626 void ArcBluetoothBridge::RemoveSdpRecord( | 1626 void ArcBluetoothBridge::RemoveSdpRecord( |
1627 uint32_t service_handle, | 1627 uint32_t service_handle, |
1628 const RemoveSdpRecordCallback& callback) { | 1628 const RemoveSdpRecordCallback& callback) { |
1629 bluetooth_adapter_->RemoveServiceRecord( | 1629 bluetooth_adapter_->RemoveServiceRecord( |
1630 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), | 1630 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), |
1631 base::Bind(&OnRemoveServiceRecordError, callback)); | 1631 base::Bind(&OnRemoveServiceRecordError, callback)); |
1632 } | 1632 } |
1633 | 1633 |
| 1634 bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) { |
| 1635 for (int i = 0; i < kMaxAdvertisements; i++) { |
| 1636 if (advertisements_.find(i) == advertisements_.end()) { |
| 1637 *adv_handle = i; |
| 1638 return true; |
| 1639 } |
| 1640 } |
| 1641 return false; |
| 1642 } |
| 1643 |
| 1644 void ArcBluetoothBridge::ReserveAdvertisementHandle( |
| 1645 const ReserveAdvertisementHandleCallback& callback) { |
| 1646 DCHECK(CalledOnValidThread()); |
| 1647 // Find an empty advertisement slot. |
| 1648 int32_t adv_handle; |
| 1649 if (!GetAdvertisementHandle(&adv_handle)) { |
| 1650 LOG(WARNING) << "Out of space for advertisement data"; |
| 1651 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE, |
| 1652 kInvalidAdvertisementHandle); |
| 1653 return; |
| 1654 } |
| 1655 |
| 1656 // We have a handle. Put an entry in the map to reserve it. |
| 1657 advertisements_[adv_handle] = nullptr; |
| 1658 |
| 1659 // The advertisement will be registered when we get the call |
| 1660 // to SetAdvertisingData. For now, just return the adv_handle. |
| 1661 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle); |
| 1662 } |
| 1663 |
| 1664 void ArcBluetoothBridge::BroadcastAdvertisement( |
| 1665 int32_t adv_handle, |
| 1666 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement, |
| 1667 const BroadcastAdvertisementCallback& callback) { |
| 1668 DCHECK(CalledOnValidThread()); |
| 1669 if (advertisements_.find(adv_handle) == advertisements_.end()) { |
| 1670 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1671 return; |
| 1672 } |
| 1673 |
| 1674 if (!advertisements_[adv_handle]) { |
| 1675 OnReadyToRegisterAdvertisement(callback, adv_handle, |
| 1676 std::move(advertisement)); |
| 1677 return; |
| 1678 } |
| 1679 |
| 1680 advertisements_[adv_handle]->Unregister( |
| 1681 base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement, |
| 1682 weak_factory_.GetWeakPtr(), callback, adv_handle, |
| 1683 base::Passed(std::move(advertisement))), |
| 1684 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError, |
| 1685 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1686 } |
| 1687 |
| 1688 void ArcBluetoothBridge::ReleaseAdvertisementHandle( |
| 1689 int32_t adv_handle, |
| 1690 const ReleaseAdvertisementHandleCallback& callback) { |
| 1691 DCHECK(CalledOnValidThread()); |
| 1692 if (advertisements_.find(adv_handle) == advertisements_.end()) { |
| 1693 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1694 return; |
| 1695 } |
| 1696 |
| 1697 if (!advertisements_[adv_handle]) { |
| 1698 advertisements_.erase(adv_handle); |
| 1699 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1700 return; |
| 1701 } |
| 1702 |
| 1703 advertisements_[adv_handle]->Unregister( |
| 1704 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone, |
| 1705 weak_factory_.GetWeakPtr(), callback, adv_handle), |
| 1706 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError, |
| 1707 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1708 } |
| 1709 |
| 1710 void ArcBluetoothBridge::OnReadyToRegisterAdvertisement( |
| 1711 const BroadcastAdvertisementCallback& callback, |
| 1712 int32_t adv_handle, |
| 1713 std::unique_ptr<device::BluetoothAdvertisement::Data> data) { |
| 1714 DCHECK(CalledOnValidThread()); |
| 1715 bluetooth_adapter_->RegisterAdvertisement( |
| 1716 std::move(data), |
| 1717 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone, |
| 1718 weak_factory_.GetWeakPtr(), callback, adv_handle), |
| 1719 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError, |
| 1720 weak_factory_.GetWeakPtr(), callback, adv_handle)); |
| 1721 } |
| 1722 |
| 1723 void ArcBluetoothBridge::OnRegisterAdvertisementDone( |
| 1724 const BroadcastAdvertisementCallback& callback, |
| 1725 int32_t adv_handle, |
| 1726 scoped_refptr<BluetoothAdvertisement> advertisement) { |
| 1727 DCHECK(CalledOnValidThread()); |
| 1728 advertisements_[adv_handle] = std::move(advertisement); |
| 1729 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1730 } |
| 1731 |
| 1732 void ArcBluetoothBridge::OnRegisterAdvertisementError( |
| 1733 const BroadcastAdvertisementCallback& callback, |
| 1734 int32_t adv_handle, |
| 1735 BluetoothAdvertisement::ErrorCode error_code) { |
| 1736 DCHECK(CalledOnValidThread()); |
| 1737 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle |
| 1738 << ", error code = " << error_code; |
| 1739 advertisements_[adv_handle] = nullptr; |
| 1740 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1741 } |
| 1742 |
| 1743 void ArcBluetoothBridge::OnUnregisterAdvertisementDone( |
| 1744 const ReleaseAdvertisementHandleCallback& callback, |
| 1745 int32_t adv_handle) { |
| 1746 DCHECK(CalledOnValidThread()); |
| 1747 advertisements_.erase(adv_handle); |
| 1748 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1749 } |
| 1750 |
| 1751 void ArcBluetoothBridge::OnUnregisterAdvertisementError( |
| 1752 const ReleaseAdvertisementHandleCallback& callback, |
| 1753 int32_t adv_handle, |
| 1754 BluetoothAdvertisement::ErrorCode error_code) { |
| 1755 DCHECK(CalledOnValidThread()); |
| 1756 LOG(WARNING) << "Failed to unregister advertisement for handle " << adv_handle |
| 1757 << ", error code = " << error_code; |
| 1758 advertisements_.erase(adv_handle); |
| 1759 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 1760 } |
| 1761 |
1634 void ArcBluetoothBridge::OnDiscoveryError() { | 1762 void ArcBluetoothBridge::OnDiscoveryError() { |
1635 LOG(WARNING) << "failed to change discovery state"; | 1763 LOG(WARNING) << "failed to change discovery state"; |
1636 } | 1764 } |
1637 | 1765 |
1638 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { | 1766 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { |
1639 auto* bluetooth_instance = | 1767 auto* bluetooth_instance = |
1640 arc_bridge_service()->bluetooth()->GetInstanceForMethod( | 1768 arc_bridge_service()->bluetooth()->GetInstanceForMethod( |
1641 "OnBondStateChanged"); | 1769 "OnBondStateChanged"); |
1642 if (!bluetooth_instance) | 1770 if (!bluetooth_instance) |
1643 return; | 1771 return; |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1838 properties.push_back(std::move(btp)); | 1966 properties.push_back(std::move(btp)); |
1839 } | 1967 } |
1840 if (type == mojom::BluetoothPropertyType::ALL || | 1968 if (type == mojom::BluetoothPropertyType::ALL || |
1841 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { | 1969 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { |
1842 // TODO(crbug.com/637171) Investigate all the le_features. | 1970 // TODO(crbug.com/637171) Investigate all the le_features. |
1843 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); | 1971 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); |
1844 mojom::BluetoothLocalLEFeaturesPtr le_features = | 1972 mojom::BluetoothLocalLEFeaturesPtr le_features = |
1845 mojom::BluetoothLocalLEFeatures::New(); | 1973 mojom::BluetoothLocalLEFeatures::New(); |
1846 le_features->version_supported = kAndroidMBluetoothVersionNumber; | 1974 le_features->version_supported = kAndroidMBluetoothVersionNumber; |
1847 le_features->local_privacy_enabled = 0; | 1975 le_features->local_privacy_enabled = 0; |
1848 le_features->max_adv_instance = kMaxAdvertisement; | 1976 le_features->max_adv_instance = kMaxAdvertisements; |
1849 le_features->rpa_offload_supported = 0; | 1977 le_features->rpa_offload_supported = 0; |
1850 le_features->max_irk_list_size = 0; | 1978 le_features->max_irk_list_size = 0; |
1851 le_features->max_adv_filter_supported = 0; | 1979 le_features->max_adv_filter_supported = 0; |
1852 le_features->activity_energy_info_supported = 0; | 1980 le_features->activity_energy_info_supported = 0; |
1853 le_features->scan_result_storage_size = 0; | 1981 le_features->scan_result_storage_size = 0; |
1854 le_features->total_trackable_advertisers = 0; | 1982 le_features->total_trackable_advertisers = 0; |
1855 le_features->extended_scan_support = false; | 1983 le_features->extended_scan_support = false; |
1856 le_features->debug_logging_supported = false; | 1984 le_features->debug_logging_supported = false; |
1857 btp->set_local_le_features(std::move(le_features)); | 1985 btp->set_local_le_features(std::move(le_features)); |
1858 properties.push_back(std::move(btp)); | 1986 properties.push_back(std::move(btp)); |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2030 sdp_bluetooth_instance->OnGetSdpRecords( | 2158 sdp_bluetooth_instance->OnGetSdpRecords( |
2031 status, std::move(remote_addr), target_uuid, | 2159 status, std::move(remote_addr), target_uuid, |
2032 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); | 2160 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0)); |
2033 } | 2161 } |
2034 | 2162 |
2035 bool ArcBluetoothBridge::CalledOnValidThread() { | 2163 bool ArcBluetoothBridge::CalledOnValidThread() { |
2036 return thread_checker_.CalledOnValidThread(); | 2164 return thread_checker_.CalledOnValidThread(); |
2037 } | 2165 } |
2038 | 2166 |
2039 } // namespace arc | 2167 } // namespace arc |
OLD | NEW |