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

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

Issue 2256003002: components/arc: implement multi advertising (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@plumb-incoming-connections
Patch Set: refactoring 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 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 using device::BluetoothRemoteGattDescriptor; 49 using device::BluetoothRemoteGattDescriptor;
50 using device::BluetoothRemoteGattService; 50 using device::BluetoothRemoteGattService;
51 using device::BluetoothTransport; 51 using device::BluetoothTransport;
52 using device::BluetoothUUID; 52 using device::BluetoothUUID;
53 53
54 namespace { 54 namespace {
55 constexpr int32_t kMinBtleVersion = 1; 55 constexpr int32_t kMinBtleVersion = 1;
56 constexpr int32_t kMinBtleNotifyVersion = 2; 56 constexpr int32_t kMinBtleNotifyVersion = 2;
57 constexpr int32_t kMinGattServerVersion = 3; 57 constexpr int32_t kMinGattServerVersion = 3;
58 constexpr int32_t kMinAddrChangeVersion = 4; 58 constexpr int32_t kMinAddrChangeVersion = 4;
59 constexpr int32_t kMinMultiAdvertisementVersion = 5;
59 constexpr uint32_t kGattReadPermission = 60 constexpr uint32_t kGattReadPermission =
60 BluetoothGattCharacteristic::Permission::PERMISSION_READ | 61 BluetoothGattCharacteristic::Permission::PERMISSION_READ |
61 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | 62 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
62 BluetoothGattCharacteristic::Permission:: 63 BluetoothGattCharacteristic::Permission::
63 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; 64 PERMISSION_READ_ENCRYPTED_AUTHENTICATED;
64 constexpr uint32_t kGattWritePermission = 65 constexpr uint32_t kGattWritePermission =
65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | 66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | 67 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
67 BluetoothGattCharacteristic::Permission:: 68 BluetoothGattCharacteristic::Permission::
68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; 69 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
69 constexpr int32_t kInvalidGattAttributeHandle = -1; 70 constexpr int32_t kInvalidGattAttributeHandle = -1;
71 constexpr int32_t kInvalidAdvertisementHandle = -1;
70 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 72 // 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. 73 // An attribute handle of value 0xFFFF is known as the maximum attribute handle.
72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; 74 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF;
73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 75 // 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. 76 // The maximum length of an attribute value shall be 512 octets.
75 constexpr int kMaxGattAttributeLength = 512; 77 constexpr int kMaxGattAttributeLength = 512;
76 // Copied from Android at system/bt/stack/btm/btm_ble_int.h 78 // Copied from Android at system/bt/stack/btm/btm_ble_int.h
77 // https://goo.gl/k7PM6u 79 // https://goo.gl/k7PM6u
78 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; 80 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95;
79 constexpr uint16_t kMaxAdvertisement = 5;
80 81
81 using GattStatusCallback = 82 using GattStatusCallback =
82 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 83 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
83 using GattReadCallback = 84 using GattReadCallback =
84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 85 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
85 86
86 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a 87 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
87 // Convert the last 4 characters of |identifier| to an 88 // Convert the last 4 characters of |identifier| to an
88 // int, by interpreting them as hexadecimal digits. 89 // int, by interpreting them as hexadecimal digits.
89 int ConvertGattIdentifierToId(const std::string identifier) { 90 int ConvertGattIdentifierToId(const std::string identifier) {
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 OnGattOperationDone(callback); 1386 OnGattOperationDone(callback);
1386 } 1387 }
1387 1388
1388 void ArcBluetoothBridge::SendIndication( 1389 void ArcBluetoothBridge::SendIndication(
1389 int32_t attribute_handle, 1390 int32_t attribute_handle,
1390 mojom::BluetoothAddressPtr address, 1391 mojom::BluetoothAddressPtr address,
1391 bool confirm, 1392 bool confirm,
1392 mojo::Array<uint8_t> value, 1393 mojo::Array<uint8_t> value,
1393 const SendIndicationCallback& callback) {} 1394 const SendIndicationCallback& callback) {}
1394 1395
1396 bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) {
puthik_chromium 2016/08/19 23:43:24 I don't think advertisementHandle need to be in ra
1397 for (int i = 0; i < kMaxAdvertisements; i++) {
1398 if (advertisements_.find(i) == advertisements_.end()) {
1399 *adv_handle = i;
1400 return true;
1401 }
1402 }
1403 return false;
1404 }
1405
1406 void ArcBluetoothBridge::ReserveAdvertisementHandle(
1407 const ReserveAdvertisementHandleCallback& callback) {
1408 DCHECK(CalledOnValidThread());
1409 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1410 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1411 kInvalidAdvertisementHandle);
1412 return;
1413 }
1414
1415 // Find an empty advertisement slot.
1416 int32_t adv_handle;
1417 if (!GetAdvertisementHandle(&adv_handle)) {
1418 LOG(WARNING) << "Out of space for advertisement data";
1419 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1420 kInvalidAdvertisementHandle);
1421 return;
1422 }
1423
1424 // We have a handle. Put an entry in the map to reserve it.
1425 advertisements_[adv_handle] = scoped_refptr<device::BluetoothAdvertisement>();
1426
1427 // The advertisement will be registered when we get the call
1428 // to SetAdvertisingData. For now, just return the adv_handle.
1429 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle);
1430 }
1431
1432 void ArcBluetoothBridge::BroadcastAdvertisement(
1433 int32_t adv_handle,
1434 mojom::BluetoothAdvertisementPtr advertisement,
1435 const BroadcastAdvertisementCallback& callback) {
1436 DCHECK(CalledOnValidThread());
1437 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1438 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1439 return;
1440 }
1441
1442 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1443 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1444 return;
1445 }
1446
1447 auto adv_data =
1448 advertisement.To<std::unique_ptr<device::BluetoothAdvertisement::Data>>();
1449 if (!adv_data) {
1450 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1451 return;
1452 }
1453
1454 if (!advertisements_[adv_handle]) {
1455 OnReadyToRegisterAdvertisement(callback, adv_handle, std::move(adv_data));
1456 }
1457
1458 advertisements_[adv_handle]->Unregister(
1459 base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement,
1460 weak_factory_.GetWeakPtr(), callback, adv_handle,
1461 base::Passed(std::move(adv_data))),
1462 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1463 weak_factory_.GetWeakPtr(), callback, adv_handle));
1464 }
1465
1466 void ArcBluetoothBridge::ReleaseAdvertisementHandle(
1467 int32_t adv_handle,
1468 const ReleaseAdvertisementHandleCallback& callback) {
1469 DCHECK(CalledOnValidThread());
1470 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1471 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1472 return;
1473 }
1474
1475 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1476 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1477 return;
1478 }
1479
1480 if (!advertisements_[adv_handle]) {
1481 advertisements_.erase(adv_handle);
1482 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1483 return;
1484 }
1485
1486 advertisements_[adv_handle]->Unregister(
1487 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone,
1488 weak_factory_.GetWeakPtr(), callback, adv_handle),
1489 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError,
1490 weak_factory_.GetWeakPtr(), callback, adv_handle));
1491 }
1492
1493 void ArcBluetoothBridge::OnReadyToRegisterAdvertisement(
1494 const BroadcastAdvertisementCallback& callback,
1495 int32_t adv_handle,
1496 std::unique_ptr<device::BluetoothAdvertisement::Data> data) {
1497 bluetooth_adapter_->RegisterAdvertisement(
1498 std::move(data),
1499 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone,
1500 weak_factory_.GetWeakPtr(), callback, adv_handle),
1501 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1502 weak_factory_.GetWeakPtr(), callback, adv_handle));
1503 }
1504
1505 void ArcBluetoothBridge::OnRegisterAdvertisementDone(
1506 const BroadcastAdvertisementCallback& callback,
1507 int32_t adv_handle,
1508 scoped_refptr<BluetoothAdvertisement> advertisement) {
1509 advertisements_[adv_handle] = advertisement;
1510 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1511 }
1512
1513 void ArcBluetoothBridge::OnRegisterAdvertisementError(
1514 const BroadcastAdvertisementCallback& callback,
1515 int32_t adv_handle,
1516 BluetoothAdvertisement::ErrorCode error_code) {
1517 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle
1518 << ", error code = " << error_code;
1519 advertisements_[adv_handle] = nullptr;
puthik_chromium 2016/08/19 23:43:24 Maybe advertisements_.erase(adv_handle);
Eric Caruso 2016/08/20 00:33:17 The comment on this method says it leaves the mapp
1520 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1521 }
1522
1523 void ArcBluetoothBridge::OnUnregisterAdvertisementDone(
1524 const ReleaseAdvertisementHandleCallback& callback,
1525 int32_t adv_handle) {
1526 advertisements_.erase(adv_handle);
1527 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1528 }
1529
1530 void ArcBluetoothBridge::OnUnregisterAdvertisementError(
1531 const ReleaseAdvertisementHandleCallback& callback,
1532 int32_t adv_handle,
1533 BluetoothAdvertisement::ErrorCode error_code) {
1534 LOG(ERROR) << "Failed to unregister advertisement for handle " << adv_handle
1535 << ", error code = " << error_code;
1536 advertisements_.erase(adv_handle);
1537 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1538 }
1539
1395 void ArcBluetoothBridge::OnDiscoveryError() { 1540 void ArcBluetoothBridge::OnDiscoveryError() {
1396 LOG(WARNING) << "failed to change discovery state"; 1541 LOG(WARNING) << "failed to change discovery state";
1397 } 1542 }
1398 1543
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1544 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1400 if (!HasBluetoothInstance()) 1545 if (!HasBluetoothInstance())
1401 return; 1546 return;
1402 1547
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1548 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1549 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
1589 properties.push_back(std::move(btp)); 1734 properties.push_back(std::move(btp));
1590 } 1735 }
1591 if (type == mojom::BluetoothPropertyType::ALL || 1736 if (type == mojom::BluetoothPropertyType::ALL ||
1592 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { 1737 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) {
1593 // TODO(crbug.com/637171) Investigate all the le_features. 1738 // TODO(crbug.com/637171) Investigate all the le_features.
1594 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1739 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
1595 mojom::BluetoothLocalLEFeaturesPtr le_features = 1740 mojom::BluetoothLocalLEFeaturesPtr le_features =
1596 mojom::BluetoothLocalLEFeatures::New(); 1741 mojom::BluetoothLocalLEFeatures::New();
1597 le_features->version_supported = kAndroidMBluetoothVersionNumber; 1742 le_features->version_supported = kAndroidMBluetoothVersionNumber;
1598 le_features->local_privacy_enabled = 0; 1743 le_features->local_privacy_enabled = 0;
1599 le_features->max_adv_instance = kMaxAdvertisement; 1744 le_features->max_adv_instance = kMaxAdvertisements;
1600 le_features->rpa_offload_supported = 0; 1745 le_features->rpa_offload_supported = 0;
1601 le_features->max_irk_list_size = 0; 1746 le_features->max_irk_list_size = 0;
1602 le_features->max_adv_filter_supported = 0; 1747 le_features->max_adv_filter_supported = 0;
1603 le_features->activity_energy_info_supported = 0; 1748 le_features->activity_energy_info_supported = 0;
1604 le_features->scan_result_storage_size = 0; 1749 le_features->scan_result_storage_size = 0;
1605 le_features->total_trackable_advertisers = 0; 1750 le_features->total_trackable_advertisers = 0;
1606 le_features->extended_scan_support = false; 1751 le_features->extended_scan_support = false;
1607 le_features->debug_logging_supported = false; 1752 le_features->debug_logging_supported = false;
1608 btp->set_local_le_features(std::move(le_features)); 1753 btp->set_local_le_features(std::move(le_features));
1609 properties.push_back(std::move(btp)); 1754 properties.push_back(std::move(btp));
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 LOG(WARNING) << "Bluetooth instance is too old (version " << version 1896 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1752 << ") need version " << version_need; 1897 << ") need version " << version_need;
1753 return false; 1898 return false;
1754 } 1899 }
1755 1900
1756 bool ArcBluetoothBridge::CalledOnValidThread() { 1901 bool ArcBluetoothBridge::CalledOnValidThread() {
1757 return thread_checker_.CalledOnValidThread(); 1902 return thread_checker_.CalledOnValidThread();
1758 } 1903 }
1759 1904
1760 } // namespace arc 1905 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698