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

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: swap CHECK_EQ for EXPECT_EQ 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 BluetoothGattCharacteristic::Permission::PERMISSION_READ | 60 BluetoothGattCharacteristic::Permission::PERMISSION_READ |
61 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | 61 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
62 BluetoothGattCharacteristic::Permission:: 62 BluetoothGattCharacteristic::Permission::
63 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; 63 PERMISSION_READ_ENCRYPTED_AUTHENTICATED;
64 constexpr uint32_t kGattWritePermission = 64 constexpr uint32_t kGattWritePermission =
65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | 65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | 66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
67 BluetoothGattCharacteristic::Permission:: 67 BluetoothGattCharacteristic::Permission::
68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; 68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
69 constexpr int32_t kInvalidGattAttributeHandle = -1; 69 constexpr int32_t kInvalidGattAttributeHandle = -1;
70 constexpr int32_t kInvalidAdvertisementHandle = -1;
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 80
81 using GattStatusCallback = 81 using GattStatusCallback =
82 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 82 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
83 using GattReadCallback = 83 using GattReadCallback =
84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
85 85
86 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a 86 // Example of identifier: /org/bluez/hci0/dev_E0_CF_65_8C_86_1A/service001a
87 // Convert the last 4 characters of |identifier| to an 87 // Convert the last 4 characters of |identifier| to an
88 // int, by interpreting them as hexadecimal digits. 88 // int, by interpreting them as hexadecimal digits.
89 int ConvertGattIdentifierToId(const std::string identifier) { 89 int ConvertGattIdentifierToId(const std::string identifier) {
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 OnGattOperationDone(callback); 1385 OnGattOperationDone(callback);
1386 } 1386 }
1387 1387
1388 void ArcBluetoothBridge::SendIndication( 1388 void ArcBluetoothBridge::SendIndication(
1389 int32_t attribute_handle, 1389 int32_t attribute_handle,
1390 mojom::BluetoothAddressPtr address, 1390 mojom::BluetoothAddressPtr address,
1391 bool confirm, 1391 bool confirm,
1392 mojo::Array<uint8_t> value, 1392 mojo::Array<uint8_t> value,
1393 const SendIndicationCallback& callback) {} 1393 const SendIndicationCallback& callback) {}
1394 1394
1395 bool ArcBluetoothBridge::GetAdvertisementHandle(int32_t* adv_handle) {
1396 for (int i = 0; i < kMaxAdvertisements; i++) {
1397 if (advertisements_.find(i) == advertisements_.end()) {
1398 *adv_handle = i;
1399 return true;
1400 }
1401 }
1402 return false;
1403 }
1404
1405 void ArcBluetoothBridge::ReserveAdvertisementHandle(
1406 const ReserveAdvertisementHandleCallback& callback) {
1407 DCHECK(CalledOnValidThread());
1408 // Find an empty advertisement slot.
1409 int32_t adv_handle;
1410 if (!GetAdvertisementHandle(&adv_handle)) {
1411 LOG(WARNING) << "Out of space for advertisement data";
1412 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1413 kInvalidAdvertisementHandle);
1414 return;
1415 }
1416
1417 // We have a handle. Put an entry in the map to reserve it.
1418 advertisements_[adv_handle] = scoped_refptr<device::BluetoothAdvertisement>();
rickyz (no longer on Chrome) 2016/08/29 01:09:23 nit: = nullptr for consistency with below
1419
1420 // The advertisement will be registered when we get the call
1421 // to SetAdvertisingData. For now, just return the adv_handle.
1422 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle);
1423 }
1424
1425 void ArcBluetoothBridge::BroadcastAdvertisement(
1426 int32_t adv_handle,
1427 mojom::BluetoothAdvertisementPtr advertisement,
1428 const BroadcastAdvertisementCallback& callback) {
1429 DCHECK(CalledOnValidThread());
1430 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1431 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1432 return;
1433 }
1434
1435 auto adv_data =
1436 advertisement.To<std::unique_ptr<device::BluetoothAdvertisement::Data>>();
1437 if (!adv_data) {
1438 LOG(WARNING) << "Tried to broadcast malformed advertisement data for "
1439 << "handle " << adv_handle;
1440 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1441 return;
1442 }
1443
1444 if (!advertisements_[adv_handle]) {
1445 OnReadyToRegisterAdvertisement(callback, adv_handle, std::move(adv_data));
1446 return;
1447 }
1448
1449 advertisements_[adv_handle]->Unregister(
1450 base::Bind(&ArcBluetoothBridge::OnReadyToRegisterAdvertisement,
1451 weak_factory_.GetWeakPtr(), callback, adv_handle,
1452 base::Passed(std::move(adv_data))),
1453 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1454 weak_factory_.GetWeakPtr(), callback, adv_handle));
1455 }
1456
1457 void ArcBluetoothBridge::ReleaseAdvertisementHandle(
1458 int32_t adv_handle,
1459 const ReleaseAdvertisementHandleCallback& callback) {
1460 DCHECK(CalledOnValidThread());
1461 if (advertisements_.find(adv_handle) == advertisements_.end()) {
1462 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1463 return;
1464 }
1465
1466 if (!advertisements_[adv_handle]) {
1467 advertisements_.erase(adv_handle);
1468 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1469 return;
1470 }
1471
1472 advertisements_[adv_handle]->Unregister(
1473 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone,
1474 weak_factory_.GetWeakPtr(), callback, adv_handle),
1475 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError,
1476 weak_factory_.GetWeakPtr(), callback, adv_handle));
1477 }
1478
1479 void ArcBluetoothBridge::OnReadyToRegisterAdvertisement(
1480 const BroadcastAdvertisementCallback& callback,
1481 int32_t adv_handle,
1482 std::unique_ptr<device::BluetoothAdvertisement::Data> data) {
1483 bluetooth_adapter_->RegisterAdvertisement(
1484 std::move(data),
1485 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone,
1486 weak_factory_.GetWeakPtr(), callback, adv_handle),
1487 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1488 weak_factory_.GetWeakPtr(), callback, adv_handle));
1489 }
1490
1491 void ArcBluetoothBridge::OnRegisterAdvertisementDone(
1492 const BroadcastAdvertisementCallback& callback,
1493 int32_t adv_handle,
1494 scoped_refptr<BluetoothAdvertisement> advertisement) {
1495 advertisements_[adv_handle] = advertisement;
rickyz (no longer on Chrome) 2016/08/24 21:47:30 Can std::move advertisement
Eric Caruso 2016/08/24 22:24:42 Since it's a scoped_refptr, it seems kind of super
Eric Caruso 2016/08/24 22:26:11 (Do we do this with std::move elsewhere?)
rickyz (no longer on Chrome) 2016/08/29 01:09:23 Yeah, we do - it's a minor optimization (avoids an
1496 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1497 }
1498
1499 void ArcBluetoothBridge::OnRegisterAdvertisementError(
1500 const BroadcastAdvertisementCallback& callback,
1501 int32_t adv_handle,
1502 BluetoothAdvertisement::ErrorCode error_code) {
1503 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle
1504 << ", error code = " << error_code;
1505 advertisements_[adv_handle] = nullptr;
1506 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1507 }
1508
1509 void ArcBluetoothBridge::OnUnregisterAdvertisementDone(
1510 const ReleaseAdvertisementHandleCallback& callback,
1511 int32_t adv_handle) {
1512 advertisements_.erase(adv_handle);
1513 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1514 }
1515
1516 void ArcBluetoothBridge::OnUnregisterAdvertisementError(
1517 const ReleaseAdvertisementHandleCallback& callback,
1518 int32_t adv_handle,
1519 BluetoothAdvertisement::ErrorCode error_code) {
1520 LOG(WARNING) << "Failed to unregister advertisement for handle " << adv_handle
1521 << ", error code = " << error_code;
1522 advertisements_.erase(adv_handle);
1523 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1524 }
1525
1395 void ArcBluetoothBridge::OnDiscoveryError() { 1526 void ArcBluetoothBridge::OnDiscoveryError() {
1396 LOG(WARNING) << "failed to change discovery state"; 1527 LOG(WARNING) << "failed to change discovery state";
1397 } 1528 }
1398 1529
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1530 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1400 if (!HasBluetoothInstance()) 1531 if (!HasBluetoothInstance())
1401 return; 1532 return;
1402 1533
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1534 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1535 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)); 1720 properties.push_back(std::move(btp));
1590 } 1721 }
1591 if (type == mojom::BluetoothPropertyType::ALL || 1722 if (type == mojom::BluetoothPropertyType::ALL ||
1592 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) { 1723 type == mojom::BluetoothPropertyType::LOCAL_LE_FEATURES) {
1593 // TODO(crbug.com/637171) Investigate all the le_features. 1724 // TODO(crbug.com/637171) Investigate all the le_features.
1594 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New(); 1725 mojom::BluetoothPropertyPtr btp = mojom::BluetoothProperty::New();
1595 mojom::BluetoothLocalLEFeaturesPtr le_features = 1726 mojom::BluetoothLocalLEFeaturesPtr le_features =
1596 mojom::BluetoothLocalLEFeatures::New(); 1727 mojom::BluetoothLocalLEFeatures::New();
1597 le_features->version_supported = kAndroidMBluetoothVersionNumber; 1728 le_features->version_supported = kAndroidMBluetoothVersionNumber;
1598 le_features->local_privacy_enabled = 0; 1729 le_features->local_privacy_enabled = 0;
1599 le_features->max_adv_instance = kMaxAdvertisement; 1730 le_features->max_adv_instance = kMaxAdvertisements;
1600 le_features->rpa_offload_supported = 0; 1731 le_features->rpa_offload_supported = 0;
1601 le_features->max_irk_list_size = 0; 1732 le_features->max_irk_list_size = 0;
1602 le_features->max_adv_filter_supported = 0; 1733 le_features->max_adv_filter_supported = 0;
1603 le_features->activity_energy_info_supported = 0; 1734 le_features->activity_energy_info_supported = 0;
1604 le_features->scan_result_storage_size = 0; 1735 le_features->scan_result_storage_size = 0;
1605 le_features->total_trackable_advertisers = 0; 1736 le_features->total_trackable_advertisers = 0;
1606 le_features->extended_scan_support = false; 1737 le_features->extended_scan_support = false;
1607 le_features->debug_logging_supported = false; 1738 le_features->debug_logging_supported = false;
1608 btp->set_local_le_features(std::move(le_features)); 1739 btp->set_local_le_features(std::move(le_features));
1609 properties.push_back(std::move(btp)); 1740 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 1882 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1752 << ") need version " << version_need; 1883 << ") need version " << version_need;
1753 return false; 1884 return false;
1754 } 1885 }
1755 1886
1756 bool ArcBluetoothBridge::CalledOnValidThread() { 1887 bool ArcBluetoothBridge::CalledOnValidThread() {
1757 return thread_checker_.CalledOnValidThread(); 1888 return thread_checker_.CalledOnValidThread();
1758 } 1889 }
1759 1890
1760 } // namespace arc 1891 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698