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

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: rebase 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 <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
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
72 int ConvertGattIdentifierToId(const std::string identifier) {
73 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
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) {
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.
94 template <class RemoteGattAttribute>
95 RemoteGattAttribute* FindGattAttributeFromUuid(
96 const std::vector<RemoteGattAttribute*> gatt_attrs,
Luis Héctor Chávez 2016/07/20 23:11:04 should this be a const-reference?
puthik_chromium 2016/07/21 00:05:04 Done.
97 const device::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())
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 617 matching lines...) Expand 10 before | Expand all | Expand 10 after
736 callback, 819 callback,
737 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST); 820 BluetoothAdvertisement::ErrorCode::ERROR_ADVERTISEMENT_DOES_NOT_EXIST);
738 return; 821 return;
739 } 822 }
740 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone, 823 advertisment_->Unregister(base::Bind(&ArcBluetoothBridge::OnStopLEListenDone,
741 weak_factory_.GetWeakPtr(), callback), 824 weak_factory_.GetWeakPtr(), callback),
742 base::Bind(&ArcBluetoothBridge::OnStopLEListenError, 825 base::Bind(&ArcBluetoothBridge::OnStopLEListenError,
743 weak_factory_.GetWeakPtr(), callback)); 826 weak_factory_.GetWeakPtr(), callback));
744 } 827 }
745 828
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) { 829 void ArcBluetoothBridge::GetGattDB(mojom::BluetoothAddressPtr remote_addr) {
771 if (!HasBluetoothInstance()) 830 if (!HasBluetoothInstance())
772 return; 831 return;
773 832
774 BluetoothDevice* device = 833 BluetoothDevice* device =
775 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); 834 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
776 mojo::Array<mojom::BluetoothGattDBElementPtr> db; 835 mojo::Array<mojom::BluetoothGattDBElementPtr> db;
777 for (auto service : device->GetGattServices()) { 836 for (auto service : device->GetGattServices()) {
778 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement< 837 mojom::BluetoothGattDBElementPtr service_element = CreateGattDBElement<
779 device::BluetoothRemoteGattService>( 838 device::BluetoothRemoteGattService>(
(...skipping 26 matching lines...) Expand all
806 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR, 865 mojom::BluetoothGattDBAttributeType::BTGATT_DB_DESCRIPTOR,
807 descriptor)); 866 descriptor));
808 } 867 }
809 } 868 }
810 } 869 }
811 870
812 arc_bridge_service()->bluetooth()->instance()->OnGetGattDB( 871 arc_bridge_service()->bluetooth()->instance()->OnGetGattDB(
813 std::move(remote_addr), std::move(db)); 872 std::move(remote_addr), std::move(db));
814 } 873 }
815 874
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( 875 BluetoothRemoteGattCharacteristic* ArcBluetoothBridge::FindGattCharacteristic(
829 mojom::BluetoothAddressPtr remote_addr, 876 mojom::BluetoothAddressPtr remote_addr,
830 mojom::BluetoothGattServiceIDPtr service_id, 877 mojom::BluetoothGattServiceIDPtr service_id,
831 mojom::BluetoothGattIDPtr char_id) const { 878 mojom::BluetoothGattIDPtr char_id) const {
832 DCHECK(remote_addr); 879 DCHECK(remote_addr);
833 DCHECK(service_id); 880 DCHECK(service_id);
834 DCHECK(char_id); 881 DCHECK(char_id);
835 882
836 BluetoothDevice* device = 883 BluetoothDevice* device =
837 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); 884 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
838 if (!device) 885 if (!device)
839 return nullptr; 886 return nullptr;
840 887
841 BluetoothRemoteGattService* service = 888 BluetoothRemoteGattService* service =
842 FindGattObjectFromUuid<BluetoothRemoteGattService>( 889 FindGattAttributeFromUuid<BluetoothRemoteGattService>(
Luis Héctor Chávez 2016/07/20 23:11:04 nit: C++ might be able to autodeduce the template
puthik_chromium 2016/07/21 00:05:03 Done.
843 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>()); 890 device->GetGattServices(), service_id->id->uuid.To<BluetoothUUID>());
844 if (!service) 891 if (!service)
845 return nullptr; 892 return nullptr;
846 893
847 return FindGattObjectFromUuid<BluetoothRemoteGattCharacteristic>( 894 return FindGattAttributeFromUuid<BluetoothRemoteGattCharacteristic>(
848 service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>()); 895 service->GetCharacteristics(), char_id->uuid.To<BluetoothUUID>());
849 } 896 }
850 897
851 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor( 898 BluetoothRemoteGattDescriptor* ArcBluetoothBridge::FindGattDescriptor(
852 mojom::BluetoothAddressPtr remote_addr, 899 mojom::BluetoothAddressPtr remote_addr,
853 mojom::BluetoothGattServiceIDPtr service_id, 900 mojom::BluetoothGattServiceIDPtr service_id,
854 mojom::BluetoothGattIDPtr char_id, 901 mojom::BluetoothGattIDPtr char_id,
855 mojom::BluetoothGattIDPtr desc_id) const { 902 mojom::BluetoothGattIDPtr desc_id) const {
856 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( 903 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
857 std::move(remote_addr), std::move(service_id), std::move(char_id)); 904 std::move(remote_addr), std::move(service_id), std::move(char_id));
858 if (!characteristic) 905 if (!characteristic)
859 return nullptr; 906 return nullptr;
860 907
861 return FindGattObjectFromUuid<BluetoothRemoteGattDescriptor>( 908 return FindGattAttributeFromUuid<BluetoothRemoteGattDescriptor>(
862 characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>()); 909 characteristic->GetDescriptors(), desc_id->uuid.To<BluetoothUUID>());
863 } 910 }
864 911
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 }
896
897 void ArcBluetoothBridge::ReadGattCharacteristic( 912 void ArcBluetoothBridge::ReadGattCharacteristic(
898 mojom::BluetoothAddressPtr remote_addr, 913 mojom::BluetoothAddressPtr remote_addr,
899 mojom::BluetoothGattServiceIDPtr service_id, 914 mojom::BluetoothGattServiceIDPtr service_id,
900 mojom::BluetoothGattIDPtr char_id, 915 mojom::BluetoothGattIDPtr char_id,
901 const ReadGattCharacteristicCallback& callback) { 916 const ReadGattCharacteristicCallback& callback) {
902 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( 917 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
903 std::move(remote_addr), std::move(service_id), std::move(char_id)); 918 std::move(remote_addr), std::move(service_id), std::move(char_id));
904 DCHECK(characteristic); 919 DCHECK(characteristic);
905 DCHECK(characteristic->GetPermissions() & kGattReadPermission); 920 DCHECK(characteristic->GetPermissions() & kGattReadPermission);
906 921
907 characteristic->ReadRemoteCharacteristic( 922 characteristic->ReadRemoteCharacteristic(
908 base::Bind(&ArcBluetoothBridge::OnGattReadDone, 923 base::Bind(&OnGattReadDone, callback),
909 weak_factory_.GetWeakPtr(), callback), 924 base::Bind(&OnGattReadError, callback));
910 base::Bind(&ArcBluetoothBridge::OnGattReadError,
911 weak_factory_.GetWeakPtr(), callback));
912 } 925 }
913 926
914 void ArcBluetoothBridge::WriteGattCharacteristic( 927 void ArcBluetoothBridge::WriteGattCharacteristic(
915 mojom::BluetoothAddressPtr remote_addr, 928 mojom::BluetoothAddressPtr remote_addr,
916 mojom::BluetoothGattServiceIDPtr service_id, 929 mojom::BluetoothGattServiceIDPtr service_id,
917 mojom::BluetoothGattIDPtr char_id, 930 mojom::BluetoothGattIDPtr char_id,
918 mojom::BluetoothGattValuePtr value, 931 mojom::BluetoothGattValuePtr value,
919 const WriteGattCharacteristicCallback& callback) { 932 const WriteGattCharacteristicCallback& callback) {
920 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( 933 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
921 std::move(remote_addr), std::move(service_id), std::move(char_id)); 934 std::move(remote_addr), std::move(service_id), std::move(char_id));
922 DCHECK(characteristic); 935 DCHECK(characteristic);
923 DCHECK(characteristic->GetPermissions() & kGattWritePermission); 936 DCHECK(characteristic->GetPermissions() & kGattWritePermission);
924 937
925 characteristic->WriteRemoteCharacteristic( 938 characteristic->WriteRemoteCharacteristic(
926 value->value.To<std::vector<uint8_t>>(), 939 value->value.To<std::vector<uint8_t>>(),
927 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, 940 base::Bind(&OnGattOperationDone, callback),
928 weak_factory_.GetWeakPtr(), callback), 941 base::Bind(&OnGattOperationError, callback));
929 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
930 weak_factory_.GetWeakPtr(), callback));
931 } 942 }
932 943
933 void ArcBluetoothBridge::ReadGattDescriptor( 944 void ArcBluetoothBridge::ReadGattDescriptor(
934 mojom::BluetoothAddressPtr remote_addr, 945 mojom::BluetoothAddressPtr remote_addr,
935 mojom::BluetoothGattServiceIDPtr service_id, 946 mojom::BluetoothGattServiceIDPtr service_id,
936 mojom::BluetoothGattIDPtr char_id, 947 mojom::BluetoothGattIDPtr char_id,
937 mojom::BluetoothGattIDPtr desc_id, 948 mojom::BluetoothGattIDPtr desc_id,
938 const ReadGattDescriptorCallback& callback) { 949 const ReadGattDescriptorCallback& callback) {
939 BluetoothRemoteGattDescriptor* descriptor = 950 BluetoothRemoteGattDescriptor* descriptor =
940 FindGattDescriptor(std::move(remote_addr), std::move(service_id), 951 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
941 std::move(char_id), std::move(desc_id)); 952 std::move(char_id), std::move(desc_id));
942 DCHECK(descriptor); 953 DCHECK(descriptor);
943 DCHECK(descriptor->GetPermissions() & kGattReadPermission); 954 DCHECK(descriptor->GetPermissions() & kGattReadPermission);
944 955
945 descriptor->ReadRemoteDescriptor( 956 descriptor->ReadRemoteDescriptor(base::Bind(&OnGattReadDone, callback),
946 base::Bind(&ArcBluetoothBridge::OnGattReadDone, 957 base::Bind(&OnGattReadError, callback));
947 weak_factory_.GetWeakPtr(), callback),
948 base::Bind(&ArcBluetoothBridge::OnGattReadError,
949 weak_factory_.GetWeakPtr(), callback));
950 } 958 }
951 959
952 void ArcBluetoothBridge::WriteGattDescriptor( 960 void ArcBluetoothBridge::WriteGattDescriptor(
953 mojom::BluetoothAddressPtr remote_addr, 961 mojom::BluetoothAddressPtr remote_addr,
954 mojom::BluetoothGattServiceIDPtr service_id, 962 mojom::BluetoothGattServiceIDPtr service_id,
955 mojom::BluetoothGattIDPtr char_id, 963 mojom::BluetoothGattIDPtr char_id,
956 mojom::BluetoothGattIDPtr desc_id, 964 mojom::BluetoothGattIDPtr desc_id,
957 mojom::BluetoothGattValuePtr value, 965 mojom::BluetoothGattValuePtr value,
958 const WriteGattDescriptorCallback& callback) { 966 const WriteGattDescriptorCallback& callback) {
959 BluetoothRemoteGattDescriptor* descriptor = 967 BluetoothRemoteGattDescriptor* descriptor =
960 FindGattDescriptor(std::move(remote_addr), std::move(service_id), 968 FindGattDescriptor(std::move(remote_addr), std::move(service_id),
961 std::move(char_id), std::move(desc_id)); 969 std::move(char_id), std::move(desc_id));
962 DCHECK(descriptor); 970 DCHECK(descriptor);
963 DCHECK(descriptor->GetPermissions() & kGattWritePermission); 971 DCHECK(descriptor->GetPermissions() & kGattWritePermission);
964 972
965 // To register / deregister GATT notification, we need to 973 // To register / deregister GATT notification, we need to
966 // 1) Write to CCC Descriptor to enable/disable the notification 974 // 1) Write to CCC Descriptor to enable/disable the notification
967 // 2) Ask BT hw to register / deregister the notification 975 // 2) Ask BT hw to register / deregister the notification
968 // The Chrome API groups both steps into one API, and does not support writing 976 // The Chrome API groups both steps into one API, and does not support writing
969 // directly to the CCC Descriptor. Therefore, until we fix 977 // directly to the CCC Descriptor. Therefore, until we fix
970 // https://crbug.com/622832, we return successfully when we encounter this. 978 // https://crbug.com/622832, we return successfully when we encounter this.
971 // TODO(http://crbug.com/622832) 979 // TODO(http://crbug.com/622832)
972 if (descriptor->GetUUID() == 980 if (descriptor->GetUUID() ==
973 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) { 981 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) {
974 OnGattWriteDone(callback); 982 OnGattOperationDone(callback);
975 return; 983 return;
976 } 984 }
977 985
978 descriptor->WriteRemoteDescriptor( 986 descriptor->WriteRemoteDescriptor(
979 value->value.To<std::vector<uint8_t>>(), 987 value->value.To<std::vector<uint8_t>>(),
980 base::Bind(&ArcBluetoothBridge::OnGattWriteDone, 988 base::Bind(&OnGattOperationDone, callback),
981 weak_factory_.GetWeakPtr(), callback), 989 base::Bind(&OnGattOperationError, callback));
982 base::Bind(&ArcBluetoothBridge::OnGattWriteError,
983 weak_factory_.GetWeakPtr(), callback));
984 } 990 }
985 991
986 void ArcBluetoothBridge::OnGattNotifyStartDone( 992 void ArcBluetoothBridge::OnGattNotifyStartDone(
987 const RegisterForGattNotificationCallback& callback, 993 const RegisterForGattNotificationCallback& callback,
988 const std::string char_string_id, 994 const std::string char_string_id,
989 std::unique_ptr<BluetoothGattNotifySession> notify_session) { 995 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
990 notification_session_[char_string_id] = std::move(notify_session); 996 notification_session_[char_string_id] = std::move(notify_session);
991 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); 997 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
992 } 998 }
993 999
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( 1000 void ArcBluetoothBridge::RegisterForGattNotification(
1006 mojom::BluetoothAddressPtr remote_addr, 1001 mojom::BluetoothAddressPtr remote_addr,
1007 mojom::BluetoothGattServiceIDPtr service_id, 1002 mojom::BluetoothGattServiceIDPtr service_id,
1008 mojom::BluetoothGattIDPtr char_id, 1003 mojom::BluetoothGattIDPtr char_id,
1009 const RegisterForGattNotificationCallback& callback) { 1004 const RegisterForGattNotificationCallback& callback) {
1010 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( 1005 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
1011 std::move(remote_addr), std::move(service_id), std::move(char_id)); 1006 std::move(remote_addr), std::move(service_id), std::move(char_id));
1012 1007
1013 if (!characteristic) { 1008 if (!characteristic) {
1014 LOG(WARNING) << __func__ << " Characteristic is not existed."; 1009 LOG(WARNING) << __func__ << " Characteristic is not existed.";
1015 return; 1010 return;
1016 } 1011 }
1017 1012
1018 if (characteristic->IsNotifying()) { 1013 if (characteristic->IsNotifying()) {
1019 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); 1014 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1020 return; 1015 return;
1021 } 1016 }
1022 1017
1023 characteristic->StartNotifySession( 1018 characteristic->StartNotifySession(
1024 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone, 1019 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartDone,
1025 weak_factory_.GetWeakPtr(), callback, 1020 weak_factory_.GetWeakPtr(), callback,
1026 characteristic->GetIdentifier()), 1021 characteristic->GetIdentifier()),
1027 base::Bind(&ArcBluetoothBridge::OnGattNotifyStartError, 1022 base::Bind(&OnGattOperationError, callback));
1028 weak_factory_.GetWeakPtr(), callback));
1029 } 1023 }
1030 1024
1031 void ArcBluetoothBridge::DeregisterForGattNotification( 1025 void ArcBluetoothBridge::DeregisterForGattNotification(
1032 mojom::BluetoothAddressPtr remote_addr, 1026 mojom::BluetoothAddressPtr remote_addr,
1033 mojom::BluetoothGattServiceIDPtr service_id, 1027 mojom::BluetoothGattServiceIDPtr service_id,
1034 mojom::BluetoothGattIDPtr char_id, 1028 mojom::BluetoothGattIDPtr char_id,
1035 const DeregisterForGattNotificationCallback& callback) { 1029 const DeregisterForGattNotificationCallback& callback) {
1036 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic( 1030 BluetoothRemoteGattCharacteristic* characteristic = FindGattCharacteristic(
1037 std::move(remote_addr), std::move(service_id), std::move(char_id)); 1031 std::move(remote_addr), std::move(service_id), std::move(char_id));
1038 1032
1039 if (!characteristic) { 1033 if (!characteristic) {
1040 LOG(WARNING) << __func__ << " Characteristic is not existed."; 1034 LOG(WARNING) << __func__ << " Characteristic is not existed.";
1041 return; 1035 return;
1042 } 1036 }
1043 1037
1044 if (!characteristic->IsNotifying()) { 1038 if (!characteristic->IsNotifying()) {
1045 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS); 1039 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1046 return; 1040 return;
1047 } 1041 }
1048 1042
1049 std::string char_id_str = characteristic->GetIdentifier(); 1043 std::string char_id_str = characteristic->GetIdentifier();
1050 std::unique_ptr<BluetoothGattNotifySession> notify = 1044 std::unique_ptr<BluetoothGattNotifySession> notify =
1051 std::move(notification_session_[char_id_str]); 1045 std::move(notification_session_[char_id_str]);
1052 notification_session_.erase(char_id_str); 1046 notification_session_.erase(char_id_str);
1053 notify->Stop(base::Bind(&ArcBluetoothBridge::OnGattNotifyStopDone, 1047 notify->Stop(base::Bind(&OnGattOperationDone, callback));
1054 weak_factory_.GetWeakPtr(), callback));
1055 } 1048 }
1056 1049
1057 void ArcBluetoothBridge::ReadRemoteRssi( 1050 void ArcBluetoothBridge::ReadRemoteRssi(
1058 mojom::BluetoothAddressPtr remote_addr, 1051 mojom::BluetoothAddressPtr remote_addr,
1059 const ReadRemoteRssiCallback& callback) { 1052 const ReadRemoteRssiCallback& callback) {
1060 BluetoothDevice* device = 1053 BluetoothDevice* device =
1061 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); 1054 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1062 int rssi = device->GetInquiryRSSI(); 1055 int rssi = device->GetInquiryRSSI();
1063 callback.Run(rssi); 1056 callback.Run(rssi);
1064 } 1057 }
1065 1058
1059 template <class LocalGattAttribute>
1060 int32_t ArcBluetoothBridge::CreateGattAttributeHandle(
1061 LocalGattAttribute* gatt_attr) {
1062 DCHECK(CalledOnValidThread());
1063 if (!gatt_attr)
1064 return kInvalidGattAttributeHandle;
1065 int32_t handle = next_gatt_server_attribute_handle();
1066 const std::string& identifier = gatt_attr->GetIdentifier();
1067 gatt_identifier_[handle] = identifier;
1068 return handle;
1069 }
1070
1066 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id, 1071 void ArcBluetoothBridge::AddService(mojom::BluetoothGattServiceIDPtr service_id,
1067 int32_t num_handles, 1072 int32_t num_handles,
1068 const AddServiceCallback& callback) {} 1073 const AddServiceCallback& callback) {
1074 base::WeakPtr<BluetoothLocalGattService> service =
1075 BluetoothLocalGattService::Create(
1076 bluetooth_adapter_.get(), service_id->id->uuid.To<BluetoothUUID>(),
1077 service_id->is_primary, nullptr /*included_service */,
Luis Héctor Chávez 2016/07/20 23:11:04 nit: /* included service */
puthik_chromium 2016/07/21 00:05:04 Done.
1078 this /* delegate*/);
1079 callback.Run(
1080 CreateGattAttributeHandle<BluetoothLocalGattService>(service.get()));
Luis Héctor Chávez 2016/07/20 23:11:04 This (and all other uses of CreateGattAttributeHan
puthik_chromium 2016/07/21 00:05:04 Done.
1081 }
1069 1082
1070 void ArcBluetoothBridge::AddCharacteristic( 1083 void ArcBluetoothBridge::AddCharacteristic(
1071 int32_t service_handle, 1084 int32_t service_handle,
1072 mojom::BluetoothUUIDPtr uuid, 1085 mojom::BluetoothUUIDPtr uuid,
1073 int32_t properties, 1086 int32_t properties,
1074 int32_t permissions, 1087 int32_t permissions,
1075 const AddCharacteristicCallback& callback) {} 1088 const AddCharacteristicCallback& callback) {
1089 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
1090 base::WeakPtr<BluetoothLocalGattCharacteristic> characteristic =
1091 BluetoothLocalGattCharacteristic::Create(
1092 uuid.To<BluetoothUUID>(), properties, permissions,
1093 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]));
1094 int32_t characteristic_handle =
1095 CreateGattAttributeHandle<BluetoothLocalGattCharacteristic>(
1096 characteristic.get());
1097 last_characteristic_[service_handle] = characteristic_handle;
1098 callback.Run(characteristic_handle);
1099 }
1076 1100
1077 void ArcBluetoothBridge::AddDescriptor(int32_t service_handle, 1101 void ArcBluetoothBridge::AddDescriptor(int32_t service_handle,
1078 mojom::BluetoothUUIDPtr uuid, 1102 mojom::BluetoothUUIDPtr uuid,
1079 int32_t permissions, 1103 int32_t permissions,
1080 const AddDescriptorCallback& callback) {} 1104 const AddDescriptorCallback& callback) {
1105 // Chrome automatically adds a CCC Descriptor to a characteristic when needed.
1106 // We will generate a bogus handle for Android.
1107 if (uuid.To<BluetoothUUID>() ==
1108 BluetoothGattDescriptor::ClientCharacteristicConfigurationUuid()) {
1109 int32_t handle = next_gatt_server_attribute_handle();
1110 callback.Run(handle);
1111 return;
1112 }
1113
1114 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
1115 BluetoothLocalGattService* service =
1116 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
1117 DCHECK(service);
1118 // Since the Android API does not give information about which characteristic
1119 // is the parent of the new descriptor, we assume that it would be the last
1120 // characteristic that was added to the given service. This matches the
1121 // Android framework code at android/bluetooth/BluetoothGattServer.java#594.
1122 // Link: https://goo.gl/cJZl1u
1123 DCHECK(last_characteristic_.find(service_handle) !=
1124 last_characteristic_.end());
1125 int32_t last_characteristic_handle = last_characteristic_[service_handle];
1126
1127 DCHECK(gatt_identifier_.find(last_characteristic_handle) !=
1128 gatt_identifier_.end());
1129 BluetoothLocalGattCharacteristic* characteristic =
1130 service->GetCharacteristic(gatt_identifier_[last_characteristic_handle]);
1131 DCHECK(characteristic);
1132
1133 base::WeakPtr<BluetoothLocalGattDescriptor> descriptor =
1134 BluetoothLocalGattDescriptor::Create(uuid.To<BluetoothUUID>(),
1135 permissions, characteristic);
1136 callback.Run(CreateGattAttributeHandle<BluetoothLocalGattDescriptor>(
1137 descriptor.get()));
1138 }
1081 1139
1082 void ArcBluetoothBridge::StartService(int32_t service_handle, 1140 void ArcBluetoothBridge::StartService(int32_t service_handle,
1083 const StartServiceCallback& callback) {} 1141 const StartServiceCallback& callback) {
1142 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
1143 BluetoothLocalGattService* service =
1144 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
1145 DCHECK(service);
1146 service->Register(base::Bind(&OnGattOperationDone, callback),
1147 base::Bind(&OnGattOperationError, callback));
1148 }
1084 1149
1085 void ArcBluetoothBridge::StopService(int32_t service_handle, 1150 void ArcBluetoothBridge::StopService(int32_t service_handle,
1086 const StopServiceCallback& callback) {} 1151 const StopServiceCallback& callback) {
1152 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
1153 BluetoothLocalGattService* service =
1154 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
1155 DCHECK(service);
1156 service->Unregister(base::Bind(&OnGattOperationDone, callback),
1157 base::Bind(&OnGattOperationError, callback));
1158 }
1087 1159
1088 void ArcBluetoothBridge::DeleteService(int32_t service_handle, 1160 void ArcBluetoothBridge::DeleteService(int32_t service_handle,
1089 const DeleteServiceCallback& callback) {} 1161 const DeleteServiceCallback& callback) {
1162 DCHECK(gatt_identifier_.find(service_handle) != gatt_identifier_.end());
Luis Héctor Chávez 2016/07/20 23:11:04 Just for my peace of mind, can you add thread-chec
puthik_chromium 2016/07/21 00:05:04 Done.
1163 BluetoothLocalGattService* service =
1164 bluetooth_adapter_->GetGattService(gatt_identifier_[service_handle]);
1165 DCHECK(service);
1166
1167 service->Delete();
1168 gatt_identifier_.erase(service_handle);
1169 OnGattOperationDone(callback);
1170 }
1090 1171
1091 void ArcBluetoothBridge::SendIndication( 1172 void ArcBluetoothBridge::SendIndication(
1092 int32_t attribute_handle, 1173 int32_t attribute_handle,
1093 mojom::BluetoothAddressPtr address, 1174 mojom::BluetoothAddressPtr address,
1094 bool confirm, 1175 bool confirm,
1095 mojo::Array<uint8_t> value, 1176 mojo::Array<uint8_t> value,
1096 const SendIndicationCallback& callback) {} 1177 const SendIndicationCallback& callback) {}
1097 1178
1098 void ArcBluetoothBridge::OnDiscoveryError() { 1179 void ArcBluetoothBridge::OnDiscoveryError() {
1099 LOG(WARNING) << "failed to change discovery state"; 1180 LOG(WARNING) << "failed to change discovery state";
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( 1506 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
1426 uint32_t version_need) const { 1507 uint32_t version_need) const {
1427 uint32_t version = arc_bridge_service()->bluetooth()->version(); 1508 uint32_t version = arc_bridge_service()->bluetooth()->version();
1428 if (version >= version_need) 1509 if (version >= version_need)
1429 return true; 1510 return true;
1430 LOG(WARNING) << "Bluetooth instance is too old (version " << version 1511 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1431 << ") need version " << version_need; 1512 << ") need version " << version_need;
1432 return false; 1513 return false;
1433 } 1514 }
1434 1515
1516 bool ArcBluetoothBridge::CalledOnValidThread() {
1517 return thread_checker_.CalledOnValidThread();
1518 }
1519
1435 } // namespace arc 1520 } // 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