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

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

Issue 2104043002: arc: bluetooth: Implement Gatt Server add/delete/start/stop service (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gs1
Patch Set: Address Palmer comment. Add max handle. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/arc/bluetooth/arc_bluetooth_bridge.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h"
6 6
7 #include <bluetooth/bluetooth.h> 7 #include <bluetooth/bluetooth.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« no previous file with comments | « components/arc/bluetooth/arc_bluetooth_bridge.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698