| 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 |