1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/proximity_auth/ble/bluetooth_low_energy_characteristics_finder.h"
7 #include "components/proximity_auth/logging/logging.h"
8 #include "device/bluetooth/bluetooth_adapter.h"
9 #include "device/bluetooth/bluetooth_device.h"
10 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
11 #include "device/bluetooth/bluetooth_uuid.h"
13 using device::BluetoothAdapter
;
14 using device::BluetoothDevice
;
15 using device::BluetoothGattCharacteristic
;
16 using device::BluetoothGattService
;
17 using device::BluetoothUUID
;
19 namespace proximity_auth
{
21 BluetoothLowEnergyCharacteristicsFinder::
22 BluetoothLowEnergyCharacteristicsFinder(
23 scoped_refptr
<BluetoothAdapter
> adapter
,
24 BluetoothDevice
* device
,
25 const RemoteAttribute
& remote_service
,
26 const RemoteAttribute
& to_peripheral_char
,
27 const RemoteAttribute
& from_peripheral_char
,
28 const SuccessCallback
& success_callback
,
29 const ErrorCallback
& error_callback
)
31 remote_service_(remote_service
),
32 to_peripheral_char_(to_peripheral_char
),
33 from_peripheral_char_(from_peripheral_char
),
34 success_callback_(success_callback
),
35 error_callback_(error_callback
) {
37 error_callback_
.Run(to_peripheral_char_
, from_peripheral_char_
);
42 adapter_
->AddObserver(this);
43 ScanRemoteCharacteristics(device
, remote_service_
.uuid
);
45 // TODO(sacomoto): implement a timeout for characteristic discovery.
48 BluetoothLowEnergyCharacteristicsFinder::
49 BluetoothLowEnergyCharacteristicsFinder() {
52 BluetoothLowEnergyCharacteristicsFinder::
53 ~BluetoothLowEnergyCharacteristicsFinder() {
56 adapter_
->RemoveObserver(this);
61 void BluetoothLowEnergyCharacteristicsFinder::GattCharacteristicAdded(
62 BluetoothAdapter
* adapter
,
63 BluetoothGattCharacteristic
* characteristic
) {
64 PA_LOG(INFO
) << "New char found: "
65 << characteristic
->GetUUID().canonical_value();
66 HandleCharacteristicUpdate(characteristic
);
69 void BluetoothLowEnergyCharacteristicsFinder::GattDiscoveryCompleteForService(
70 BluetoothAdapter
* adapter
,
71 BluetoothGattService
* service
) {
72 if (service
&& service
->GetUUID() == remote_service_
.uuid
) {
73 PA_LOG(INFO
) << "All characteristics discovered for "
74 << remote_service_
.uuid
.canonical_value();
76 if (to_peripheral_char_
.id
.empty() || from_peripheral_char_
.id
.empty()) {
77 if (!error_callback_
.is_null()) {
78 error_callback_
.Run(to_peripheral_char_
, from_peripheral_char_
);
85 void BluetoothLowEnergyCharacteristicsFinder::ScanRemoteCharacteristics(
86 BluetoothDevice
* device
,
87 const BluetoothUUID
& service_uuid
) {
88 PA_LOG(INFO
) << "Scanning remote characteristics.";
90 std::vector
<BluetoothGattService
*> services
= device
->GetGattServices();
91 for (const auto& service
: services
) {
92 if (service
->GetUUID() == service_uuid
) {
93 // Right service found, now scaning its characteristics.
94 std::vector
<device::BluetoothGattCharacteristic
*> characteristics
=
95 service
->GetCharacteristics();
96 for (const auto& characteristic
: characteristics
) {
97 HandleCharacteristicUpdate(characteristic
);
105 void BluetoothLowEnergyCharacteristicsFinder::HandleCharacteristicUpdate(
106 BluetoothGattCharacteristic
* characteristic
) {
107 UpdateCharacteristicsStatus(characteristic
);
109 if (!to_peripheral_char_
.id
.empty() && !from_peripheral_char_
.id
.empty() &&
110 !success_callback_
.is_null()) {
111 PA_LOG(INFO
) << "Found write and read characteristics on remote device.";
112 success_callback_
.Run(remote_service_
, to_peripheral_char_
,
113 from_peripheral_char_
);
118 void BluetoothLowEnergyCharacteristicsFinder::UpdateCharacteristicsStatus(
119 BluetoothGattCharacteristic
* characteristic
) {
120 if (characteristic
) {
121 BluetoothUUID uuid
= characteristic
->GetUUID();
122 if (to_peripheral_char_
.uuid
== uuid
)
123 to_peripheral_char_
.id
= characteristic
->GetIdentifier();
124 if (from_peripheral_char_
.uuid
== uuid
)
125 from_peripheral_char_
.id
= characteristic
->GetIdentifier();
127 BluetoothGattService
* service
= characteristic
->GetService();
128 if (service
&& service
->GetUUID() == remote_service_
.uuid
)
129 remote_service_
.id
= service
->GetIdentifier();
133 void BluetoothLowEnergyCharacteristicsFinder::ResetCallbacks() {
134 success_callback_
.Reset();
135 error_callback_
.Reset();
138 } // namespace proximity_auth