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

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

Issue 2149713002: arc: bluetooth: Add SDP host side support (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Change GetSdpRecords() to be async and add OnGetSdpRecords() to BluetoothInstance interface Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h" 5 #include "components/arc/bluetooth/arc_bluetooth_bridge.h"
6 6
7 #include <bluetooth/bluetooth.h> 7 #include <bluetooth/bluetooth.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <sys/socket.h> 10 #include <sys/socket.h>
(...skipping 10 matching lines...) Expand all
21 #include "base/threading/thread_task_runner_handle.h" 21 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h" 22 #include "base/time/time.h"
23 #include "components/arc/arc_bridge_service.h" 23 #include "components/arc/arc_bridge_service.h"
24 #include "components/arc/bluetooth/bluetooth_type_converters.h" 24 #include "components/arc/bluetooth/bluetooth_type_converters.h"
25 #include "device/bluetooth/bluetooth_common.h" 25 #include "device/bluetooth/bluetooth_common.h"
26 #include "device/bluetooth/bluetooth_device.h" 26 #include "device/bluetooth/bluetooth_device.h"
27 #include "device/bluetooth/bluetooth_gatt_connection.h" 27 #include "device/bluetooth/bluetooth_gatt_connection.h"
28 #include "device/bluetooth/bluetooth_gatt_notify_session.h" 28 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
29 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h" 29 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
30 #include "device/bluetooth/bluetooth_local_gatt_descriptor.h" 30 #include "device/bluetooth/bluetooth_local_gatt_descriptor.h"
31 #include "device/bluetooth/bluez/bluetooth_device_bluez.h"
31 #include "mojo/edk/embedder/embedder.h" 32 #include "mojo/edk/embedder/embedder.h"
32 #include "mojo/edk/embedder/scoped_platform_handle.h" 33 #include "mojo/edk/embedder/scoped_platform_handle.h"
33 34
34 using device::BluetoothAdapter; 35 using device::BluetoothAdapter;
35 using device::BluetoothAdapterFactory; 36 using device::BluetoothAdapterFactory;
36 using device::BluetoothAdvertisement; 37 using device::BluetoothAdvertisement;
37 using device::BluetoothDevice; 38 using device::BluetoothDevice;
38 using device::BluetoothDiscoveryFilter; 39 using device::BluetoothDiscoveryFilter;
39 using device::BluetoothDiscoverySession; 40 using device::BluetoothDiscoverySession;
40 using device::BluetoothGattConnection; 41 using device::BluetoothGattConnection;
(...skipping 24 matching lines...) Expand all
65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | 66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
66 BluetoothGattCharacteristic::Permission:: 67 BluetoothGattCharacteristic::Permission::
67 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; 68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
68 constexpr int32_t kInvalidGattAttributeHandle = -1; 69 constexpr int32_t kInvalidGattAttributeHandle = -1;
69 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 70 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2
70 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. 71 // An attribute handle of value 0xFFFF is known as the maximum attribute handle.
71 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; 72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF;
72 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9
73 // The maximum length of an attribute value shall be 512 octets. 74 // The maximum length of an attribute value shall be 512 octets.
74 constexpr int kMaxGattAttributeLength = 512; 75 constexpr int kMaxGattAttributeLength = 512;
76 // Bluetooth SDP Service Class ID List Attribute identifier
77 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001;
75 78
76 using GattStatusCallback = 79 using GattStatusCallback =
77 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 80 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
78 using GattReadCallback = 81 using GattReadCallback =
79 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 82 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
83 using CreateSdpRecordCallback =
84 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>;
85 using RemoveSdpRecordCallback =
86 base::Callback<void(arc::mojom::BluetoothStatus)>;
80 87
81 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a 88 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
82 // Convert the last 4 characters of |identifier| to an 89 // Convert the last 4 characters of |identifier| to an
83 // int, by interpreting them as hexadecimal digits. 90 // int, by interpreting them as hexadecimal digits.
84 int ConvertGattIdentifierToId(const std::string identifier) { 91 int ConvertGattIdentifierToId(const std::string identifier) {
85 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); 92 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
86 } 93 }
87 94
88 // Create GattDBElement and fill in common data for 95 // Create GattDBElement and fill in common data for
89 // Gatt Service/Characteristic/Descriptor. 96 // Gatt Service/Characteristic/Descriptor.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
166 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS) 173 if (status == arc::mojom::BluetoothGattStatus::GATT_SUCCESS)
167 success_callback.Run(); 174 success_callback.Run();
168 else 175 else
169 error_callback.Run(); 176 error_callback.Run();
170 } 177 }
171 178
172 bool IsGattOffsetValid(int offset) { 179 bool IsGattOffsetValid(int offset) {
173 return 0 <= offset && offset < kMaxGattAttributeLength; 180 return 0 <= offset && offset < kMaxGattAttributeLength;
174 } 181 }
175 182
183 void OnCreateServiceRecordDone(
184 const CreateSdpRecordCallback& callback,
185 uint32_t service_handle) {
186 arc::mojom::BluetoothCreateSdpRecordResultPtr result =
187 arc::mojom::BluetoothCreateSdpRecordResult::New();
188 result->status = arc::mojom::BluetoothStatus::SUCCESS;
189 result->service_handle = service_handle;
190
191 callback.Run(std::move(result));
192 }
193
194 void OnCreateServiceRecordError(
195 const CreateSdpRecordCallback& callback,
196 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
197 arc::mojom::BluetoothCreateSdpRecordResultPtr result =
198 arc::mojom::BluetoothCreateSdpRecordResult::New();
199 if (error_code ==
200 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY)
201 result->status = arc::mojom::BluetoothStatus::NOT_READY;
202 else
203 result->status = arc::mojom::BluetoothStatus::FAIL;
204
205 callback.Run(std::move(result));
206 }
207
208 void OnRemoveServiceRecordDone(
209 const RemoveSdpRecordCallback& callback) {
210 callback.Run(arc::mojom::BluetoothStatus::SUCCESS);
211 }
212
213 void OnRemoveServiceRecordError(
214 const RemoveSdpRecordCallback& callback,
215 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
216 arc::mojom::BluetoothStatus status;
217 if (error_code ==
218 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY)
219 status = arc::mojom::BluetoothStatus::NOT_READY;
220 else
221 status = arc::mojom::BluetoothStatus::FAIL;
222
223 callback.Run(status);
224 }
225
176 } // namespace 226 } // namespace
177 227
178 namespace arc { 228 namespace arc {
179 229
180 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) 230 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
181 : ArcService(bridge_service), binding_(this), weak_factory_(this) { 231 : ArcService(bridge_service), binding_(this), weak_factory_(this) {
182 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { 232 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
183 VLOG(1) << "registering bluetooth adapter"; 233 VLOG(1) << "registering bluetooth adapter";
184 BluetoothAdapterFactory::GetAdapter(base::Bind( 234 BluetoothAdapterFactory::GetAdapter(base::Bind(
185 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); 235 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
801 BluetoothDevice* device = 851 BluetoothDevice* device =
802 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); 852 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
803 DCHECK(device); 853 DCHECK(device);
804 854
805 if (device->IsConnected()) { 855 if (device->IsConnected()) {
806 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( 856 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange(
807 std::move(remote_addr), true); 857 std::move(remote_addr), true);
808 return; 858 return;
809 } 859 }
810 860
811 // Also pass disconnect callback in error case 861 // Also pass disconnect callback in error case since it would be disconnected
812 // since it would be disconnected anyway. 862 // anyway.
813 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); 863 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
814 device->CreateGattConnection( 864 device->CreateGattConnection(
815 base::Bind(&ArcBluetoothBridge::OnGattConnected, 865 base::Bind(&ArcBluetoothBridge::OnGattConnected,
816 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), 866 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
817 base::Bind(&ArcBluetoothBridge::OnGattConnectError, 867 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
818 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); 868 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
819 } 869 }
820 870
821 void ArcBluetoothBridge::DisconnectLEDevice( 871 void ArcBluetoothBridge::DisconnectLEDevice(
822 mojom::BluetoothAddressPtr remote_addr) { 872 mojom::BluetoothAddressPtr remote_addr) {
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1300 OnGattOperationDone(callback); 1350 OnGattOperationDone(callback);
1301 } 1351 }
1302 1352
1303 void ArcBluetoothBridge::SendIndication( 1353 void ArcBluetoothBridge::SendIndication(
1304 int32_t attribute_handle, 1354 int32_t attribute_handle,
1305 mojom::BluetoothAddressPtr address, 1355 mojom::BluetoothAddressPtr address,
1306 bool confirm, 1356 bool confirm,
1307 mojo::Array<uint8_t> value, 1357 mojo::Array<uint8_t> value,
1308 const SendIndicationCallback& callback) {} 1358 const SendIndicationCallback& callback) {}
1309 1359
1360 void ArcBluetoothBridge::GetSdpRecords(
1361 mojom::BluetoothAddressPtr remote_addr,
1362 mojom::BluetoothUUIDPtr target_uuid) {
1363 BluetoothDevice* device =
1364 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1365
1366 // Do an early return if there is no device with |remote_addr|.
1367 if (!device) {
1368 OnGetServiceRecordsError(std::move(remote_addr), std::move(target_uuid),
1369 bluez::BluetoothServiceRecordBlueZ::ErrorCode::
1370 ERROR_DEVICE_DISCONNECTED);
1371 return;
1372 }
1373
1374 bluez::BluetoothDeviceBlueZ* device_bluez =
rickyz (no longer on Chrome) 2016/08/16 23:55:07 Is it documented anywhere that GetDevice always re
Miao 2016/08/17 14:30:19 https://cs.chromium.org/chromium/src/device/blueto
rickyz (no longer on Chrome) 2016/08/17 18:54:54 I understand that this needs to be casted to acces
rkc 2016/08/17 19:16:13 I am unsure of what you're looking for exactly but
rickyz (no longer on Chrome) 2016/08/17 19:32:26 Sure, even better would be if this assumption coul
1375 static_cast<bluez::BluetoothDeviceBlueZ*>(device);
1376
1377 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
1378 mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone();
1379
1380 device_bluez->GetServiceRecords(
1381 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone,
1382 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr),
1383 base::Passed(&target_uuid)),
1384 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError,
1385 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone),
1386 base::Passed(&target_uuid_clone)));
1387 }
1388
1389 void ArcBluetoothBridge::CreateSdpRecord(
1390 mojom::BluetoothSdpRecordPtr record,
1391 const CreateSdpRecordCallback& callback) {
1392 bluez::BluetoothServiceRecordBlueZ rcd_bluez(
1393 mojo::ConvertTo<bluez::BluetoothServiceRecordBlueZ>(record));
1394
1395 std::vector<uint16_t> v = rcd_bluez.GetAttributeIds();
1396
1397 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included
1398 // after type conversion, since it is mandatory for creating a service record.
1399 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) ==
1400 v.end()) {
1401 mojom::BluetoothCreateSdpRecordResultPtr result =
1402 mojom::BluetoothCreateSdpRecordResult::New();
1403 result->status = mojom::BluetoothStatus::FAIL;
1404 callback.Run(std::move(result));
1405 return;
1406 }
1407
1408 bluetooth_adapter_->CreateServiceRecord(
1409 rcd_bluez, base::Bind(&OnCreateServiceRecordDone, callback),
1410 base::Bind(&OnCreateServiceRecordError, callback));
1411 }
1412
1413 void ArcBluetoothBridge::RemoveSdpRecord(
1414 uint32_t service_handle,
1415 const RemoveSdpRecordCallback& callback) {
1416 bluetooth_adapter_->RemoveServiceRecord(
1417 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback),
1418 base::Bind(&OnRemoveServiceRecordError, callback));
1419 }
1420
1310 void ArcBluetoothBridge::OnDiscoveryError() { 1421 void ArcBluetoothBridge::OnDiscoveryError() {
1311 LOG(WARNING) << "failed to change discovery state"; 1422 LOG(WARNING) << "failed to change discovery state";
1312 } 1423 }
1313 1424
1314 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1425 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1315 if (!HasBluetoothInstance()) 1426 if (!HasBluetoothInstance())
1316 return; 1427 return;
1317 1428
1318 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1429 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1319 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1430 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1616 1727
1617 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { 1728 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) {
1618 int rssi = device->GetInquiryRSSI(); 1729 int rssi = device->GetInquiryRSSI();
1619 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = 1730 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1620 GetAdvertisingData(device); 1731 GetAdvertisingData(device);
1621 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( 1732 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound(
1622 addr->Clone(), rssi, std::move(adv_data)); 1733 addr->Clone(), rssi, std::move(adv_data));
1623 } 1734 }
1624 1735
1625 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1736 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
1626 // to 1737 // to make sure the bond state machine on Android is ready to take the
1627 // make sure the bond state machine on Android is ready to take the
1628 // pair-done event. Otherwise the pair-done event will be dropped as an 1738 // pair-done event. Otherwise the pair-done event will be dropped as an
1629 // invalid change of paired status. 1739 // invalid change of paired status.
1630 OnPairing(addr->Clone()); 1740 OnPairing(addr->Clone());
1631 OnPairedDone(std::move(addr)); 1741 OnPairedDone(std::move(addr));
1632 } 1742 }
1633 } 1743 }
1634 1744
1745 void ArcBluetoothBridge::OnGetServiceRecordsDone(
1746 mojom::BluetoothAddressPtr remote_addr,
1747 mojom::BluetoothUUIDPtr target_uuid,
1748 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records) {
1749 mojo::Array<mojom::BluetoothSdpRecordPtr> rcds;
Luis Héctor Chávez 2016/08/16 15:56:03 nit: Try not to abbreviate. Same in all places you
Miao 2016/08/17 14:30:19 Done.
1750 for (auto& rcd : records)
1751 rcds.push_back(mojo::ConvertTo<mojom::BluetoothSdpRecordPtr>(rcd));
1752
1753 if (!HasBluetoothInstance())
Luis Héctor Chávez 2016/08/16 15:56:03 nit: move to beginning to avoid the allocation if
Miao 2016/08/17 14:30:19 Done.
1754 return;
1755
1756 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
1757 mojom::BluetoothStatus::SUCCESS, std::move(remote_addr),
1758 std::move(target_uuid), std::move(rcds));
1759 }
1760
1761 void ArcBluetoothBridge::OnGetServiceRecordsError(
1762 mojom::BluetoothAddressPtr remote_addr,
1763 mojom::BluetoothUUIDPtr target_uuid,
1764 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
1765 mojom::BluetoothStatus status;
1766
1767 switch (error_code) {
1768 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY:
1769 status = mojom::BluetoothStatus::NOT_READY;
1770 break;
1771 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::
1772 ERROR_DEVICE_DISCONNECTED:
1773 status = mojom::BluetoothStatus::RMT_DEV_DOWN;
1774 break;
1775 default:
1776 status = mojom::BluetoothStatus::FAIL;
1777 break;
1778 }
1779
1780 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
1781 status, std::move(remote_addr), std::move(target_uuid),
1782 mojo::Array<mojom::BluetoothSdpRecordPtr>());
1783 }
1784
1635 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( 1785 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
1636 uint32_t version_need) const { 1786 uint32_t version_need) const {
1637 uint32_t version = arc_bridge_service()->bluetooth()->version(); 1787 uint32_t version = arc_bridge_service()->bluetooth()->version();
1638 if (version >= version_need) 1788 if (version >= version_need)
1639 return true; 1789 return true;
1640 LOG(WARNING) << "Bluetooth instance is too old (version " << version 1790 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1641 << ") need version " << version_need; 1791 << ") need version " << version_need;
1642 return false; 1792 return false;
1643 } 1793 }
1644 1794
1645 bool ArcBluetoothBridge::CalledOnValidThread() { 1795 bool ArcBluetoothBridge::CalledOnValidThread() {
1646 return thread_checker_.CalledOnValidThread(); 1796 return thread_checker_.CalledOnValidThread();
1647 } 1797 }
1648 1798
1649 } // namespace arc 1799 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698