| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 constexpr uint32_t kGattReadPermission = | 57 constexpr uint32_t kGattReadPermission = |
| 58 BluetoothGattCharacteristic::Permission::PERMISSION_READ | | 58 BluetoothGattCharacteristic::Permission::PERMISSION_READ | |
| 59 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | | 59 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | |
| 60 BluetoothGattCharacteristic::Permission:: | 60 BluetoothGattCharacteristic::Permission:: |
| 61 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; | 61 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; |
| 62 constexpr uint32_t kGattWritePermission = | 62 constexpr uint32_t kGattWritePermission = |
| 63 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | | 63 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | |
| 64 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | | 64 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | |
| 65 BluetoothGattCharacteristic::Permission:: | 65 BluetoothGattCharacteristic::Permission:: |
| 66 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; | 66 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; |
| 67 constexpr int32_t kInvalidGattAttributeHandle = -1; |
| 68 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 |
| 69 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. |
| 70 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; |
| 71 |
| 72 using GattStatusCallback = |
| 73 base::Callback<void(arc::mojom::BluetoothGattStatus)>; |
| 74 using GattReadCallback = |
| 75 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; |
| 76 |
| 77 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a |
| 78 // Convert the last 4 characters of |identifier| to an |
| 79 // int, by interpreting them as hexadecimal digits. |
| 80 int ConvertGattIdentifierToId(const std::string identifier) { |
| 81 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); |
| 82 } |
| 83 |
| 84 // Create GattDBElement and fill in common data for |
| 85 // Gatt Service/Characteristic/Descriptor. |
| 86 template <class RemoteGattAttribute> |
| 87 arc::mojom::BluetoothGattDBElementPtr CreateGattDBElement( |
| 88 const arc::mojom::BluetoothGattDBAttributeType type, |
| 89 const RemoteGattAttribute* attribute) { |
| 90 arc::mojom::BluetoothGattDBElementPtr element = |
| 91 arc::mojom::BluetoothGattDBElement::New(); |
| 92 element->type = type; |
| 93 element->uuid = arc::mojom::BluetoothUUID::From(attribute->GetUUID()); |
| 94 element->id = element->attribute_handle = element->start_handle = |
| 95 element->end_handle = |
| 96 ConvertGattIdentifierToId(attribute->GetIdentifier()); |
| 97 element->properties = 0; |
| 98 return element; |
| 99 } |
| 100 |
| 101 template <class RemoteGattAttribute> |
| 102 RemoteGattAttribute* FindGattAttributeByUuid( |
| 103 const std::vector<RemoteGattAttribute*>& attributes, |
| 104 const BluetoothUUID& uuid) { |
| 105 auto it = std::find_if( |
| 106 attributes.begin(), attributes.end(), |
| 107 [uuid](RemoteGattAttribute* attr) { return attr->GetUUID() == uuid; }); |
| 108 return it != attributes.end() ? *it : nullptr; |
| 109 } |
| 110 |
| 111 // Common success callback for GATT operations that only need to report |
| 112 // GattStatus back to Android. |
| 113 void OnGattOperationDone(const GattStatusCallback& callback) { |
| 114 callback.Run(arc::mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 115 } |
| 116 |
| 117 // Common error callback for GATT operations that only need to report |
| 118 // GattStatus back to Android. |
| 119 void OnGattOperationError(const GattStatusCallback& callback, |
| 120 BluetoothGattService::GattErrorCode error_code) { |
| 121 callback.Run(mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code)); |
| 122 } |
| 123 |
| 124 // Common success callback for ReadGattCharacteristic and ReadGattDescriptor |
| 125 void OnGattReadDone(const GattReadCallback& callback, |
| 126 const std::vector<uint8_t>& result) { |
| 127 arc::mojom::BluetoothGattValuePtr gattValue = |
| 128 arc::mojom::BluetoothGattValue::New(); |
| 129 gattValue->status = arc::mojom::BluetoothGattStatus::GATT_SUCCESS; |
| 130 gattValue->value = mojo::Array<uint8_t>::From(result); |
| 131 callback.Run(std::move(gattValue)); |
| 132 } |
| 133 |
| 134 // Common error callback for ReadGattCharacteristic and ReadGattDescriptor |
| 135 void OnGattReadError(const GattReadCallback& callback, |
| 136 BluetoothGattService::GattErrorCode error_code) { |
| 137 arc::mojom::BluetoothGattValuePtr gattValue = |
| 138 arc::mojom::BluetoothGattValue::New(); |
| 139 gattValue->status = |
| 140 mojo::ConvertTo<arc::mojom::BluetoothGattStatus>(error_code); |
| 141 gattValue->value = nullptr; |
| 142 callback.Run(std::move(gattValue)); |
| 143 } |
| 144 |
| 67 } // namespace | 145 } // namespace |
| 68 | 146 |
| 69 namespace arc { | 147 namespace arc { |
| 70 | 148 |
| 71 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) | 149 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) |
| 72 : ArcService(bridge_service), binding_(this), weak_factory_(this) { | 150 : ArcService(bridge_service), binding_(this), weak_factory_(this) { |
| 73 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { | 151 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { |
| 74 VLOG(1) << "registering bluetooth adapter"; | 152 VLOG(1) << "registering bluetooth adapter"; |
| 75 BluetoothAdapterFactory::GetAdapter(base::Bind( | 153 BluetoothAdapterFactory::GetAdapter(base::Bind( |
| 76 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); | 154 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); |
| 77 } else { | 155 } else { |
| 78 VLOG(1) << "no bluetooth adapter available"; | 156 VLOG(1) << "no bluetooth adapter available"; |
| 79 } | 157 } |
| 80 | 158 |
| 81 arc_bridge_service()->bluetooth()->AddObserver(this); | 159 arc_bridge_service()->bluetooth()->AddObserver(this); |
| 82 } | 160 } |
| 83 | 161 |
| 84 ArcBluetoothBridge::~ArcBluetoothBridge() { | 162 ArcBluetoothBridge::~ArcBluetoothBridge() { |
| 163 DCHECK(CalledOnValidThread()); |
| 164 |
| 85 arc_bridge_service()->bluetooth()->RemoveObserver(this); | 165 arc_bridge_service()->bluetooth()->RemoveObserver(this); |
| 86 | 166 |
| 87 if (bluetooth_adapter_) | 167 if (bluetooth_adapter_) |
| 88 bluetooth_adapter_->RemoveObserver(this); | 168 bluetooth_adapter_->RemoveObserver(this); |
| 89 } | 169 } |
| 90 | 170 |
| 91 void ArcBluetoothBridge::OnAdapterInitialized( | 171 void ArcBluetoothBridge::OnAdapterInitialized( |
| 92 scoped_refptr<BluetoothAdapter> adapter) { | 172 scoped_refptr<BluetoothAdapter> adapter) { |
| 173 DCHECK(CalledOnValidThread()); |
| 174 |
| 93 // We can downcast here because we are always running on Chrome OS, and | 175 // We can downcast here because we are always running on Chrome OS, and |
| 94 // so our adapter uses BlueZ. | 176 // so our adapter uses BlueZ. |
| 95 bluetooth_adapter_ = | 177 bluetooth_adapter_ = |
| 96 static_cast<bluez::BluetoothAdapterBlueZ*>(adapter.get()); | 178 static_cast<bluez::BluetoothAdapterBlueZ*>(adapter.get()); |
| 97 bluetooth_adapter_->AddObserver(this); | 179 bluetooth_adapter_->AddObserver(this); |
| 98 } | 180 } |
| 99 | 181 |
| 100 void ArcBluetoothBridge::OnInstanceReady() { | 182 void ArcBluetoothBridge::OnInstanceReady() { |
| 101 mojom::BluetoothInstance* bluetooth_instance = | 183 mojom::BluetoothInstance* bluetooth_instance = |
| 102 arc_bridge_service()->bluetooth()->instance(); | 184 arc_bridge_service()->bluetooth()->instance(); |
| 103 if (!bluetooth_instance) { | 185 if (!bluetooth_instance) { |
| 104 LOG(ERROR) << "OnBluetoothInstanceReady called, " | 186 LOG(ERROR) << "OnBluetoothInstanceReady called, " |
| 105 << "but no bluetooth instance found"; | 187 << "but no bluetooth instance found"; |
| 106 return; | 188 return; |
| 107 } | 189 } |
| 108 bluetooth_instance->Init(binding_.CreateInterfacePtrAndBind()); | 190 bluetooth_instance->Init(binding_.CreateInterfacePtrAndBind()); |
| 109 } | 191 } |
| 110 | 192 |
| 111 void ArcBluetoothBridge::AdapterPresentChanged(BluetoothAdapter* adapter, | 193 void ArcBluetoothBridge::AdapterPresentChanged(BluetoothAdapter* adapter, |
| 112 bool present) { | 194 bool present) { |
| 195 DCHECK(CalledOnValidThread()); |
| 196 |
| 113 // If the adapter goes away, remove ourselves as an observer. | 197 // If the adapter goes away, remove ourselves as an observer. |
| 114 if (!present && adapter == bluetooth_adapter_) { | 198 if (!present && adapter == bluetooth_adapter_) { |
| 115 adapter->RemoveObserver(this); | 199 adapter->RemoveObserver(this); |
| 116 bluetooth_adapter_ = nullptr; | 200 bluetooth_adapter_ = nullptr; |
| 117 } | 201 } |
| 118 } | 202 } |
| 119 | 203 |
| 120 void ArcBluetoothBridge::AdapterPoweredChanged(BluetoothAdapter* adapter, | 204 void ArcBluetoothBridge::AdapterPoweredChanged(BluetoothAdapter* adapter, |
| 121 bool powered) { | 205 bool powered) { |
| 122 if (!HasBluetoothInstance()) | 206 if (!HasBluetoothInstance()) |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 692 return; | 776 return; |
| 693 } | 777 } |
| 694 | 778 |
| 695 // Discard result. Will call the callback when discovery is completed. | 779 // Discard result. Will call the callback when discovery is completed. |
| 696 device->GetGattServices(); | 780 device->GetGattServices(); |
| 697 } | 781 } |
| 698 | 782 |
| 699 void ArcBluetoothBridge::OnStartLEListenDone( | 783 void ArcBluetoothBridge::OnStartLEListenDone( |
| 700 const StartLEListenCallback& callback, | 784 const StartLEListenCallback& callback, |
| 701 scoped_refptr<BluetoothAdvertisement> advertisement) { | 785 scoped_refptr<BluetoothAdvertisement> advertisement) { |
| 786 DCHECK(CalledOnValidThread()); |
| 702 advertisment_ = advertisement; | 787 advertisment_ = advertisement; |
| 703 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | 788 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 704 } | 789 } |
| 705 | 790 |
| 706 void ArcBluetoothBridge::OnStartLEListenError( | 791 void ArcBluetoothBridge::OnStartLEListenError( |
| 707 const StartLEListenCallback& callback, | 792 const StartLEListenCallback& callback, |
| 708 BluetoothAdvertisement::ErrorCode error_code) { | 793 BluetoothAdvertisement::ErrorCode error_code) { |
| 794 DCHECK(CalledOnValidThread()); |
| 709 advertisment_ = nullptr; | 795 advertisment_ = nullptr; |
| 710 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); | 796 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 711 } | 797 } |
| 712 | 798 |
| 713 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) { | 799 void ArcBluetoothBridge::StartLEListen(const StartLEListenCallback& callback) { |
| 800 DCHECK(CalledOnValidThread()); |
| 714 std::unique_ptr<BluetoothAdvertisement::Data> adv_data = | 801 std::unique_ptr<BluetoothAdvertisement::Data> adv_data = |
| 715 base::WrapUnique(new BluetoothAdvertisement::Data( | 802 base::WrapUnique(new BluetoothAdvertisement::Data( |
| 716 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST)); | 803 BluetoothAdvertisement::ADVERTISEMENT_TYPE_BROADCAST)); |
| 717 bluetooth_adapter_->RegisterAdvertisement( | 804 bluetooth_adapter_->RegisterAdvertisement( |
| 718 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone, | 805 std::move(adv_data), base::Bind(&ArcBluetoothBridge::OnStartLEListenDone, |
| 719 weak_factory_.GetWeakPtr(), callback), | 806 weak_factory_.GetWeakPtr(), callback), |
| 720 base::Bind(&ArcBluetoothBridge::OnStartLEListenError, | 807 base::Bind(&ArcBluetoothBridge::OnStartLEListenError, |
| 721 weak_factory_.GetWeakPtr(), callback)); | 808 weak_factory_.GetWeakPtr(), callback)); |
| 722 } | 809 } |
| 723 | 810 |
| 724 void ArcBluetoothBridge::OnStopLEListenDone( | 811 void ArcBluetoothBridge::OnStopLEListenDone( |
| 725 const StopLEListenCallback& callback) { | 812 const StopLEListenCallback& callback) { |
| 813 DCHECK(CalledOnValidThread()); |
| 726 advertisment_ = nullptr; | 814 advertisment_ = nullptr; |
| 727 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | 815 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 728 } | 816 } |
| 729 | 817 |
| 730 void ArcBluetoothBridge::OnStopLEListenError( | 818 void ArcBluetoothBridge::OnStopLEListenError( |
| 731 const StopLEListenCallback& callback, | 819 const StopLEListenCallback& callback, |
| 732 BluetoothAdvertisement::ErrorCode error_code) { | 820 BluetoothAdvertisement::ErrorCode error_code) { |
| 821 DCHECK(CalledOnValidThread()); |
| 733 advertisment_ = nullptr; | 822 advertisment_ = nullptr; |
| 734 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); | 823 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE); |
| 735 } | 824 } |
| 736 | 825 |
| 737 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) { | 826 void ArcBluetoothBridge::StopLEListen(const StopLEListenCallback& callback) { |
| 738 if (!advertisment_) { | 827 if (!advertisment_) { |
| 739 OnStopLEListenError( | 828 OnStopLEListenError( |
| 740 callback, | 829 callback, |
| 741 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); | 830 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); |
| 742 return; | 831 return; |
| 743 } | 832 } |
| 744 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone, | 833 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone, |
| 745 weak_factory_.GetWeakPtr(), callback), | 834 weak_factory_.GetWeakPtr(), callback), |
| 746 base::Bind(&ArcBluetoothBridge::OnStopLEListenError, | 835 base::Bind(&ArcBluetoothBridge::OnStopLEListenError, |
| 747 weak_factory_.GetWeakPtr(), callback)); | 836 weak_factory_.GetWeakPtr(), callback)); |
| 748 } | 837 } |
| 749 | 838 |
| 750 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a | |
| 751 // We want to convert last digit of the identifier to int in base 16 | |
| 752 int ArcBluetoothBridge::ConvertGattIdentifierToId( | |
| 753 const std::string identifier) const { | |
| 754 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); | |
| 755 } | |
| 756 | |
| 757 // Create GattDBElement and fill in common data for | |
| 758 // Gatt Service/Characteristic/Descriptor. | |
| 759 template <class T> | |
| 760 mojom::BluetoothGattDBElementPtr ArcBluetoothBridge::CreateGattDBElement( | |
| 761 const mojom::BluetoothGattDBAttributeType type, | |
| 762 const T* gattObject) const { | |
| 763 mojom::BluetoothGattDBElementPtr element = | |
| 764 mojom::BluetoothGattDBElement::New(); | |
| 765 element->type = type; | |
| 766 element->uuid = mojom::BluetoothUUID::From(gattObject->GetUUID()); | |
| 767 element->id = element->attribute_handle = element->start_handle = | |
| 768 element->end_handle = | |
| 769 ConvertGattIdentifierToId(gattObject->GetIdentifier()); | |
| 770 element->properties = 0; | |
| 771 return element; | |
| 772 } | |
| 773 | |
| 774 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) { | 839 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) { |
| 775 if (!HasBluetoothInstance()) | 840 if (!HasBluetoothInstance()) |
| 776 return; | 841 return; |
| 777 | 842 |
| 778 BluetoothDevice* device = | 843 BluetoothDevice* device = |
| 779 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 844 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 780 mojo::Array<mojom::BluetoothGattDBElementPtr> db; | 845 mojo::Array<mojom::BluetoothGattDBElementPtr> db; |
| 781 for (auto* service : device->GetGattServices()) { | 846 for (auto* service : device->GetGattServices()) { |
| 782 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement< | 847 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement( |
| 783 device::BluetoothRemoteGattService>( | |
| 784 service->IsPrimary() | 848 service->IsPrimary() |
| 785 ? mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE | 849 ? mojom::BluetoothGattDBAttributeType::BTGATT_DB_PRIMARY_SERVICE |
| 786 : mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE, | 850 : mojom::BluetoothGattDBAttributeType::BTGATT_DB_SECONDARY_SERVICE, |
| 787 service); | 851 service); |
| 788 | 852 |
| 789 const auto& characteristics = service->GetCharacteristics(); | 853 const auto& characteristics = service->GetCharacteristics(); |
| 790 if (characteristics.size() > 0) { | 854 if (characteristics.size() > 0) { |
| 791 const auto& descriptors = characteristics.back()->GetDescriptors(); | 855 const auto& descriptors = characteristics.back()->GetDescriptors(); |
| 792 service_element->start_handle = | 856 service_element->start_handle = |
| 793 ConvertGattIdentifierToId(characteristics.front()->GetIdentifier()); | 857 ConvertGattIdentifierToId(characteristics.front()->GetIdentifier()); |
| 794 service_element->end_handle = ConvertGattIdentifierToId( | 858 service_element->end_handle = ConvertGattIdentifierToId( |
| 795 descriptors.size() > 0 ? descriptors.back()->GetIdentifier() | 859 descriptors.size() > 0 ? descriptors.back()->GetIdentifier() |
| 796 : characteristics.back()->GetIdentifier()); | 860 : characteristics.back()->GetIdentifier()); |
| 797 } | 861 } |
| 798 db.push_back(std::move(service_element)); | 862 db.push_back(std::move(service_element)); |
| 799 | 863 |
| 800 for (auto* characteristic : characteristics) { | 864 for (auto* characteristic : characteristics) { |
| 801 mojom::BluetoothGattDBElementPtr characteristic_element = | 865 mojom::BluetoothGattDBElementPtr characteristic_element = |
| 802 CreateGattDBElement<device::BluetoothRemoteGattCharacteristic>( | 866 CreateGattDBElement( |
| 803 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, | 867 mojom::BluetoothGattDBAttributeType::BTGATT_DB_CHARACTERISTIC, |
| 804 characteristic); | 868 characteristic); |
| 805 characteristic_element->properties = characteristic->GetProperties(); | 869 characteristic_element->properties = characteristic->GetProperties(); |
| 806 db.push_back(std::move(characteristic_element)); | 870 db.push_back(std::move(characteristic_element)); |
| 807 | 871 |
| 808 for (auto* descriptor : characteristic->GetDescriptors()) { | 872 for (auto* descriptor : characteristic->GetDescriptors()) { |
| 809 db.push_back(CreateGattDBElement<device::BluetoothRemoteGattDescriptor>( | 873 db.push_back(CreateGattDBElement( |
| 810 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, | 874 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, |
| 811 descriptor)); | 875 descriptor)); |
| 812 } | 876 } |
| 813 } | 877 } |
| 814 } | 878 } |
| 815 | 879 |
| 816 arc_bridge_service()->bluetooth()->instance()->OnGetGattDB( | 880 arc_bridge_service()->bluetooth()->instance()->OnGetGattDB( |
| 817 std::move(remote_addr), std::move(db)); | 881 std::move(remote_addr), std::move(db)); |
| 818 } | 882 } |
| 819 | 883 |
| 820 // Find Gatt Service/Characteristic/Descriptor from std::vector from UUID. | |
| 821 template <class T> | |
| 822 T* ArcBluetoothBridge::FindGattObjectFromUuid( | |
| 823 const std::vector<T*> gatt_objs, | |
| 824 const device::BluetoothUUID uuid) const { | |
| 825 auto it = std::find_if(gatt_objs.begin(), gatt_objs.end(), | |
| 826 [&](T* obj) { return obj->GetUUID() == uuid; }); | |
| 827 if (it == gatt_objs.end()) | |
| 828 return nullptr; | |
| 829 return *it; | |
| 830 } | |
| 831 | |
| 832 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic( | 884 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic( |
| 833 mojom::BluetoothAddressPtr remote_addr, | 885 mojom::BluetoothAddressPtr remote_addr, |
| 834 mojom::BluetoothGattServiceIDPtr service_id, | 886 mojom::BluetoothGattServiceIDPtr service_id, |
| 835 mojom::BluetoothGattIDPtr char_id) const { | 887 mojom::BluetoothGattIDPtr char_id) const { |
| 836 DCHECK(remote_addr); | 888 DCHECK(remote_addr); |
| 837 DCHECK(service_id); | 889 DCHECK(service_id); |
| 838 DCHECK(char_id); | 890 DCHECK(char_id); |
| 839 | 891 |
| 840 BluetoothDevice* device = | 892 BluetoothDevice* device = |
| 841 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 893 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 842 if (!device) | 894 if (!device) |
| 843 return nullptr; | 895 return nullptr; |
| 844 | 896 |
| 845 BluetoothRemoteGattService* service = | 897 BluetoothRemoteGattService* service = FindGattAttributeByUuid( |
| 846 FindGattObjectFromUuid<BluetoothRemoteGattService>( | 898 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>()); |
| 847 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>()); | |
| 848 if (!service) | 899 if (!service) |
| 849 return nullptr; | 900 return nullptr; |
| 850 | 901 |
| 851 return FindGattObjectFromUuid<BluetoothRemoteGattCharacteristic>( | 902 return FindGattAttributeByUuid(service->GetCharacteristics(), |
| 852 service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>()); | 903 char_id->uuid.To<BluetoothUUID>()); |
| 853 } | 904 } |
| 854 | 905 |
| 855 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor( | 906 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor( |
| 856 mojom::BluetoothAddressPtr remote_addr, | 907 mojom::BluetoothAddressPtr remote_addr, |
| 857 mojom::BluetoothGattServiceIDPtr service_id, | 908 mojom::BluetoothGattServiceIDPtr service_id, |
| 858 mojom::BluetoothGattIDPtr char_id, | 909 mojom::BluetoothGattIDPtr char_id, |
| 859 mojom::BluetoothGattIDPtr desc_id) const { | 910 mojom::BluetoothGattIDPtr desc_id) const { |
| 860 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( | 911 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 861 std::move(remote_addr), std::move(service_id), std::move(char_id)); | 912 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 862 if (!characteristic) | 913 if (!characteristic) |
| 863 return nullptr; | 914 return nullptr; |
| 864 | 915 |
| 865 return FindGattObjectFromUuid<BluetoothRemoteGattDescriptor>( | 916 return FindGattAttributeByUuid(characteristic->GetDescriptors(), |
| 866 characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>()); | 917 desc_id->uuid.To<BluetoothUUID>()); |
| 867 } | |
| 868 | |
| 869 // Same callback for both ReadGattCharacteristic and ReadGattDescriptor | |
| 870 void ArcBluetoothBridge::OnGattReadDone( | |
| 871 const GattReadCallback& callback, | |
| 872 const std::vector<uint8_t>& result) const { | |
| 873 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New(); | |
| 874 gattValue->status = mojom::BluetoothGattStatus::GATT_SUCCESS; | |
| 875 gattValue->value = mojo::Array<uint8_t>::From(result); | |
| 876 callback.Run(std::move(gattValue)); | |
| 877 } | |
| 878 | |
| 879 void ArcBluetoothBridge::OnGattReadError( | |
| 880 const GattReadCallback& callback, | |
| 881 BluetoothGattService::GattErrorCode error_code) const { | |
| 882 mojom::BluetoothGattValuePtr gattValue = mojom::BluetoothGattValue::New(); | |
| 883 gattValue->status = mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code); | |
| 884 gattValue->value = nullptr; | |
| 885 | |
| 886 callback.Run(std::move(gattValue)); | |
| 887 } | |
| 888 | |
| 889 // Same callback for both WriteGattCharacteristic and WriteGattDescriptor | |
| 890 void ArcBluetoothBridge::OnGattWriteDone( | |
| 891 const GattWriteCallback& callback) const { | |
| 892 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | |
| 893 } | |
| 894 | |
| 895 void ArcBluetoothBridge::OnGattWriteError( | |
| 896 const GattWriteCallback& callback, | |
| 897 BluetoothGattService::GattErrorCode error_code) const { | |
| 898 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code)); | |
| 899 } | 918 } |
| 900 | 919 |
| 901 void ArcBluetoothBridge::ReadGattCharacteristic( | 920 void ArcBluetoothBridge::ReadGattCharacteristic( |
| 902 mojom::BluetoothAddressPtr remote_addr, | 921 mojom::BluetoothAddressPtr remote_addr, |
| 903 mojom::BluetoothGattServiceIDPtr service_id, | 922 mojom::BluetoothGattServiceIDPtr service_id, |
| 904 mojom::BluetoothGattIDPtr char_id, | 923 mojom::BluetoothGattIDPtr char_id, |
| 905 const ReadGattCharacteristicCallback& callback) { | 924 const ReadGattCharacteristicCallback& callback) { |
| 906 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( | 925 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 907 std::move(remote_addr), std::move(service_id), std::move(char_id)); | 926 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 908 DCHECK(characteristic); | 927 DCHECK(characteristic); |
| 909 DCHECK(characteristic->GetPermissions() & kGattReadPermission); | 928 DCHECK(characteristic->GetPermissions() & kGattReadPermission); |
| 910 | 929 |
| 911 characteristic->ReadRemoteCharacteristic( | 930 characteristic->ReadRemoteCharacteristic( |
| 912 base::Bind(&ArcBluetoothBridge::OnGattReadDone, | 931 base::Bind(&OnGattReadDone, callback), |
| 913 weak_factory_.GetWeakPtr(), callback), | 932 base::Bind(&OnGattReadError, callback)); |
| 914 base::Bind(&ArcBluetoothBridge::OnGattReadError, | |
| 915 weak_factory_.GetWeakPtr(), callback)); | |
| 916 } | 933 } |
| 917 | 934 |
| 918 void ArcBluetoothBridge::WriteGattCharacteristic( | 935 void ArcBluetoothBridge::WriteGattCharacteristic( |
| 919 mojom::BluetoothAddressPtr remote_addr, | 936 mojom::BluetoothAddressPtr remote_addr, |
| 920 mojom::BluetoothGattServiceIDPtr service_id, | 937 mojom::BluetoothGattServiceIDPtr service_id, |
| 921 mojom::BluetoothGattIDPtr char_id, | 938 mojom::BluetoothGattIDPtr char_id, |
| 922 mojom::BluetoothGattValuePtr value, | 939 mojom::BluetoothGattValuePtr value, |
| 923 const WriteGattCharacteristicCallback& callback) { | 940 const WriteGattCharacteristicCallback& callback) { |
| 924 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( | 941 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 925 std::move(remote_addr), std::move(service_id), std::move(char_id)); | 942 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 926 DCHECK(characteristic); | 943 DCHECK(characteristic); |
| 927 DCHECK(characteristic->GetPermissions() & kGattWritePermission); | 944 DCHECK(characteristic->GetPermissions() & kGattWritePermission); |
| 928 | 945 |
| 929 characteristic->WriteRemoteCharacteristic( | 946 characteristic->WriteRemoteCharacteristic( |
| 930 value->value.To<std::vector<uint8_t>>(), | 947 value->value.To<std::vector<uint8_t>>(), |
| 931 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, | 948 base::Bind(&OnGattOperationDone, callback), |
| 932 weak_factory_.GetWeakPtr(), callback), | 949 base::Bind(&OnGattOperationError, callback)); |
| 933 base::Bind(&ArcBluetoothBridge::OnGattWriteError, | |
| 934 weak_factory_.GetWeakPtr(), callback)); | |
| 935 } | 950 } |
| 936 | 951 |
| 937 void ArcBluetoothBridge::ReadGattDescriptor( | 952 void ArcBluetoothBridge::ReadGattDescriptor( |
| 938 mojom::BluetoothAddressPtr remote_addr, | 953 mojom::BluetoothAddressPtr remote_addr, |
| 939 mojom::BluetoothGattServiceIDPtr service_id, | 954 mojom::BluetoothGattServiceIDPtr service_id, |
| 940 mojom::BluetoothGattIDPtr char_id, | 955 mojom::BluetoothGattIDPtr char_id, |
| 941 mojom::BluetoothGattIDPtr desc_id, | 956 mojom::BluetoothGattIDPtr desc_id, |
| 942 const ReadGattDescriptorCallback& callback) { | 957 const ReadGattDescriptorCallback& callback) { |
| 943 BluetoothRemoteGattDescriptor* descriptor = | 958 BluetoothRemoteGattDescriptor* descriptor = |
| 944 FindGattDescriptor(std::move(remote_addr), std::move(service_id), | 959 FindGattDescriptor(std::move(remote_addr), std::move(service_id), |
| 945 std::move(char_id), std::move(desc_id)); | 960 std::move(char_id), std::move(desc_id)); |
| 946 DCHECK(descriptor); | 961 DCHECK(descriptor); |
| 947 DCHECK(descriptor->GetPermissions() & kGattReadPermission); | 962 DCHECK(descriptor->GetPermissions() & kGattReadPermission); |
| 948 | 963 |
| 949 descriptor->ReadRemoteDescriptor( | 964 descriptor->ReadRemoteDescriptor(base::Bind(&OnGattReadDone, callback), |
| 950 base::Bind(&ArcBluetoothBridge::OnGattReadDone, | 965 base::Bind(&OnGattReadError, callback)); |
| 951 weak_factory_.GetWeakPtr(), callback), | |
| 952 base::Bind(&ArcBluetoothBridge::OnGattReadError, | |
| 953 weak_factory_.GetWeakPtr(), callback)); | |
| 954 } | 966 } |
| 955 | 967 |
| 956 void ArcBluetoothBridge::WriteGattDescriptor( | 968 void ArcBluetoothBridge::WriteGattDescriptor( |
| 957 mojom::BluetoothAddressPtr remote_addr, | 969 mojom::BluetoothAddressPtr remote_addr, |
| 958 mojom::BluetoothGattServiceIDPtr service_id, | 970 mojom::BluetoothGattServiceIDPtr service_id, |
| 959 mojom::BluetoothGattIDPtr char_id, | 971 mojom::BluetoothGattIDPtr char_id, |
| 960 mojom::BluetoothGattIDPtr desc_id, | 972 mojom::BluetoothGattIDPtr desc_id, |
| 961 mojom::BluetoothGattValuePtr value, | 973 mojom::BluetoothGattValuePtr value, |
| 962 const WriteGattDescriptorCallback& callback) { | 974 const WriteGattDescriptorCallback& callback) { |
| 963 BluetoothRemoteGattDescriptor* descriptor = | 975 BluetoothRemoteGattDescriptor* descriptor = |
| 964 FindGattDescriptor(std::move(remote_addr), std::move(service_id), | 976 FindGattDescriptor(std::move(remote_addr), std::move(service_id), |
| 965 std::move(char_id), std::move(desc_id)); | 977 std::move(char_id), std::move(desc_id)); |
| 966 DCHECK(descriptor); | 978 DCHECK(descriptor); |
| 967 DCHECK(descriptor->GetPermissions() & kGattWritePermission); | 979 DCHECK(descriptor->GetPermissions() & kGattWritePermission); |
| 968 | 980 |
| 969 // To register / deregister GATT notification, we need to | 981 // To register / deregister GATT notification, we need to |
| 970 // 1) Write to CCC Descriptor to enable/disable the notification | 982 // 1) Write to CCC Descriptor to enable/disable the notification |
| 971 // 2) Ask BT hw to register / deregister the notification | 983 // 2) Ask BT hw to register / deregister the notification |
| 972 // The Chrome API groups both steps into one API, and does not support writing | 984 // The Chrome API groups both steps into one API, and does not support writing |
| 973 // directly to the CCC Descriptor. Therefore, until we fix | 985 // directly to the CCC Descriptor. Therefore, until we fix |
| 974 // https://crbug.com/622832, we return successfully when we encounter this. | 986 // https://crbug.com/622832, we return successfully when we encounter this. |
| 975 // TODO(http://crbug.com/622832) | 987 // TODO(http://crbug.com/622832) |
| 976 if (descriptor->GetUUID() == | 988 if (descriptor->GetUUID() == |
| 977 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) { | 989 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) { |
| 978 OnGattWriteDone(callback); | 990 OnGattOperationDone(callback); |
| 979 return; | 991 return; |
| 980 } | 992 } |
| 981 | 993 |
| 982 descriptor->WriteRemoteDescriptor( | 994 descriptor->WriteRemoteDescriptor( |
| 983 value->value.To<std::vector<uint8_t>>(), | 995 value->value.To<std::vector<uint8_t>>(), |
| 984 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, | 996 base::Bind(&OnGattOperationDone, callback), |
| 985 weak_factory_.GetWeakPtr(), callback), | 997 base::Bind(&OnGattOperationError, callback)); |
| 986 base::Bind(&ArcBluetoothBridge::OnGattWriteError, | |
| 987 weak_factory_.GetWeakPtr(), callback)); | |
| 988 } | 998 } |
| 989 | 999 |
| 990 void ArcBluetoothBridge::OnGattNotifyStartDone( | 1000 void ArcBluetoothBridge::OnGattNotifyStartDone( |
| 991 const RegisterForGattNotificationCallback& callback, | 1001 const RegisterForGattNotificationCallback& callback, |
| 992 const std::string char_string_id, | 1002 const std::string char_string_id, |
| 993 std::unique_ptr<BluetoothGattNotifySession> notify_session) { | 1003 std::unique_ptr<BluetoothGattNotifySession> notify_session) { |
| 1004 DCHECK(CalledOnValidThread()); |
| 994 notification_session_[char_string_id] = std::move(notify_session); | 1005 notification_session_[char_string_id] = std::move(notify_session); |
| 995 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | 1006 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 996 } | 1007 } |
| 997 | 1008 |
| 998 void ArcBluetoothBridge::OnGattNotifyStartError( | |
| 999 const RegisterForGattNotificationCallback& callback, | |
| 1000 BluetoothGattService::GattErrorCode error_code) const { | |
| 1001 callback.Run(mojo::ConvertTo<mojom::BluetoothGattStatus>(error_code)); | |
| 1002 } | |
| 1003 | |
| 1004 void ArcBluetoothBridge::OnGattNotifyStopDone( | |
| 1005 const DeregisterForGattNotificationCallback& callback) const { | |
| 1006 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | |
| 1007 } | |
| 1008 | |
| 1009 void ArcBluetoothBridge::RegisterForGattNotification( | 1009 void ArcBluetoothBridge::RegisterForGattNotification( |
| 1010 mojom::BluetoothAddressPtr remote_addr, | 1010 mojom::BluetoothAddressPtr remote_addr, |
| 1011 mojom::BluetoothGattServiceIDPtr service_id, | 1011 mojom::BluetoothGattServiceIDPtr service_id, |
| 1012 mojom::BluetoothGattIDPtr char_id, | 1012 mojom::BluetoothGattIDPtr char_id, |
| 1013 const RegisterForGattNotificationCallback& callback) { | 1013 const RegisterForGattNotificationCallback& callback) { |
| 1014 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( | 1014 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 1015 std::move(remote_addr), std::move(service_id), std::move(char_id)); | 1015 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 1016 | 1016 |
| 1017 if (!characteristic) { | 1017 if (!characteristic) { |
| 1018 LOG(WARNING) << __func__ << " Characteristic is not existed."; | 1018 LOG(WARNING) << __func__ << " Characteristic is not existed."; |
| 1019 return; | 1019 return; |
| 1020 } | 1020 } |
| 1021 | 1021 |
| 1022 if (characteristic->IsNotifying()) { | 1022 if (characteristic->IsNotifying()) { |
| 1023 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | 1023 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1024 return; | 1024 return; |
| 1025 } | 1025 } |
| 1026 | 1026 |
| 1027 characteristic->StartNotifySession( | 1027 characteristic->StartNotifySession( |
| 1028 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone, | 1028 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone, |
| 1029 weak_factory_.GetWeakPtr(), callback, | 1029 weak_factory_.GetWeakPtr(), callback, |
| 1030 characteristic->GetIdentifier()), | 1030 characteristic->GetIdentifier()), |
| 1031 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError, | 1031 base::Bind(&OnGattOperationError, callback)); |
| 1032 weak_factory_.GetWeakPtr(), callback)); | |
| 1033 } | 1032 } |
| 1034 | 1033 |
| 1035 void ArcBluetoothBridge::DeregisterForGattNotification( | 1034 void ArcBluetoothBridge::DeregisterForGattNotification( |
| 1036 mojom::BluetoothAddressPtr remote_addr, | 1035 mojom::BluetoothAddressPtr remote_addr, |
| 1037 mojom::BluetoothGattServiceIDPtr service_id, | 1036 mojom::BluetoothGattServiceIDPtr service_id, |
| 1038 mojom::BluetoothGattIDPtr char_id, | 1037 mojom::BluetoothGattIDPtr char_id, |
| 1039 const DeregisterForGattNotificationCallback& callback) { | 1038 const DeregisterForGattNotificationCallback& callback) { |
| 1039 DCHECK(CalledOnValidThread()); |
| 1040 |
| 1040 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( | 1041 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( |
| 1041 std::move(remote_addr), std::move(service_id), std::move(char_id)); | 1042 std::move(remote_addr), std::move(service_id), std::move(char_id)); |
| 1042 | 1043 |
| 1043 if (!characteristic) { | 1044 if (!characteristic) { |
| 1044 LOG(WARNING) << __func__ << " Characteristic is not existed."; | 1045 LOG(WARNING) << __func__ << " Characteristic is not existed."; |
| 1045 return; | 1046 return; |
| 1046 } | 1047 } |
| 1047 | 1048 |
| 1048 if (!characteristic->IsNotifying()) { | 1049 if (!characteristic->IsNotifying()) { |
| 1049 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); | 1050 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); |
| 1050 return; | 1051 return; |
| 1051 } | 1052 } |
| 1052 | 1053 |
| 1053 std::string char_id_str = characteristic->GetIdentifier(); | 1054 std::string char_id_str = characteristic->GetIdentifier(); |
| 1054 std::unique_ptr<BluetoothGattNotifySession> notify = | 1055 std::unique_ptr<BluetoothGattNotifySession> notify = |
| 1055 std::move(notification_session_[char_id_str]); | 1056 std::move(notification_session_[char_id_str]); |
| 1056 notification_session_.erase(char_id_str); | 1057 notification_session_.erase(char_id_str); |
| 1057 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone, | 1058 notify->Stop(base::Bind(&OnGattOperationDone, callback)); |
| 1058 weak_factory_.GetWeakPtr(), callback)); | |
| 1059 } | 1059 } |
| 1060 | 1060 |
| 1061 void ArcBluetoothBridge::ReadRemoteRssi( | 1061 void ArcBluetoothBridge::ReadRemoteRssi( |
| 1062 mojom::BluetoothAddressPtr remote_addr, | 1062 mojom::BluetoothAddressPtr remote_addr, |
| 1063 const ReadRemoteRssiCallback& callback) { | 1063 const ReadRemoteRssiCallback& callback) { |
| 1064 BluetoothDevice* device = | 1064 BluetoothDevice* device = |
| 1065 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); | 1065 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); |
| 1066 int rssi = device->GetInquiryRSSI(); | 1066 int rssi = device->GetInquiryRSSI(); |
| 1067 callback.Run(rssi); | 1067 callback.Run(rssi); |
| 1068 } | 1068 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1083 if (wrap_result != MOJO_RESULT_OK) { | 1083 if (wrap_result != MOJO_RESULT_OK) { |
| 1084 LOG(ERROR) << "Failed to wrap handles. Closing: " << wrap_result; | 1084 LOG(ERROR) << "Failed to wrap handles. Closing: " << wrap_result; |
| 1085 callback.Run(mojo::ScopedHandle()); | 1085 callback.Run(mojo::ScopedHandle()); |
| 1086 return; | 1086 return; |
| 1087 } | 1087 } |
| 1088 mojo::ScopedHandle scoped_handle{mojo::Handle(wrapped_handle)}; | 1088 mojo::ScopedHandle scoped_handle{mojo::Handle(wrapped_handle)}; |
| 1089 | 1089 |
| 1090 callback.Run(std::move(scoped_handle)); | 1090 callback.Run(std::move(scoped_handle)); |
| 1091 } | 1091 } |
| 1092 | 1092 |
| 1093 bool ArcBluetoothBridge::IsGattServerAttributeHandleAvailable(int need) { |
| 1094 return gatt_server_attribute_next_handle_ + need <= kMaxGattAttributeHandle; |
| 1095 } |
| 1096 |
| 1097 int32_t ArcBluetoothBridge::GetNextGattServerAttributeHandle() { |
| 1098 return IsGattServerAttributeHandleAvailable(1) |
| 1099 ? ++gatt_server_attribute_next_handle_ |
| 1100 : kInvalidGattAttributeHandle; |
| 1101 } |
| 1102 |
| 1103 template <class LocalGattAttribute> |
| 1104 int32_t ArcBluetoothBridge::CreateGattAttributeHandle( |
| 1105 LocalGattAttribute* attribute) { |
| 1106 DCHECK(CalledOnValidThread()); |
| 1107 if (!attribute) |
| 1108 return kInvalidGattAttributeHandle; |
| 1109 int32_t handle = GetNextGattServerAttributeHandle(); |
| 1110 if (handle == kInvalidGattAttributeHandle) |
| 1111 return kInvalidGattAttributeHandle; |
| 1112 const std::string& identifier = attribute->GetIdentifier(); |
| 1113 gatt_identifier_[handle] = identifier; |
| 1114 return handle; |
| 1115 } |
| 1116 |
| 1093 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id, | 1117 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id, |
| 1094 int32_t num_handles, | 1118 int32_t num_handles, |
| 1095 const AddServiceCallback& callback) {} | 1119 const AddServiceCallback& callback) { |
| 1120 if (!IsGattServerAttributeHandleAvailable(num_handles)) { |
| 1121 callback.Run(kInvalidGattAttributeHandle); |
| 1122 return; |
| 1123 } |
| 1124 base::WeakPtr<BluetoothLocalGattService> service = |
| 1125 BluetoothLocalGattService::Create( |
| 1126 bluetooth_adapter_.get(), service_id->id->uuid.To<BluetoothUUID>(), |
| 1127 service_id->is_primary, nullptr /* included_service */, |
| 1128 this /* delegate */); |
| 1129 callback.Run(CreateGattAttributeHandle(service.get())); |
| 1130 } |
| 1096 | 1131 |
| 1097 void ArcBluetoothBridge::AddCharacteristic( | 1132 void ArcBluetoothBridge::AddCharacteristic( |
| 1098 int32_t service_handle, | 1133 int32_t service_handle, |
| 1099 mojom::BluetoothUUIDPtr uuid, | 1134 mojom::BluetoothUUIDPtr uuid, |
| 1100 int32_t properties, | 1135 int32_t properties, |
| 1101 int32_t permissions, | 1136 int32_t permissions, |
| 1102 const AddCharacteristicCallback& callback) {} | 1137 const AddCharacteristicCallback& callback) { |
| 1138 DCHECK(CalledOnValidThread()); |
| 1139 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1140 if (!IsGattServerAttributeHandleAvailable(1)) { |
| 1141 callback.Run(kInvalidGattAttributeHandle); |
| 1142 return; |
| 1143 } |
| 1144 base::WeakPtr<BluetoothLocalGattCharacteristic> characteristic = |
| 1145 BluetoothLocalGattCharacteristic::Create( |
| 1146 uuid.To<BluetoothUUID>(), properties, permissions, |
| 1147 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle])); |
| 1148 int32_t characteristic_handle = |
| 1149 CreateGattAttributeHandle(characteristic.get()); |
| 1150 last_characteristic_[service_handle] = characteristic_handle; |
| 1151 callback.Run(characteristic_handle); |
| 1152 } |
| 1103 | 1153 |
| 1104 void ArcBluetoothBridge::AddDescriptor(int32_t service_handle, | 1154 void ArcBluetoothBridge::AddDescriptor(int32_t service_handle, |
| 1105 mojom::BluetoothUUIDPtr uuid, | 1155 mojom::BluetoothUUIDPtr uuid, |
| 1106 int32_t permissions, | 1156 int32_t permissions, |
| 1107 const AddDescriptorCallback& callback) {} | 1157 const AddDescriptorCallback& callback) { |
| 1158 DCHECK(CalledOnValidThread()); |
| 1159 if (!IsGattServerAttributeHandleAvailable(1)) { |
| 1160 callback.Run(kInvalidGattAttributeHandle); |
| 1161 return; |
| 1162 } |
| 1163 // Chrome automatically adds a CCC Descriptor to a characteristic when needed. |
| 1164 // We will generate a bogus handle for Android. |
| 1165 if (uuid.To<BluetoothUUID>() == |
| 1166 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) { |
| 1167 int32_t handle = GetNextGattServerAttributeHandle(); |
| 1168 callback.Run(handle); |
| 1169 return; |
| 1170 } |
| 1171 |
| 1172 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1173 BluetoothLocalGattService* service = |
| 1174 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); |
| 1175 DCHECK(service); |
| 1176 // Since the Android API does not give information about which characteristic |
| 1177 // is the parent of the new descriptor, we assume that it would be the last |
| 1178 // characteristic that was added to the given service. This matches the |
| 1179 // Android framework code at android/bluetooth/BluetoothGattServer.java#594. |
| 1180 // Link: https://goo.gl/cJZl1u |
| 1181 DCHECK(last_characteristic_.find(service_handle) != |
| 1182 last_characteristic_.end()); |
| 1183 int32_t last_characteristic_handle = last_characteristic_[service_handle]; |
| 1184 |
| 1185 DCHECK(gatt_identifier_.find(last_characteristic_handle) != |
| 1186 gatt_identifier_.end()); |
| 1187 BluetoothLocalGattCharacteristic* characteristic = |
| 1188 service->GetCharacteristic(gatt_identifier_[last_characteristic_handle]); |
| 1189 DCHECK(characteristic); |
| 1190 |
| 1191 base::WeakPtr<BluetoothLocalGattDescriptor> descriptor = |
| 1192 BluetoothLocalGattDescriptor::Create(uuid.To<BluetoothUUID>(), |
| 1193 permissions, characteristic); |
| 1194 callback.Run(CreateGattAttributeHandle(descriptor.get())); |
| 1195 } |
| 1108 | 1196 |
| 1109 void ArcBluetoothBridge::StartService(int32_t service_handle, | 1197 void ArcBluetoothBridge::StartService(int32_t service_handle, |
| 1110 const StartServiceCallback& callback) {} | 1198 const StartServiceCallback& callback) { |
| 1199 DCHECK(CalledOnValidThread()); |
| 1200 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1201 BluetoothLocalGattService* service = |
| 1202 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); |
| 1203 DCHECK(service); |
| 1204 service->Register(base::Bind(&OnGattOperationDone, callback), |
| 1205 base::Bind(&OnGattOperationError, callback)); |
| 1206 } |
| 1111 | 1207 |
| 1112 void ArcBluetoothBridge::StopService(int32_t service_handle, | 1208 void ArcBluetoothBridge::StopService(int32_t service_handle, |
| 1113 const StopServiceCallback& callback) {} | 1209 const StopServiceCallback& callback) { |
| 1210 DCHECK(CalledOnValidThread()); |
| 1211 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1212 BluetoothLocalGattService* service = |
| 1213 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); |
| 1214 DCHECK(service); |
| 1215 service->Unregister(base::Bind(&OnGattOperationDone, callback), |
| 1216 base::Bind(&OnGattOperationError, callback)); |
| 1217 } |
| 1114 | 1218 |
| 1115 void ArcBluetoothBridge::DeleteService(int32_t service_handle, | 1219 void ArcBluetoothBridge::DeleteService(int32_t service_handle, |
| 1116 const DeleteServiceCallback& callback) {} | 1220 const DeleteServiceCallback& callback) { |
| 1221 DCHECK(CalledOnValidThread()); |
| 1222 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end()); |
| 1223 BluetoothLocalGattService* service = |
| 1224 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]); |
| 1225 DCHECK(service); |
| 1226 |
| 1227 service->Delete(); |
| 1228 gatt_identifier_.erase(service_handle); |
| 1229 OnGattOperationDone(callback); |
| 1230 } |
| 1117 | 1231 |
| 1118 void ArcBluetoothBridge::SendIndication( | 1232 void ArcBluetoothBridge::SendIndication( |
| 1119 int32_t attribute_handle, | 1233 int32_t attribute_handle, |
| 1120 mojom::BluetoothAddressPtr address, | 1234 mojom::BluetoothAddressPtr address, |
| 1121 bool confirm, | 1235 bool confirm, |
| 1122 mojo::Array<uint8_t> value, | 1236 mojo::Array<uint8_t> value, |
| 1123 const SendIndicationCallback& callback) {} | 1237 const SendIndicationCallback& callback) {} |
| 1124 | 1238 |
| 1125 void ArcBluetoothBridge::OnDiscoveryError() { | 1239 void ArcBluetoothBridge::OnDiscoveryError() { |
| 1126 LOG(WARNING) << "failed to change discovery state"; | 1240 LOG(WARNING) << "failed to change discovery state"; |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1452 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( | 1566 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( |
| 1453 uint32_t version_need) const { | 1567 uint32_t version_need) const { |
| 1454 uint32_t version = arc_bridge_service()->bluetooth()->version(); | 1568 uint32_t version = arc_bridge_service()->bluetooth()->version(); |
| 1455 if (version >= version_need) | 1569 if (version >= version_need) |
| 1456 return true; | 1570 return true; |
| 1457 LOG(WARNING) << "Bluetooth instance is too old (version " << version | 1571 LOG(WARNING) << "Bluetooth instance is too old (version " << version |
| 1458 << ") need version " << version_need; | 1572 << ") need version " << version_need; |
| 1459 return false; | 1573 return false; |
| 1460 } | 1574 } |
| 1461 | 1575 |
| 1576 bool ArcBluetoothBridge::CalledOnValidThread() { |
| 1577 return thread_checker_.CalledOnValidThread(); |
| 1578 } |
| 1579 |
| 1462 } // namespace arc | 1580 } // namespace arc |
| OLD | NEW |