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

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: Rewind to the previous approach using generic attribute and type converter Created 4 years, 3 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 29 matching lines...) Expand all
70 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 71 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2
71 // An attribute handle of value 0xFFFF is known as the maximum attribute handle. 72 // An attribute handle of value 0xFFFF is known as the maximum attribute handle.
72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; 73 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF;
73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 74 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9
74 // The maximum length of an attribute value shall be 512 octets. 75 // The maximum length of an attribute value shall be 512 octets.
75 constexpr int kMaxGattAttributeLength = 512; 76 constexpr int kMaxGattAttributeLength = 512;
76 // Copied from Android at system/bt/stack/btm/btm_ble_int.h 77 // Copied from Android at system/bt/stack/btm/btm_ble_int.h
77 // https://goo.gl/k7PM6u 78 // https://goo.gl/k7PM6u
78 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; 79 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95;
79 constexpr uint16_t kMaxAdvertisement = 5; 80 constexpr uint16_t kMaxAdvertisement = 5;
81 // Bluetooth SDP Service Class ID List Attribute identifier
82 constexpr uint16_t kServiceClassIDListAttributeID = 0x0001;
80 83
81 using GattStatusCallback = 84 using GattStatusCallback =
82 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 85 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
83 using GattReadCallback = 86 using GattReadCallback =
84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 87 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
88 using CreateSdpRecordCallback =
89 base::Callback<void(arc::mojom::BluetoothCreateSdpRecordResultPtr)>;
90 using RemoveSdpRecordCallback =
91 base::Callback<void(arc::mojom::BluetoothStatus)>;
85 92
86 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a 93 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
87 // Convert the last 4 characters of |identifier| to an 94 // Convert the last 4 characters of |identifier| to an
88 // int, by interpreting them as hexadecimal digits. 95 // int, by interpreting them as hexadecimal digits.
89 int ConvertGattIdentifierToId(const std::string identifier) { 96 int ConvertGattIdentifierToId(const std::string identifier) {
90 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16); 97 return std::stoi(identifier.substr(identifier.size() - 4), nullptr, 16);
91 } 98 }
92 99
93 // Create GattDBElement and fill in common data for 100 // Create GattDBElement and fill in common data for
94 // Gatt Service/Characteristic/Descriptor. 101 // Gatt Service/Characteristic/Descriptor.
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 bool IsGattOffsetValid(int offset) { 184 bool IsGattOffsetValid(int offset) {
178 return 0 <= offset && offset < kMaxGattAttributeLength; 185 return 0 <= offset && offset < kMaxGattAttributeLength;
179 } 186 }
180 187
181 // This is needed because Android only support UUID 16 bits in advertising data. 188 // This is needed because Android only support UUID 16 bits in advertising data.
182 uint16_t GetUUID16(const BluetoothUUID& uuid) { 189 uint16_t GetUUID16(const BluetoothUUID& uuid) {
183 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy 190 // Convert xxxxyyyy-xxxx-xxxx-xxxx-xxxxxxxxxxxx to int16 yyyy
184 return std::stoi(uuid.canonical_value().substr(4, 4), nullptr, 16); 191 return std::stoi(uuid.canonical_value().substr(4, 4), nullptr, 16);
185 } 192 }
186 193
194 void OnCreateServiceRecordDone(const CreateSdpRecordCallback& callback,
195 uint32_t service_handle) {
196 arc::mojom::BluetoothCreateSdpRecordResultPtr result =
197 arc::mojom::BluetoothCreateSdpRecordResult::New();
198 result->status = arc::mojom::BluetoothStatus::SUCCESS;
199 result->service_handle = service_handle;
200
201 callback.Run(std::move(result));
202 }
203
204 void OnCreateServiceRecordError(
205 const CreateSdpRecordCallback& callback,
206 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
207 arc::mojom::BluetoothCreateSdpRecordResultPtr result =
208 arc::mojom::BluetoothCreateSdpRecordResult::New();
209 if (error_code ==
210 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY)
211 result->status = arc::mojom::BluetoothStatus::NOT_READY;
212 else
213 result->status = arc::mojom::BluetoothStatus::FAIL;
214
215 callback.Run(std::move(result));
216 }
217
218 void OnRemoveServiceRecordDone(const RemoveSdpRecordCallback& callback) {
219 callback.Run(arc::mojom::BluetoothStatus::SUCCESS);
220 }
221
222 void OnRemoveServiceRecordError(
223 const RemoveSdpRecordCallback& callback,
224 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
225 arc::mojom::BluetoothStatus status;
226 if (error_code ==
227 bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY)
228 status = arc::mojom::BluetoothStatus::NOT_READY;
229 else
230 status = arc::mojom::BluetoothStatus::FAIL;
231
232 callback.Run(status);
233 }
234
187 } // namespace 235 } // namespace
188 236
189 namespace arc { 237 namespace arc {
190 238
191 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service) 239 ArcBluetoothBridge::ArcBluetoothBridge(ArcBridgeService* bridge_service)
192 : ArcService(bridge_service), binding_(this), weak_factory_(this) { 240 : ArcService(bridge_service), binding_(this), weak_factory_(this) {
193 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) { 241 if (BluetoothAdapterFactory::IsBluetoothAdapterAvailable()) {
194 VLOG(1) << "Registering bluetooth adapter."; 242 VLOG(1) << "Registering bluetooth adapter.";
195 BluetoothAdapterFactory::GetAdapter(base::Bind( 243 BluetoothAdapterFactory::GetAdapter(base::Bind(
196 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr())); 244 &ArcBluetoothBridge::OnAdapterInitialized, weak_factory_.GetWeakPtr()));
(...skipping 689 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 BluetoothDevice* device = 934 BluetoothDevice* device =
887 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>()); 935 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
888 DCHECK(device); 936 DCHECK(device);
889 937
890 if (device->IsConnected()) { 938 if (device->IsConnected()) {
891 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange( 939 arc_bridge_service()->bluetooth()->instance()->OnLEConnectionStateChange(
892 std::move(remote_addr), true); 940 std::move(remote_addr), true);
893 return; 941 return;
894 } 942 }
895 943
896 // Also pass disconnect callback in error case 944 // Also pass disconnect callback in error case since it would be disconnected
897 // since it would be disconnected anyway. 945 // anyway.
898 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone(); 946 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
899 device->CreateGattConnection( 947 device->CreateGattConnection(
900 base::Bind(&ArcBluetoothBridge::OnGattConnected, 948 base::Bind(&ArcBluetoothBridge::OnGattConnected,
901 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)), 949 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr)),
902 base::Bind(&ArcBluetoothBridge::OnGattConnectError, 950 base::Bind(&ArcBluetoothBridge::OnGattConnectError,
903 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone))); 951 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone)));
904 } 952 }
905 953
906 void ArcBluetoothBridge::DisconnectLEDevice( 954 void ArcBluetoothBridge::DisconnectLEDevice(
907 mojom::BluetoothAddressPtr remote_addr) { 955 mojom::BluetoothAddressPtr remote_addr) {
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 OnGattOperationDone(callback); 1433 OnGattOperationDone(callback);
1386 } 1434 }
1387 1435
1388 void ArcBluetoothBridge::SendIndication( 1436 void ArcBluetoothBridge::SendIndication(
1389 int32_t attribute_handle, 1437 int32_t attribute_handle,
1390 mojom::BluetoothAddressPtr address, 1438 mojom::BluetoothAddressPtr address,
1391 bool confirm, 1439 bool confirm,
1392 mojo::Array<uint8_t> value, 1440 mojo::Array<uint8_t> value,
1393 const SendIndicationCallback& callback) {} 1441 const SendIndicationCallback& callback) {}
1394 1442
1443 void ArcBluetoothBridge::GetSdpRecords(mojom::BluetoothAddressPtr remote_addr,
1444 mojom::BluetoothUUIDPtr target_uuid) {
1445 BluetoothDevice* device =
1446 bluetooth_adapter_->GetDevice(remote_addr->To<std::string>());
1447
1448 // Do an early return if there is no device with |remote_addr|.
1449 if (!device) {
1450 OnGetServiceRecordsError(std::move(remote_addr), std::move(target_uuid),
1451 bluez::BluetoothServiceRecordBlueZ::ErrorCode::
1452 ERROR_DEVICE_DISCONNECTED);
1453 return;
1454 }
1455
1456 bluez::BluetoothDeviceBlueZ* device_bluez =
1457 static_cast<bluez::BluetoothDeviceBlueZ*>(device);
1458
1459 mojom::BluetoothAddressPtr remote_addr_clone = remote_addr.Clone();
1460 mojom::BluetoothUUIDPtr target_uuid_clone = target_uuid.Clone();
1461
1462 device_bluez->GetServiceRecords(
1463 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsDone,
1464 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr),
1465 base::Passed(&target_uuid)),
1466 base::Bind(&ArcBluetoothBridge::OnGetServiceRecordsError,
1467 weak_factory_.GetWeakPtr(), base::Passed(&remote_addr_clone),
1468 base::Passed(&target_uuid_clone)));
1469 }
1470
1471 void ArcBluetoothBridge::CreateSdpRecord(
1472 mojom::BluetoothSdpRecordPtr record_mojo,
1473 const CreateSdpRecordCallback& callback) {
1474 auto record = record_mojo.To<bluez::BluetoothServiceRecordBlueZ>();
1475
1476 std::vector<uint16_t> v = record.GetAttributeIds();
rickyz (no longer on Chrome) 2016/08/29 00:48:06 Wouldn't it be better to extend bluez::BluetoothSe
Miao 2016/09/01 18:45:37 Please see https://codereview.chromium.org/2302963
1477
1478 // Check if ServiceClassIDList attribute (attribute ID 0x0001) is included
1479 // after type conversion, since it is mandatory for creating a service record.
1480 if (std::find(v.begin(), v.end(), kServiceClassIDListAttributeID) ==
1481 v.end()) {
1482 mojom::BluetoothCreateSdpRecordResultPtr result =
1483 mojom::BluetoothCreateSdpRecordResult::New();
1484 result->status = mojom::BluetoothStatus::FAIL;
1485 callback.Run(std::move(result));
1486 return;
1487 }
1488
1489 bluetooth_adapter_->CreateServiceRecord(
1490 record, base::Bind(&OnCreateServiceRecordDone, callback),
1491 base::Bind(&OnCreateServiceRecordError, callback));
1492 }
1493
1494 void ArcBluetoothBridge::RemoveSdpRecord(
1495 uint32_t service_handle,
1496 const RemoveSdpRecordCallback& callback) {
1497 bluetooth_adapter_->RemoveServiceRecord(
1498 service_handle, base::Bind(&OnRemoveServiceRecordDone, callback),
1499 base::Bind(&OnRemoveServiceRecordError, callback));
1500 }
1501
1395 void ArcBluetoothBridge::OnDiscoveryError() { 1502 void ArcBluetoothBridge::OnDiscoveryError() {
1396 LOG(WARNING) << "failed to change discovery state"; 1503 LOG(WARNING) << "failed to change discovery state";
1397 } 1504 }
1398 1505
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1506 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1400 if (!HasBluetoothInstance()) 1507 if (!HasBluetoothInstance())
1401 return; 1508 return;
1402 1509
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1510 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1511 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
1728 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) { 1835 if (arc_bridge_service()->bluetooth()->version() >= kMinBtleVersion) {
1729 base::Optional<int8_t> rssi = device->GetInquiryRSSI(); 1836 base::Optional<int8_t> rssi = device->GetInquiryRSSI();
1730 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data = 1837 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data =
1731 GetAdvertisingData(device); 1838 GetAdvertisingData(device);
1732 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound( 1839 arc_bridge_service()->bluetooth()->instance()->OnLEDeviceFound(
1733 addr->Clone(), rssi.value_or(mojom::kUnknownPower), 1840 addr->Clone(), rssi.value_or(mojom::kUnknownPower),
1734 std::move(adv_data)); 1841 std::move(adv_data));
1735 } 1842 }
1736 1843
1737 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING 1844 // OnBondStateChanged must be called with mojom::BluetoothBondState::BONDING
1738 // to 1845 // to make sure the bond state machine on Android is ready to take the
1739 // make sure the bond state machine on Android is ready to take the
1740 // pair-done event. Otherwise the pair-done event will be dropped as an 1846 // pair-done event. Otherwise the pair-done event will be dropped as an
1741 // invalid change of paired status. 1847 // invalid change of paired status.
1742 OnPairing(addr->Clone()); 1848 OnPairing(addr->Clone());
1743 OnPairedDone(std::move(addr)); 1849 OnPairedDone(std::move(addr));
1744 } 1850 }
1745 } 1851 }
1746 1852
1853 void ArcBluetoothBridge::OnGetServiceRecordsDone(
1854 mojom::BluetoothAddressPtr remote_addr,
1855 mojom::BluetoothUUIDPtr target_uuid,
1856 const std::vector<bluez::BluetoothServiceRecordBlueZ>& records_bluez) {
1857 if (!HasBluetoothInstance())
1858 return;
1859
1860 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
1861 mojom::BluetoothStatus::SUCCESS, std::move(remote_addr),
1862 std::move(target_uuid),
1863 mojo::Array<mojom::BluetoothSdpRecordPtr>::From(records_bluez));
1864 }
1865
1866 void ArcBluetoothBridge::OnGetServiceRecordsError(
1867 mojom::BluetoothAddressPtr remote_addr,
1868 mojom::BluetoothUUIDPtr target_uuid,
1869 bluez::BluetoothServiceRecordBlueZ::ErrorCode error_code) {
1870 mojom::BluetoothStatus status;
1871
1872 switch (error_code) {
1873 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::ERROR_ADAPTER_NOT_READY:
1874 status = mojom::BluetoothStatus::NOT_READY;
1875 break;
1876 case bluez::BluetoothServiceRecordBlueZ::ErrorCode::
1877 ERROR_DEVICE_DISCONNECTED:
1878 status = mojom::BluetoothStatus::RMT_DEV_DOWN;
1879 break;
1880 default:
1881 status = mojom::BluetoothStatus::FAIL;
1882 break;
1883 }
1884
1885 arc_bridge_service()->bluetooth()->instance()->OnGetSdpRecords(
1886 status, std::move(remote_addr), std::move(target_uuid),
1887 mojo::Array<mojom::BluetoothSdpRecordPtr>::New(0));
1888 }
1889
1747 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion( 1890 bool ArcBluetoothBridge::CheckBluetoothInstanceVersion(
1748 uint32_t version_need) const { 1891 uint32_t version_need) const {
1749 uint32_t version = arc_bridge_service()->bluetooth()->version(); 1892 uint32_t version = arc_bridge_service()->bluetooth()->version();
1750 if (version >= version_need) 1893 if (version >= version_need)
1751 return true; 1894 return true;
1752 LOG(WARNING) << "Bluetooth instance is too old (version " << version 1895 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1753 << ") need version " << version_need; 1896 << ") need version " << version_need;
1754 return false; 1897 return false;
1755 } 1898 }
1756 1899
1757 bool ArcBluetoothBridge::CalledOnValidThread() { 1900 bool ArcBluetoothBridge::CalledOnValidThread() {
1758 return thread_checker_.CalledOnValidThread(); 1901 return thread_checker_.CalledOnValidThread();
1759 } 1902 }
1760 1903
1761 } // namespace arc 1904 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698