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

Side by Side Diff: components/proximity_auth/ble/bluetooth_low_energy_connection.cc

Issue 1116963002: Bluetooth low energy connection. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removing debug messages Created 5 years, 7 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
(Empty)
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.
4
5 #include "components/proximity_auth/ble/bluetooth_low_energy_connection.h"
6
7 #include "base/bind.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/memory/weak_ptr.h"
10 #include "components/proximity_auth/connection_finder.h"
11 #include "components/proximity_auth/ble/fake_wire_message.h"
12 #include "components/proximity_auth/wire_message.h"
13 #include "device/bluetooth/bluetooth_adapter.h"
14 #include "device/bluetooth/bluetooth_device.h"
15 #include "device/bluetooth/bluetooth_gatt_characteristic.h"
16 #include "device/bluetooth/bluetooth_gatt_connection.h"
17 #include "device/bluetooth/bluetooth_gatt_notify_session.h"
18 #include "device/bluetooth/bluetooth_uuid.h"
19
20 using device::BluetoothAdapter;
21 using device::BluetoothDevice;
22 using device::BluetoothGattConnection;
23 using device::BluetoothGattService;
24 using device::BluetoothGattCharacteristic;
25 using device::BluetoothGattNotifySession;
26 using device::BluetoothUUID;
27
28 namespace proximity_auth {
29
30 BluetoothLowEnergyConnection::BluetoothLowEnergyConnection(
31 const RemoteDevice& device,
32 scoped_refptr<device::BluetoothAdapter> adapter,
33 BluetoothUUID remote_service_uuid,
34 scoped_ptr<BluetoothGattConnection> gatt_connection)
35 : Connection(device),
36 adapter_(adapter),
37 remote_service_uuid_(remote_service_uuid),
38 connection_(gatt_connection.Pass()),
39 notify_session_pending_(false),
40 weak_ptr_factory_(this) {
41 if (connection_) {
msarda 2015/05/05 11:56:13 Can |connection_| be null? If not, then it is bett
sacomoto 2015/05/06 13:47:58 Done.
42 SetStatus(IN_PROGRESS);
43 }
44
45 if (adapter_) {
msarda 2015/05/05 11:56:14 DCHECK(adapter_)?
sacomoto 2015/05/06 13:47:58 Done.
46 adapter_->AddObserver(this);
47 }
48 }
49
50 BluetoothLowEnergyConnection::~BluetoothLowEnergyConnection() {
51 Disconnect();
52 if (adapter_) {
53 adapter_->RemoveObserver(this);
54 adapter_ = NULL;
55 }
56 }
57
58 void BluetoothLowEnergyConnection::Connect() {
59 NOTREACHED();
60 }
61
62 void BluetoothLowEnergyConnection::Disconnect() {
63 StopNotifySession();
64 if (connection_) {
65 connection_.reset();
66 BluetoothDevice* device = GetRemoteDevice();
67 if (device) {
68 VLOG(1) << "Forget device " << device->GetAddress();
69 device->Forget(base::Bind(&base::DoNothing));
msarda 2015/05/05 11:56:14 Please add a comment that disconnect actually forg
sacomoto 2015/05/06 13:47:58 Done.
70 }
71 }
72 }
73
74 // TODO(sacomoto): Send a Socketeer incoming signal. Implement a sender with
msarda 2015/05/05 11:56:13 Remove all reference to Socketeer.
sacomoto 2015/05/06 13:47:58 Done.
75 // full support for messages larger than a single characteristic value.
76 void BluetoothLowEnergyConnection::SendMessageImpl(
77 scoped_ptr<WireMessage> message) {
78 DCHECK(!GetGattCharacteristic(to_peripheral_char_id_));
79 VLOG(1) << "Sending message " << message->Serialize();
80
81 std::string serialized_message = message->Serialize();
82 std::vector<uint8> bytes(serialized_message.begin(),
83 serialized_message.end());
84
85 GetGattCharacteristic(to_peripheral_char_id_)
86 ->WriteRemoteCharacteristic(
87 bytes, base::Bind(&base::DoNothing),
88 base::Bind(
89 &BluetoothLowEnergyConnection::OnWriteRemoteCharacteristicError,
90 weak_ptr_factory_.GetWeakPtr()));
91 }
92
93 void BluetoothLowEnergyConnection::DeviceRemoved(BluetoothAdapter* adapter,
94 BluetoothDevice* device) {
95 if (device && device->GetAddress() == remote_device_address()) {
96 VLOG(1) << "device removed " << remote_device_address();
msarda 2015/05/05 11:56:13 Log should state with CAPS: s/device/Device
sacomoto 2015/05/06 13:47:57 Done.
97 Disconnect();
98 }
99 }
100
101 void BluetoothLowEnergyConnection::GattDiscoveryCompleteForService(
102 BluetoothAdapter* adapter,
103 BluetoothGattService* service) {
104 if (service && service->GetUUID() == remote_service_uuid_) {
105 VLOG(1) << "All characteristics discovered for "
106 << remote_service_uuid_.canonical_value();
107
108 std::vector<device::BluetoothGattCharacteristic*> characteristics =
109 service->GetCharacteristics();
110 for (auto iter = characteristics.begin(); iter != characteristics.end();
111 iter++) {
112 HandleCharacteristicUpdate(*iter);
113 }
114
115 if (to_peripheral_char_id_.empty() || from_peripheral_char_id_.empty()) {
116 VLOG(1) << "Connection error, missing characteristics for service.";
msarda 2015/05/05 11:56:13 s/service/Smart Lock service
msarda 2015/05/05 11:56:13 Please also log which one of |to_peripheral_char_i
sacomoto 2015/05/06 13:47:58 Done.
sacomoto 2015/05/06 13:47:58 Done.
117 Disconnect();
118 }
119 }
120 }
121
122 void BluetoothLowEnergyConnection::GattCharacteristicAdded(
123 BluetoothAdapter* adapter,
124 BluetoothGattCharacteristic* characteristic) {
125 VLOG(1) << "new char found: " << characteristic->GetUUID().canonical_value();
126 HandleCharacteristicUpdate(characteristic);
127 }
128
129 // TODO(sacomoto): Parse the Sockeeter incoming signal. Implement a receiver
msarda 2015/05/05 11:56:13 Remove Socketeer.
sacomoto 2015/05/06 13:47:58 Done.
130 // with full suport for messages larger than a single characteristic value.
131 void BluetoothLowEnergyConnection::GattCharacteristicValueChanged(
132 BluetoothAdapter* adapter,
133 BluetoothGattCharacteristic* characteristic,
134 const std::vector<uint8>& value) {
135 VLOG(1) << "Characteristic value changed: "
136 << characteristic->GetUUID().canonical_value();
137 if (characteristic->GetIdentifier() == from_peripheral_char_id_) {
138 std::string message(value.begin(), value.end());
139 VLOG(1) << "value: " << message;
140 // TODO(sacomoto): Actually handle the message and call OnBytesReceived when
141 // complete.
142 }
143 }
144
145 scoped_ptr<WireMessage> BluetoothLowEnergyConnection::DeserializeWireMessage(
146 bool* is_incomplete_message) {
147 return FakeWireMessage::Deserialize(received_bytes(), is_incomplete_message);
148 }
149
150 void BluetoothLowEnergyConnection::HandleCharacteristicUpdate(
151 BluetoothGattCharacteristic* characteristic) {
152 // Checks if |characteristic| is equal to |from_peripheral_char_| or
153 // |to_peripheral_char_| are present.
154 UpdateCharacteristicsStatus(characteristic);
155
156 // Starts a notify session for |from_peripheral_char_|.
157 if (characteristic->GetIdentifier() == from_peripheral_char_id_)
158 StartNotifySession();
159
160 // Checks if the connection is complete.
161 CompleteConnection();
162 }
163
164 void BluetoothLowEnergyConnection::CompleteConnection() {
165 if (status() == IN_PROGRESS && !to_peripheral_char_id_.empty() &&
166 !from_peripheral_char_id_.empty() && notify_session_) {
167 VLOG(1) << "Connection completed";
168 SetStatus(CONNECTED);
169 SendInviteToConnectSignal();
msarda 2015/05/05 11:56:13 Should we wait for a reply to invite signal before
sacomoto 2015/05/06 13:47:58 Done.
170 }
171 }
172
173 void BluetoothLowEnergyConnection::StartNotifySession() {
174 BluetoothGattCharacteristic* characteristic =
175 GetGattCharacteristic(from_peripheral_char_id_);
176 if (!characteristic) {
177 VLOG(1) << "Characteristic " << from_peripheral_char_ << " not found.";
178 return;
179 }
180
181 if (notify_session_ || notify_session_pending_) {
182 VLOG(1) << "Notify session already started.";
183 return;
184 }
185
186 notify_session_pending_ = true;
187 characteristic->StartNotifySession(
188 base::Bind(&BluetoothLowEnergyConnection::OnNotifySessionStarted,
189 weak_ptr_factory_.GetWeakPtr()),
190 base::Bind(&BluetoothLowEnergyConnection::OnNotifySessionError,
191 weak_ptr_factory_.GetWeakPtr()));
192 }
193
194 void BluetoothLowEnergyConnection::OnNotifySessionError(
195 BluetoothGattService::GattErrorCode error) {
196 VLOG(1) << "Error starting notification session: " << error;
197 notify_session_pending_ = false;
198 }
199
200 void BluetoothLowEnergyConnection::OnNotifySessionStarted(
201 scoped_ptr<BluetoothGattNotifySession> notify_session) {
202 VLOG(1) << "Notification session started "
203 << notify_session->GetCharacteristicIdentifier();
204 notify_session_ = notify_session.Pass();
205 notify_session_pending_ = false;
206
207 // Checks if the connection is complete.
208 CompleteConnection();
209 }
210
211 void BluetoothLowEnergyConnection::StopNotifySession() {
212 if (notify_session_) {
213 notify_session_->Stop(base::Bind(&base::DoNothing));
214 notify_session_.reset();
215 }
216 }
217
218 void BluetoothLowEnergyConnection::OnWriteRemoteCharacteristicError(
219 BluetoothGattService::GattErrorCode error) {
220 VLOG(1) << "Error writing characteristic" << to_peripheral_char_;
221 }
222
223 void BluetoothLowEnergyConnection::SendInviteToConnectSignal() {
224 // From Socketeer library: connect signal is 0 (32-bit int).
225 const char connect_signal[4] = {};
226 SendMessage(scoped_ptr<FakeWireMessage>(new FakeWireMessage(connect_signal)));
227 }
228
229 void BluetoothLowEnergyConnection::UpdateCharacteristicsStatus(
230 BluetoothGattCharacteristic* characteristic) {
231 if (characteristic) {
232 std::string canonical_value = characteristic->GetUUID().canonical_value();
233 VLOG(1) << canonical_value;
234 if (to_peripheral_char_ == canonical_value) {
235 to_peripheral_char_id_ = characteristic->GetIdentifier();
236 }
237 if (from_peripheral_char_ == canonical_value) {
238 from_peripheral_char_id_ = characteristic->GetIdentifier();
239 }
240 BluetoothGattService* service = characteristic->GetService();
241 if (service && service->GetUUID() == remote_service_uuid_)
242 remote_service_id_ = service->GetIdentifier();
243 }
244 }
245
246 BluetoothDevice* BluetoothLowEnergyConnection::GetRemoteDevice() {
247 if (!adapter_ || !adapter_->IsInitialized()) {
248 VLOG(1) << "adapter not ready";
249 return NULL;
250 }
251 return adapter_->GetDevice(remote_device_address());
252 }
253
254 BluetoothGattService* BluetoothLowEnergyConnection::GetRemoteService() {
255 BluetoothDevice* remote_device = GetRemoteDevice();
256 if (!remote_device) {
257 VLOG(1) << "device not found";
258 return NULL;
259 }
260 return remote_device->GetGattService(remote_service_id_);
261 }
262
263 BluetoothGattCharacteristic*
264 BluetoothLowEnergyConnection::GetGattCharacteristic(
265 const std::string& gatt_characteristic) {
266 BluetoothGattService* remote_service = GetRemoteService();
267 if (!remote_service) {
268 VLOG(1) << "service not found";
269 return NULL;
270 }
271 return remote_service->GetCharacteristic(gatt_characteristic);
272 }
273
274 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698