Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1287)

Side by Side Diff: components/arc/bluetooth/arc_bluetooth_bridge.cc

Issue 2256003002: components/arc: implement multi advertising (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@plumb-incoming-connections
Patch Set: now using StructTraits/EnumTraits/UnionTraits/&c. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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 84
85 using GattStatusCallback = 85 using GattStatusCallback =
86 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 86 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
87 using GattReadCallback = 87 using GattReadCallback =
88 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 88 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
89 using CreateSdpRecordCallback = 89 using CreateSdpRecordCallback =
90 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>; 90 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>;
91 using RemoveSdpRecordCallback = 91 using RemoveSdpRecordCallback =
(...skipping 1479 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 } 1571 }
1572 1572
1573 void ArcBluetoothBridge::RemoveSdpRecord( 1573 void ArcBluetoothBridge::RemoveSdpRecord(
1574 uint32_t service_handle, 1574 uint32_t service_handle,
1575 const RemoveSdpRecordCallback& callback) { 1575 const RemoveSdpRecordCallback& callback) {
1576 bluetooth_adapter_->RemoveServiceRecord( 1576 bluetooth_adapter_->RemoveServiceRecord(
1577 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback), 1577 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback),
1578 base::Bind(&OnRemoveServiceRecordError, callback)); 1578 base::Bind(&OnRemoveServiceRecordError, callback));
1579 } 1579 }
1580 1580
1581 bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) {
1582 for (int i = 0; i < kMaxAdvertisements; i++) {
1583 if (advertisements_.find(i) == advertisements_.end()) {
1584 *adv_handle = i;
1585 return true;
1586 }
1587 }
1588 return false;
1589 }
1590
1591 void ArcBluetoothBridge::ReserveAdvertisementHandle(
1592 const ReserveAdvertisementHandleCallback& callback) {
1593 DCHECK(CalledOnValidThread());
1594 // Find an empty advertisement slot.
1595 int32_t adv_handle;
1596 if (!GetAdvertisementHandle(&adv_handle)) {
1597 LOG(WARNING) << "Out of space for advertisement data";
1598 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1599 kInvalidAdvertisementHandle);
1600 return;
1601 }
1602
1603 // We have a handle. Put an entry in the map to reserve it.
1604 advertisements_[adv_handle] = nullptr;
1605
1606 // The advertisement will be registered when we get the call
1607 // to SetAdvertisingData. For now, just return the adv_handle.
1608 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle);
1609 }
1610
1611 void ArcBluetoothBridge::BroadcastAdvertisement(
1612 int32_t adv_handle,
1613 std::unique_ptr<device::BluetoothAdvertisement::Data> advertisement,
1614 const BroadcastAdvertisementCallback& callback) {
1615 DCHECK(CalledOnValidThread());
1616 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1617 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1618 return;
1619 }
1620
1621 if (!advertisements_[adv_handle]) {
1622 OnReadyToRegisterAdvertisement(callback, adv_handle,
1623 std::move(advertisement));
1624 return;
1625 }
1626
1627 advertisements_[adv_handle]->Unregister(
1628 base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement,
1629 weak_factory_.GetWeakPtr(), callback, adv_handle,
1630 base::Passed(std::move(advertisement))),
1631 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1632 weak_factory_.GetWeakPtr(), callback, adv_handle));
1633 }
1634
1635 void ArcBluetoothBridge::ReleaseAdvertisementHandle(
1636 int32_t adv_handle,
1637 const ReleaseAdvertisementHandleCallback& callback) {
1638 DCHECK(CalledOnValidThread());
1639 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1640 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1641 return;
1642 }
1643
1644 if (!advertisements_[adv_handle]) {
1645 advertisements_.erase(adv_handle);
1646 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1647 return;
1648 }
1649
1650 advertisements_[adv_handle]->Unregister(
1651 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone,
1652 weak_factory_.GetWeakPtr(), callback, adv_handle),
1653 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError,
1654 weak_factory_.GetWeakPtr(), callback, adv_handle));
1655 }
1656
1657 void ArcBluetoothBridge::OnReadyToRegisterAdvertisement(
1658 const BroadcastAdvertisementCallback& callback,
1659 int32_t adv_handle,
1660 std::unique_ptr<device::BluetoothAdvertisement::Data> data) {
1661 DCHECK(CalledOnValidThread());
1662 bluetooth_adapter_->RegisterAdvertisement(
1663 std::move(data),
1664 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone,
1665 weak_factory_.GetWeakPtr(), callback, adv_handle),
1666 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1667 weak_factory_.GetWeakPtr(), callback, adv_handle));
1668 }
1669
1670 void ArcBluetoothBridge::OnRegisterAdvertisementDone(
1671 const BroadcastAdvertisementCallback& callback,
1672 int32_t adv_handle,
1673 scoped_refptr<BluetoothAdvertisement> advertisement) {
1674 DCHECK(CalledOnValidThread());
1675 advertisements_[adv_handle] = std::move(advertisement);
1676 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1677 }
1678
1679 void ArcBluetoothBridge::OnRegisterAdvertisementError(
1680 const BroadcastAdvertisementCallback& callback,
1681 int32_t adv_handle,
1682 BluetoothAdvertisement::ErrorCode error_code) {
1683 DCHECK(CalledOnValidThread());
1684 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle
1685 << ", error code = " << error_code;
1686 advertisements_[adv_handle] = nullptr;
1687 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1688 }
1689
1690 void ArcBluetoothBridge::OnUnregisterAdvertisementDone(
1691 const ReleaseAdvertisementHandleCallback& callback,
1692 int32_t adv_handle) {
1693 DCHECK(CalledOnValidThread());
1694 advertisements_.erase(adv_handle);
1695 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1696 }
1697
1698 void ArcBluetoothBridge::OnUnregisterAdvertisementError(
1699 const ReleaseAdvertisementHandleCallback& callback,
1700 int32_t adv_handle,
1701 BluetoothAdvertisement::ErrorCode error_code) {
1702 DCHECK(CalledOnValidThread());
1703 LOG(WARNING) << "Failed to unregister advertisement for handle " << adv_handle
1704 << ", error code = " << error_code;
1705 advertisements_.erase(adv_handle);
1706 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1707 }
1708
1581 void ArcBluetoothBridge::OnDiscoveryError() { 1709 void ArcBluetoothBridge::OnDiscoveryError() {
1582 LOG(WARNING) << "failed to change discovery state"; 1710 LOG(WARNING) << "failed to change discovery state";
1583 } 1711 }
1584 1712
1585 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1713 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1586 if (!HasBluetoothInstance()) 1714 if (!HasBluetoothInstance())
1587 return; 1715 return;
1588 1716
1589 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1717 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1590 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1718 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
1768 properties.push_back(std::move(btp)); 1896 properties.push_back(std::move(btp));
1769 } 1897 }
1770 if (type == mojom::BluetoothPropertyType::ALL || 1898 if (type == mojom::BluetoothPropertyType::ALL ||
1771 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { 1899 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) {
1772 // TODO(crbug.com/637171) Investigate all the le_features. 1900 // TODO(crbug.com/637171) Investigate all the le_features.
1773 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1901 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
1774 mojom::BluetoothLocalLEFeaturesPtr le_features = 1902 mojom::BluetoothLocalLEFeaturesPtr le_features =
1775 mojom::BluetoothLocalLEFeatures::New(); 1903 mojom::BluetoothLocalLEFeatures::New();
1776 le_features->version_supported = kAndroidMBluetoothVersionNumber; 1904 le_features->version_supported = kAndroidMBluetoothVersionNumber;
1777 le_features->local_privacy_enabled = 0; 1905 le_features->local_privacy_enabled = 0;
1778 le_features->max_adv_instance = kMaxAdvertisement; 1906 le_features->max_adv_instance = kMaxAdvertisements;
1779 le_features->rpa_offload_supported = 0; 1907 le_features->rpa_offload_supported = 0;
1780 le_features->max_irk_list_size = 0; 1908 le_features->max_irk_list_size = 0;
1781 le_features->max_adv_filter_supported = 0; 1909 le_features->max_adv_filter_supported = 0;
1782 le_features->activity_energy_info_supported = 0; 1910 le_features->activity_energy_info_supported = 0;
1783 le_features->scan_result_storage_size = 0; 1911 le_features->scan_result_storage_size = 0;
1784 le_features->total_trackable_advertisers = 0; 1912 le_features->total_trackable_advertisers = 0;
1785 le_features->extended_scan_support = false; 1913 le_features->extended_scan_support = false;
1786 le_features->debug_logging_supported = false; 1914 le_features->debug_logging_supported = false;
1787 btp->set_local_le_features(std::move(le_features)); 1915 btp->set_local_le_features(std::move(le_features));
1788 properties.push_back(std::move(btp)); 1916 properties.push_back(std::move(btp));
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 LOG(WARNING) << "Bluetooth instance is too old (version " << version 2101 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1974 << ") need version " << version_need; 2102 << ") need version " << version_need;
1975 return false; 2103 return false;
1976 } 2104 }
1977 2105
1978 bool ArcBluetoothBridge::CalledOnValidThread() { 2106 bool ArcBluetoothBridge::CalledOnValidThread() {
1979 return thread_checker_.CalledOnValidThread(); 2107 return thread_checker_.CalledOnValidThread();
1980 } 2108 }
1981 2109
1982 } // namespace arc 2110 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698