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