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

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: 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>
11 11
12 #include <iomanip> 12 #include <iomanip>
13 #include <string> 13 #include <string>
14 #include <utility> 14 #include <utility>
15 15
16 #include "base/bind.h" 16 #include "base/bind.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/posix/eintr_wrapper.h" 18 #include "base/posix/eintr_wrapper.h"
19 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
20 #include "base/strings/stringprintf.h"
20 #include "base/strings/utf_string_conversions.h" 21 #include "base/strings/utf_string_conversions.h"
21 #include "base/threading/thread_task_runner_handle.h" 22 #include "base/threading/thread_task_runner_handle.h"
22 #include "base/time/time.h" 23 #include "base/time/time.h"
23 #include "components/arc/arc_bridge_service.h" 24 #include "components/arc/arc_bridge_service.h"
24 #include "components/arc/bluetooth/bluetooth_type_converters.h" 25 #include "components/arc/bluetooth/bluetooth_type_converters.h"
25 #include "device/bluetooth/bluetooth_common.h" 26 #include "device/bluetooth/bluetooth_common.h"
26 #include "device/bluetooth/bluetooth_device.h" 27 #include "device/bluetooth/bluetooth_device.h"
27 #include "device/bluetooth/bluetooth_gatt_connection.h" 28 #include "device/bluetooth/bluetooth_gatt_connection.h"
28 #include "device/bluetooth/bluetooth_gatt_notify_session.h" 29 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
29 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h" 30 #include "device/bluetooth/bluetooth_local_gatt_characteristic.h"
(...skipping 19 matching lines...) Expand all
49 using device::BluetoothRemoteGattDescriptor; 50 using device::BluetoothRemoteGattDescriptor;
50 using device::BluetoothRemoteGattService; 51 using device::BluetoothRemoteGattService;
51 using device::BluetoothTransport; 52 using device::BluetoothTransport;
52 using device::BluetoothUUID; 53 using device::BluetoothUUID;
53 54
54 namespace { 55 namespace {
55 constexpr int32_t kMinBtleVersion = 1; 56 constexpr int32_t kMinBtleVersion = 1;
56 constexpr int32_t kMinBtleNotifyVersion = 2; 57 constexpr int32_t kMinBtleNotifyVersion = 2;
57 constexpr int32_t kMinGattServerVersion = 3; 58 constexpr int32_t kMinGattServerVersion = 3;
58 constexpr int32_t kMinAddrChangeVersion = 4; 59 constexpr int32_t kMinAddrChangeVersion = 4;
60 constexpr int32_t kMinMultiAdvertisementVersion = 5;
59 constexpr uint32_t kGattReadPermission = 61 constexpr uint32_t kGattReadPermission =
60 BluetoothGattCharacteristic::Permission::PERMISSION_READ | 62 BluetoothGattCharacteristic::Permission::PERMISSION_READ |
61 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED | 63 BluetoothGattCharacteristic::Permission::PERMISSION_READ_ENCRYPTED |
62 BluetoothGattCharacteristic::Permission:: 64 BluetoothGattCharacteristic::Permission::
63 PERMISSION_READ_ENCRYPTED_AUTHENTICATED; 65 PERMISSION_READ_ENCRYPTED_AUTHENTICATED;
64 constexpr uint32_t kGattWritePermission = 66 constexpr uint32_t kGattWritePermission =
65 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE | 67 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE |
66 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED | 68 BluetoothGattCharacteristic::Permission::PERMISSION_WRITE_ENCRYPTED |
67 BluetoothGattCharacteristic::Permission:: 69 BluetoothGattCharacteristic::Permission::
68 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED; 70 PERMISSION_WRITE_ENCRYPTED_AUTHENTICATED;
69 constexpr int32_t kInvalidGattAttributeHandle = -1; 71 constexpr int32_t kInvalidGattAttributeHandle = -1;
72 constexpr int32_t kInvalidAdvertisementHandle = -1;
70 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.2 73 // 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. 74 // An attribute handle of value 0xFFFF is known as the maximum attribute handle.
72 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF; 75 constexpr int32_t kMaxGattAttributeHandle = 0xFFFF;
73 // Bluetooth Specification Version 4.2 Vol 3 Part F Section 3.2.9 76 // 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. 77 // The maximum length of an attribute value shall be 512 octets.
75 constexpr int kMaxGattAttributeLength = 512; 78 constexpr int kMaxGattAttributeLength = 512;
76 // Copied from Android at system/bt/stack/btm/btm_ble_int.h 79 // Copied from Android at system/bt/stack/btm/btm_ble_int.h
77 // https://goo.gl/k7PM6u 80 // https://goo.gl/k7PM6u
78 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95; 81 constexpr uint16_t kAndroidMBluetoothVersionNumber = 95;
79 constexpr uint16_t kMaxAdvertisement = 5;
80 82
81 using GattStatusCallback = 83 using GattStatusCallback =
82 base::Callback<void(arc::mojom::BluetoothGattStatus)>; 84 base::Callback<void(arc::mojom::BluetoothGattStatus)>;
83 using GattReadCallback = 85 using GattReadCallback =
84 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>; 86 base::Callback<void(arc::mojom::BluetoothGattValuePtr)>;
85 87
86 // 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
87 // Convert the last 4 characters of |identifier| to an 89 // Convert the last 4 characters of |identifier| to an
88 // int, by interpreting them as hexadecimal digits. 90 // int, by interpreting them as hexadecimal digits.
89 int ConvertGattIdentifierToId(const std::string identifier) { 91 int ConvertGattIdentifierToId(const std::string identifier) {
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 OnGattOperationDone(callback); 1387 OnGattOperationDone(callback);
1386 } 1388 }
1387 1389
1388 void ArcBluetoothBridge::SendIndication( 1390 void ArcBluetoothBridge::SendIndication(
1389 int32_t attribute_handle, 1391 int32_t attribute_handle,
1390 mojom::BluetoothAddressPtr address, 1392 mojom::BluetoothAddressPtr address,
1391 bool confirm, 1393 bool confirm,
1392 mojo::Array<uint8_t> value, 1394 mojo::Array<uint8_t> value,
1393 const SendIndicationCallback& callback) {} 1395 const SendIndicationCallback& callback) {}
1394 1396
1397 void ArcBluetoothBridge::EnableAdvertising(
1398 int32_t min_interval,
1399 int32_t max_interval,
1400 BluetoothAdvertisement::AdvertisementType adv_type,
1401 int32_t channel_map,
1402 int32_t tx_power,
1403 int32_t timeout_s,
1404 const EnableAdvertisingCallback& callback) {
1405 DCHECK(CalledOnValidThread());
1406 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1407 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1408 kInvalidAdvertisementHandle);
1409 return;
1410 }
1411
1412 // Find an empty advertisement slot.
1413 int adv_handle = -1;
1414 for (int i = 0; i < kMaxAdvertisement; i++)
Luis Héctor Chávez 2016/08/18 04:29:12 nit: this needs braces
1415 if (!advertisements_[i].in_use)
1416 adv_handle = i;
Luis Héctor Chávez 2016/08/18 04:29:12 break;?
1417
1418 if (adv_handle == -1) {
1419 LOG(WARNING) << "Out of space for advertisement data";
1420 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE,
1421 kInvalidAdvertisementHandle);
1422 return;
1423 }
1424
1425 // We have a handle. Mark the advertisement record in-use and
1426 // record the advertisement type.
1427 advertisements_[adv_handle].in_use = true;
1428 advertisements_[adv_handle].adv_type = adv_type;
1429
1430 // The advertisement will be registered when we get the call
1431 // to SetAdvertisingData. For now, just return the adv_handle.
1432 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS, adv_handle);
1433 }
1434
1435 void ArcBluetoothBridge::SetAdvertisingData(
1436 int32_t adv_handle,
1437 bool include_name,
1438 bool include_tx_power,
1439 int32_t appearance,
1440 mojo::Array<mojom::BluetoothAdvertisingDataPtr> adv_data,
1441 const SetAdvertisingDataCallback& callback) {
1442 DCHECK(CalledOnValidThread());
1443 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1444 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1445 return;
1446 }
1447
1448 if (adv_handle < 0 || adv_handle > kMaxAdvertisement ||
puthik_chromium 2016/08/17 23:22:04 adv_handle >= kMaxAdvertisement
Luis Héctor Chávez 2016/08/18 04:29:12 Actually you're repeating the same snippet several
1449 !advertisements_[adv_handle].in_use) {
1450 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1451 return;
1452 }
1453
1454 // Create BluetoothAdvertisement::Data using the adv_type we got when
puthik_chromium 2016/08/17 23:27:11 Should this in the type_converter?
rkc 2016/08/18 00:06:09 What Opal said. This should be in a type converter
1455 // advertising was enabled, and the data in adv_data.
1456 std::unique_ptr<BluetoothAdvertisement::Data> data = base::WrapUnique(
Luis Héctor Chávez 2016/08/18 04:29:12 base::WrapUnique(new T(...)) is being deprecated.
1457 new BluetoothAdvertisement::Data(advertisements_[adv_handle].adv_type));
1458 for (const auto& adv_entry : adv_data) {
1459 if (adv_entry->is_service_uuids()) {
1460 std::vector<BluetoothUUID> adv_uuids =
1461 adv_entry->get_service_uuids().To<std::vector<BluetoothUUID>>();
1462
1463 std::unique_ptr<std::vector<std::string>> uuid_list =
1464 base::WrapUnique(new std::vector<std::string>());
1465 for (const auto& uuid : adv_uuids) {
1466 uuid_list->push_back(uuid.value());
1467 }
1468 data->set_service_uuids(std::move(uuid_list));
1469 } else if (adv_entry->is_service_data()) {
1470 std::string service_uuid =
1471 base::StringPrintf("%04x", adv_entry->get_service_data()->uuid_16bit);
1472 std::vector<uint8_t> service_data =
1473 adv_entry->get_service_data()->data.To<std::vector<uint8_t>>();
1474
1475 data->set_service_data(
1476 base::WrapUnique(new std::map<std::string, std::vector<uint8_t>>{
1477 {service_uuid, service_data}}));
1478 } else if (adv_entry->is_manufacturer_data()) {
1479 // We get manufacturer data as a big blob. The first two bytes
1480 // should be a company identifier code in little-endian.
1481 std::vector<uint8_t> blob =
1482 adv_entry->get_manufacturer_data().To<std::vector<uint8_t>>();
1483 if (blob.size() < 2) {
Luis Héctor Chávez 2016/08/18 04:29:13 nit: s/2/sizeof(uint16_t)/
1484 LOG(WARNING) << "Received malformed manufacturer data for handle "
1485 << adv_handle;
1486 advertisements_[adv_handle].Clear();
1487 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1488 return;
1489 }
1490
1491 uint16_t cic = blob[0] << 8 | blob[1];
Luis Héctor Chávez 2016/08/18 04:29:12 Please add the same comment about the endianness h
1492 blob.erase(blob.begin(), blob.begin() + 2);
1493 data->set_manufacturer_data(base::WrapUnique(
1494 new std::map<uint16_t, std::vector<uint8_t>>{{cic, blob}}));
1495 }
1496 }
1497 data->set_include_tx_power(include_tx_power);
1498
1499 bluetooth_adapter_->RegisterAdvertisement(
1500 std::move(data),
1501 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementDone,
1502 weak_factory_.GetWeakPtr(), callback, adv_handle),
1503 base::Bind(&ArcBluetoothBridge::OnRegisterAdvertisementError,
1504 weak_factory_.GetWeakPtr(), callback, adv_handle));
1505 }
1506
1507 void ArcBluetoothBridge::OnRegisterAdvertisementDone(
1508 const SetAdvertisingDataCallback& callback,
1509 int32_t adv_handle,
1510 scoped_refptr<BluetoothAdvertisement> advertisement) {
1511 advertisements_[adv_handle].advertisement = advertisement;
1512 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1513 }
1514
1515 void ArcBluetoothBridge::OnRegisterAdvertisementError(
1516 const SetAdvertisingDataCallback& callback,
1517 int32_t adv_handle,
1518 BluetoothAdvertisement::ErrorCode error_code) {
1519 LOG(WARNING) << "Failed to register advertisement for handle " << adv_handle
1520 << ", error code = " << error_code;
1521 advertisements_[adv_handle].Clear();
1522 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1523 }
1524
1525 void ArcBluetoothBridge::DisableAdvertising(
1526 int32_t adv_handle,
1527 const DisableAdvertisingCallback& callback) {
1528 DCHECK(CalledOnValidThread());
1529 if (!CheckBluetoothInstanceVersion(kMinMultiAdvertisementVersion)) {
1530 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1531 return;
1532 }
1533
1534 if (adv_handle < 0 || adv_handle > kMaxAdvertisement ||
rkc 2016/08/18 00:06:09 adv_handle >= kMaxAdvertisement
1535 !advertisements_[adv_handle].in_use) {
1536 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1537 return;
1538 }
1539
1540 advertisements_[adv_handle].advertisement->Unregister(
1541 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementDone,
1542 weak_factory_.GetWeakPtr(), callback, adv_handle),
1543 base::Bind(&ArcBluetoothBridge::OnUnregisterAdvertisementError,
1544 weak_factory_.GetWeakPtr(), callback, adv_handle));
1545 }
1546
1547 void ArcBluetoothBridge::OnUnregisterAdvertisementDone(
1548 const DisableAdvertisingCallback& callback,
1549 int32_t adv_handle) {
1550 advertisements_[adv_handle].Clear();
1551 callback.Run(mojom::BluetoothGattStatus::GATT_SUCCESS);
1552 }
1553
1554 void ArcBluetoothBridge::OnUnregisterAdvertisementError(
1555 const DisableAdvertisingCallback& callback,
1556 int32_t adv_handle,
1557 BluetoothAdvertisement::ErrorCode error_code) {
1558 LOG(WARNING) << "Failed to disable advertising for handle " << adv_handle
1559 << ", error code = " << error_code;
1560 advertisements_[adv_handle].Clear();
1561 callback.Run(mojom::BluetoothGattStatus::GATT_FAILURE);
1562 }
1563
1395 void ArcBluetoothBridge::OnDiscoveryError() { 1564 void ArcBluetoothBridge::OnDiscoveryError() {
1396 LOG(WARNING) << "failed to change discovery state"; 1565 LOG(WARNING) << "failed to change discovery state";
1397 } 1566 }
1398 1567
1399 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const { 1568 void ArcBluetoothBridge::OnPairing(mojom::BluetoothAddressPtr addr) const {
1400 if (!HasBluetoothInstance()) 1569 if (!HasBluetoothInstance())
1401 return; 1570 return;
1402 1571
1403 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged( 1572 arc_bridge_service()->bluetooth()->instance()->OnBondStateChanged(
1404 mojom::BluetoothStatus::SUCCESS, std::move(addr), 1573 mojom::BluetoothStatus::SUCCESS, std::move(addr),
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1751 LOG(WARNING) << "Bluetooth instance is too old (version " << version 1920 LOG(WARNING) << "Bluetooth instance is too old (version " << version
1752 << ") need version " << version_need; 1921 << ") need version " << version_need;
1753 return false; 1922 return false;
1754 } 1923 }
1755 1924
1756 bool ArcBluetoothBridge::CalledOnValidThread() { 1925 bool ArcBluetoothBridge::CalledOnValidThread() {
1757 return thread_checker_.CalledOnValidThread(); 1926 return thread_checker_.CalledOnValidThread();
1758 } 1927 }
1759 1928
1760 } // namespace arc 1929 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698