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

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

Issue 2075313002: Substituting legacy protocol with uWeave protocol (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updated gyp build files Created 4 years, 5 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 2016 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_weave_client_connec tion.h"
6
7 #include <utility>
8
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/task_runner.h"
12 #include "base/threading/thread_task_runner_handle.h"
13 #include "components/proximity_auth/bluetooth_throttler.h"
14 #include "components/proximity_auth/connection_finder.h"
15 #include "components/proximity_auth/logging/logging.h"
16 #include "components/proximity_auth/wire_message.h"
17 #include "device/bluetooth/bluetooth_gatt_connection.h"
18
19 using device::BluetoothAdapter;
20 using device::BluetoothDevice;
21 using device::BluetoothGattConnection;
22 using device::BluetoothRemoteGattService;
23 using device::BluetoothRemoteGattCharacteristic;
24 using device::BluetoothGattNotifySession;
25 using device::BluetoothUUID;
26
27 namespace proximity_auth {
28 namespace weave {
29 namespace {
30
31 typedef BluetoothLowEnergyWeavePacketReceiver::State ReceiverState;
32
33 const int kDefaultMessageCounter = 0;
34
35 // The UUID of the TX characteristic used to transmit data to the server.
36 const char kTXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000101";
37
38 // The UUID of the RX characteristic used to receive data from the server.
39 const char kRXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000102";
40
41 } // namespace
42
43 BluetoothLowEnergyWeaveClientConnection::
44 BluetoothLowEnergyWeaveClientConnection(
45 const RemoteDevice& device,
46 scoped_refptr<device::BluetoothAdapter> adapter,
47 const BluetoothUUID remote_service_uuid,
48 BluetoothThrottler* bluetooth_throttler,
49 int max_number_of_write_attempts)
50 : Connection(device),
51 adapter_(adapter),
52 remote_service_({remote_service_uuid, ""}),
53 packet_generator_(
54 BluetoothLowEnergyWeavePacketGenerator::Factory::NewInstance()),
55 packet_receiver_(
56 BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance(
57 BluetoothLowEnergyWeavePacketReceiver::ReceiverType::CLIENT)),
58 tx_characteristic_({BluetoothUUID(kTXCharacteristicUUID), ""}),
59 rx_characteristic_({BluetoothUUID(kRXCharacteristicUUID), ""}),
60 bluetooth_throttler_(bluetooth_throttler),
61 task_runner_(base::ThreadTaskRunnerHandle::Get()),
62 sub_status_(SubStatus::DISCONNECTED),
63 write_remote_characteristic_pending_(false),
64 next_message_counter_to_use_(kDefaultMessageCounter + 1),
65 max_number_of_write_attempts_(max_number_of_write_attempts),
66 weak_ptr_factory_(this) {
67 DCHECK(adapter_);
68 DCHECK(adapter_->IsInitialized());
69
70 adapter_->AddObserver(this);
71 }
72
73 BluetoothLowEnergyWeaveClientConnection::
74 ~BluetoothLowEnergyWeaveClientConnection() {
75 // Since the destructor can be called at anytime, it would be unwise to send a
76 // connection since we might not be connected at all.
Tim Song 2016/07/21 20:49:34 "it would be unwise to send a connection" What do
jingxuy 2016/07/21 21:30:34 Done.
77 DestroyConnection();
78
79 if (adapter_) {
80 adapter_->RemoveObserver(this);
81 adapter_ = NULL;
82 }
83 }
84
85 void BluetoothLowEnergyWeaveClientConnection::Connect() {
86 DCHECK(sub_status() == SubStatus::DISCONNECTED);
87
88 SetSubStatus(SubStatus::WAITING_GATT_CONNECTION);
89 base::TimeDelta throttler_delay = bluetooth_throttler_->GetDelay();
90 PA_LOG(INFO) << "Connecting in " << throttler_delay;
91
92 start_time_ = base::TimeTicks::Now();
93
94 // If necessary, wait to create a new GATT connection.
95 //
96 // Avoid creating a new GATT connection immediately after a given device was
97 // disconnected. This is a workaround for crbug.com/508919.
98 if (!throttler_delay.is_zero()) {
99 task_runner_->PostDelayedTask(
100 FROM_HERE,
101 base::Bind(
102 &BluetoothLowEnergyWeaveClientConnection::CreateGattConnection,
103 weak_ptr_factory_.GetWeakPtr()),
104 throttler_delay);
105 return;
106 }
107
108 CreateGattConnection();
109 }
110
111 void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() {
112 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
113
114 BluetoothDevice* remote_device = GetRemoteDevice();
115 if (remote_device) {
Tim Song 2016/07/21 20:49:35 If remote_device == null, we should call DestroyCo
jingxuy 2016/07/21 21:30:34 DestroyConnection destroys a gatt connection. so i
Tim Song 2016/07/22 00:52:50 It also calls SetStatus(DISCONNECTED), which would
jingxuy 2016/07/22 17:14:59 Done.
116 PA_LOG(INFO) << "Creating GATT connection with "
117 << remote_device->GetAddress();
118
119 remote_device->CreateGattConnection(
120 base::Bind(
121 &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
122 weak_ptr_factory_.GetWeakPtr()),
123 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
124 OnCreateGattConnectionError,
125 weak_ptr_factory_.GetWeakPtr()));
126 }
127 }
128
129 void BluetoothLowEnergyWeaveClientConnection::Disconnect() {
130 if (sub_status_ == SubStatus::CONNECTED) {
131 // Friendly disconnect by sending a connection close and then destroy the
132 // the connection once the connection close has been sent.
133 WriteRequest request(packet_generator_->CreateConnectionClose(
134 ReasonForClose::CLOSE_WITHOUT_ERROR),
135 WriteRequestType::CONNECTION_CLOSE);
136 WriteRemoteCharacteristic(request);
137 } else {
138 DestroyConnection();
139 }
140 }
141
142 void BluetoothLowEnergyWeaveClientConnection::DestroyConnection() {
143 if (sub_status() != SubStatus::DISCONNECTED) {
144 weak_ptr_factory_.InvalidateWeakPtrs();
145 StopNotifySession();
146 characteristic_finder_.reset();
147 if (gatt_connection_) {
148 PA_LOG(INFO) << "Disconnect from device "
149 << gatt_connection_->GetDeviceAddress();
150
151 // Destroying BluetoothGattConnection also disconnects it.
152 gatt_connection_.reset();
153 }
154
155 // Only transition to the DISCONNECTED state after perfoming all necessary
156 // operations. Otherwise, it'll trigger observers that can pontentially
157 // destroy the current instance (causing a crash).
158 SetSubStatus(SubStatus::DISCONNECTED);
159 }
160 }
161
162 void BluetoothLowEnergyWeaveClientConnection::SetSubStatus(
163 SubStatus new_sub_status) {
164 sub_status_ = new_sub_status;
165
166 // Sets the status of parent class proximity_auth::Connection accordingly.
167 if (new_sub_status == SubStatus::CONNECTED) {
168 SetStatus(Status::CONNECTED);
169 } else if (new_sub_status == SubStatus::DISCONNECTED) {
170 SetStatus(Status::DISCONNECTED);
171 } else {
172 SetStatus(Status::IN_PROGRESS);
173 }
174 }
175
176 void BluetoothLowEnergyWeaveClientConnection::SetTaskRunnerForTesting(
177 scoped_refptr<base::TaskRunner> task_runner) {
178 task_runner_ = task_runner;
179 }
180
181 void BluetoothLowEnergyWeaveClientConnection::SendMessageImpl(
182 std::unique_ptr<WireMessage> message) {
183 PA_LOG(INFO) << "Sending message " << message->Serialize();
184 std::string serialized_msg = message->Serialize();
185
186 int current_message_counter = next_message_counter_to_use_;
187 next_message_counter_to_use_++;
188
189 // Transfer ownership of message to the unique_ptr in map_to_message_,
190 // message will contain nullptr.
191 map_to_message_.insert(std::pair<int, std::unique_ptr<WireMessage>>(
192 current_message_counter, std::move(message)));
193
194 std::vector<Packet> packets =
195 packet_generator_->EncodeDataMessage(serialized_msg);
196
197 for (uint32_t i = 0; i < packets.size(); ++i) {
198 WriteRequestType request_type = (i == packets.size() - 1)
199 ? WriteRequestType::MESSAGE_COMPLETE
200 : WriteRequestType::REGULAR;
201 WriteRequest request =
202 WriteRequest(packets[i], request_type, current_message_counter);
203 WriteRemoteCharacteristic(request);
204 }
205 }
206
207 // Changes in the GATT connection with the remote device should be observed
208 // here. If the GATT connection is dropped, we should call DestroyConnection()
209 // anyway, so the object can notify its observers.
210 void BluetoothLowEnergyWeaveClientConnection::DeviceChanged(
211 BluetoothAdapter* adapter,
212 BluetoothDevice* device) {
213 DCHECK(device);
214 if (sub_status() == SubStatus::DISCONNECTED ||
215 device->GetAddress() != GetDeviceAddress())
216 return;
217
218 if (sub_status() != SubStatus::WAITING_GATT_CONNECTION &&
219 !device->IsConnected()) {
220 PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress()
221 << "\ndevice connected: " << device->IsConnected()
222 << "\ngatt connection: "
223 << (gatt_connection_ ? gatt_connection_->IsConnected()
224 : false);
225 DestroyConnection();
226 }
227 }
228
229 void BluetoothLowEnergyWeaveClientConnection::DeviceRemoved(
230 BluetoothAdapter* adapter,
231 BluetoothDevice* device) {
232 DCHECK(device);
233 if (sub_status_ == SubStatus::DISCONNECTED ||
234 device->GetAddress() != GetDeviceAddress())
235 return;
236
237 PA_LOG(INFO) << "Device removed " << GetDeviceAddress();
238 DestroyConnection();
239 }
240
241 void BluetoothLowEnergyWeaveClientConnection::GattCharacteristicValueChanged(
242 BluetoothAdapter* adapter,
243 BluetoothRemoteGattCharacteristic* characteristic,
244 const Packet& value) {
245 DCHECK_EQ(adapter, adapter_.get());
246 if (sub_status() != SubStatus::WAITING_CONNECTION_RESPONSE &&
247 sub_status() != SubStatus::CONNECTED)
248 return;
249
250 PA_LOG(INFO) << "Characteristic value changed: "
251 << characteristic->GetUUID().canonical_value();
252
253 if (characteristic->GetIdentifier() == rx_characteristic_.id) {
254 ReceiverState state = packet_receiver_->ReceivePacket(value);
255
256 PA_LOG(INFO) << "\nReceiver State: " << state;
257 switch (state) {
258 case ReceiverState::DATA_READY:
259 OnBytesReceived(packet_receiver_->GetDataMessage());
260 break;
261 case ReceiverState::CONNECTION_CLOSED:
262 PA_LOG(ERROR) << "Connection closed due to: " << GetReasonForClose();
263 DestroyConnection();
264 break;
265 case ReceiverState::ERROR_DETECTED:
266 OnPacketReceiverError();
267 break;
268 case ReceiverState::WAITING:
269 // Receiver state should have changed from CONNECTING to WAITING if
270 // a proper connection response had been received.
271 // The max packet size selected from the connection response will be
272 // used to generate future data packets.
273 packet_generator_->SetMaxPacketSize(
274 packet_receiver_->GetMaxPacketSize());
275 DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE);
276 CompleteConnection();
277 break;
278 case ReceiverState::RECEIVING_DATA:
279 // Normal in between states, so do nothing.
280 break;
281 default:
282 NOTREACHED();
283 }
284 }
285 }
286
287 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
Tim Song 2016/07/21 20:49:35 nit: move these WriteRequest definitions below all
jingxuy 2016/07/21 21:30:34 Done.
288 const Packet& val,
289 WriteRequestType request_type,
290 int message_counter)
291 : value(val),
292 request_type(request_type),
293 message_counter(message_counter),
294 number_of_failed_attempts(0) {}
295
296 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
297 const Packet& val,
298 WriteRequestType request_type)
299 : value(val),
300 request_type(request_type),
301 message_counter(kDefaultMessageCounter),
302 number_of_failed_attempts(0) {}
303
304 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
305 const WriteRequest& other) = default;
306
307 BluetoothLowEnergyWeaveClientConnection::WriteRequest::~WriteRequest() {}
308
309 void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() {
310 PA_LOG(INFO) << "Connection completed. Time elapsed: "
311 << base::TimeTicks::Now() - start_time_;
312 SetSubStatus(SubStatus::CONNECTED);
313 }
314
315 void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
316 device::BluetoothDevice::ConnectErrorCode error_code) {
317 DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
318 PA_LOG(WARNING) << "Error creating GATT connection to "
319 << remote_device().bluetooth_address
320 << "error code: " << error_code;
Tim Song 2016/07/21 20:49:34 nit: extra space or comma before "error code: "
jingxuy 2016/07/21 21:30:34 Done.
321 DestroyConnection();
322 }
323
324 void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated(
325 std::unique_ptr<device::BluetoothGattConnection> gatt_connection) {
326 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
327 PA_LOG(INFO) << "GATT connection with " << gatt_connection->GetDeviceAddress()
328 << " created.";
329 PrintTimeElapsed();
330
331 // Informing |bluetooth_trottler_| a new connection was established.
332 bluetooth_throttler_->OnConnection(this);
333
334 gatt_connection_ = std::move(gatt_connection);
Tim Song 2016/07/21 20:49:34 nit: You don't need the std::move() call. By defau
jingxuy 2016/07/21 21:30:34 Done.
335 SetSubStatus(SubStatus::WAITING_CHARACTERISTICS);
336 characteristic_finder_.reset(CreateCharacteristicsFinder(
337 base::Bind(
338 &BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound,
339 weak_ptr_factory_.GetWeakPtr()),
340 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
341 OnCharacteristicsFinderError,
342 weak_ptr_factory_.GetWeakPtr())));
343 }
344
345 BluetoothLowEnergyCharacteristicsFinder*
346 BluetoothLowEnergyWeaveClientConnection::CreateCharacteristicsFinder(
347 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback&
348 success_callback,
349 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback&
350 error_callback) {
351 return new BluetoothLowEnergyCharacteristicsFinder(
352 adapter_, GetRemoteDevice(), remote_service_, tx_characteristic_,
353 rx_characteristic_, success_callback, error_callback);
354 }
355
356 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound(
357 const RemoteAttribute& service,
358 const RemoteAttribute& tx_characteristic,
359 const RemoteAttribute& rx_characteristic) {
360 PA_LOG(INFO) << "Remote chacteristics found.";
361 PrintTimeElapsed();
362
363 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
364 remote_service_ = service;
365 tx_characteristic_ = tx_characteristic;
366 rx_characteristic_ = rx_characteristic;
367
368 SetSubStatus(SubStatus::CHARACTERISTICS_FOUND);
369 StartNotifySession();
370 }
371
372 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFinderError(
373 const RemoteAttribute& tx_characteristic,
374 const RemoteAttribute& rx_characteristic) {
375 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
376 PA_LOG(WARNING) << "Connection error, missing characteristics for SmartLock "
377 "service.\n"
378 << (tx_characteristic.id.empty()
Tim Song 2016/07/21 20:49:35 nit: put new lines or spaces between each characte
jingxuy 2016/07/21 21:30:33 Done.
379 ? tx_characteristic.uuid.canonical_value()
380 : "")
381 << (rx_characteristic.id.empty()
382 ? ", " + rx_characteristic.uuid.canonical_value()
383 : "")
384 << " not found.";
385
386 DestroyConnection();
387 }
388
389 void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() {
390 if (sub_status() == SubStatus::CHARACTERISTICS_FOUND) {
Tim Song 2016/07/21 20:49:34 DCHECK() this state instead. Can StartNotifySessio
jingxuy 2016/07/21 21:30:34 Done.
391 BluetoothRemoteGattCharacteristic* characteristic =
392 GetGattCharacteristic(rx_characteristic_.id);
393 DCHECK(characteristic);
Tim Song 2016/07/21 20:49:34 nit: might as well do a full CHECK here, as we're
jingxuy 2016/07/21 21:30:34 A lot of your comments are on legacy code. Sorry I
394
395 // This is a workaround for crbug.com/507325. If |characteristic| is already
396 // notifying |characteristic->StartNotifySession()| will fail with
397 // GATT_ERROR_FAILED.
398 if (characteristic->IsNotifying()) {
399 PA_LOG(INFO) << characteristic->GetUUID().canonical_value()
400 << " already notifying.";
401 SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
402 SendConnectionRequest();
403 return;
404 }
405
406 SetSubStatus(SubStatus::WAITING_NOTIFY_SESSION);
407 characteristic->StartNotifySession(
408 base::Bind(
409 &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted,
410 weak_ptr_factory_.GetWeakPtr()),
411 base::Bind(
412 &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError,
413 weak_ptr_factory_.GetWeakPtr()));
414 }
415 }
416
417 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
418 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
419 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
420 PA_LOG(INFO) << "Notification session started "
421 << notify_session->GetCharacteristicIdentifier();
422 PrintTimeElapsed();
423
424 SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
425 notify_session_ = std::move(notify_session);
Tim Song 2016/07/21 20:49:35 nit: no need for std::move
jingxuy 2016/07/21 21:30:34 also legacy code. Done.
jingxuy 2016/07/22 17:14:59 Also wasn't thinking clearly yesterday. On second
Tim Song 2016/07/22 18:41:34 Ah I see, I was thinking of scoped_ptr, which has
426
427 SendConnectionRequest();
428 }
429
430 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError(
431 BluetoothRemoteGattService::GattErrorCode error) {
432 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
433 PA_LOG(WARNING) << "Error starting notification session: " << error;
434 DestroyConnection();
435 }
436
437 void BluetoothLowEnergyWeaveClientConnection::StopNotifySession() {
438 if (notify_session_) {
439 notify_session_->Stop(base::Bind(&base::DoNothing));
440 notify_session_.reset();
441 }
442 }
443
444 void BluetoothLowEnergyWeaveClientConnection::SendConnectionRequest() {
445 if (sub_status() == SubStatus::NOTIFY_SESSION_READY) {
446 PA_LOG(INFO) << "Sending connection request to the server";
447 SetSubStatus(SubStatus::WAITING_CONNECTION_RESPONSE);
448
449 WriteRequest write_request =
450 WriteRequest(packet_generator_->CreateConnectionRequest(),
451 WriteRequestType::CONNECTION_REQUEST);
452
453 WriteRemoteCharacteristic(write_request);
454 }
455 }
456
457 void BluetoothLowEnergyWeaveClientConnection::WriteRemoteCharacteristic(
458 const WriteRequest& request) {
459 write_requests_queue_.push(request);
460 ProcessNextWriteRequest();
461 }
462
463 void BluetoothLowEnergyWeaveClientConnection::ProcessNextWriteRequest() {
464 BluetoothRemoteGattCharacteristic* characteristic =
465 GetGattCharacteristic(tx_characteristic_.id);
466 if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ &&
467 characteristic) {
468 write_remote_characteristic_pending_ = true;
469 WriteRequest next_request = write_requests_queue_.front();
470
471 PA_LOG(INFO) << "Writing characteristic...";
Tim Song 2016/07/21 20:49:35 nit: it would be nice to log the number of bytes w
jingxuy 2016/07/21 21:30:34 Done.
472 characteristic->WriteRemoteCharacteristic(
473 next_request.value,
474 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
475 OnRemoteCharacteristicWritten,
476 weak_ptr_factory_.GetWeakPtr(), next_request.request_type,
477 next_request.message_counter),
478 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
479 OnWriteRemoteCharacteristicError,
480 weak_ptr_factory_.GetWeakPtr(), next_request.request_type,
481 next_request.message_counter));
482 }
483 }
484
485 void BluetoothLowEnergyWeaveClientConnection::OnRemoteCharacteristicWritten(
486 WriteRequestType request_type,
487 int message_counter) {
488 PA_LOG(INFO) << "Characteristic written.";
489
490 switch (request_type) {
491 case WriteRequestType::REGULAR:
492 case WriteRequestType::CONNECTION_REQUEST:
493 break;
494 case WriteRequestType::MESSAGE_COMPLETE:
495 OnDidSendMessage(*map_to_message_[message_counter], true);
496 map_to_message_.erase(message_counter);
497 break;
498 case WriteRequestType::CONNECTION_CLOSE:
499 DestroyConnection();
500 break;
501 default:
502 NOTREACHED();
503 }
504
505 // Removes the top of queue (already processed) and process the next request.
506 DCHECK(!write_requests_queue_.empty());
507 write_requests_queue_.pop();
508 write_remote_characteristic_pending_ = false;
509 ProcessNextWriteRequest();
510 }
511
512 void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
513 WriteRequestType request_type,
514 int message_counter,
515 BluetoothRemoteGattService::GattErrorCode error) {
516 PA_LOG(WARNING) << "Error " << error << " writing characteristic: "
517 << tx_characteristic_.uuid.canonical_value();
518
519 write_remote_characteristic_pending_ = false;
520
521 // Increases the number of failed attempts and retry.
522 DCHECK(!write_requests_queue_.empty());
523 if (++write_requests_queue_.front().number_of_failed_attempts >=
524 max_number_of_write_attempts_) {
525 switch (request_type) {
526 case WriteRequestType::REGULAR:
527 case WriteRequestType::MESSAGE_COMPLETE:
528 OnDidSendMessage(*map_to_message_[message_counter], false);
529 map_to_message_.erase(message_counter);
530 break;
531 case WriteRequestType::CONNECTION_CLOSE:
532 case WriteRequestType::CONNECTION_REQUEST:
533 break;
534 default:
535 NOTREACHED();
536 }
537
538 // If the previous write failed that many times, probably can't write a
539 // connection close either, so just destroy the connection.
540 DestroyConnection();
541 } else {
542 ProcessNextWriteRequest();
543 }
544 }
545
546 void BluetoothLowEnergyWeaveClientConnection::OnPacketReceiverError() {
547 PA_LOG(ERROR) << "Received erroneous packet. Closing connection.";
548
549 WriteRequest request(packet_generator_->CreateConnectionClose(
550 packet_receiver_->GetReasonToClose()),
551 WriteRequestType::CONNECTION_CLOSE);
552
553 // Skip all other writes that's not in progress.
554
555 // C++ queue does not have a clear method.
556 // According to stackoverflow
557 // "http://stackoverflow.com/questions/709146/how-do-i-clear-the-stdqueue-
558 // efficiently"
559 std::queue<WriteRequest> empty;
560 std::swap(write_requests_queue_, empty);
561
562 if (write_remote_characteristic_pending_) {
563 // Add the in progress write back to the queue.
564 write_requests_queue_.push(empty.front());
565 }
566
567 WriteRemoteCharacteristic(request);
568 }
569
570 void BluetoothLowEnergyWeaveClientConnection::PrintTimeElapsed() {
571 PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_;
572 }
573
574 std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() {
575 // When the remote device is connected we should rely on the address given by
576 // |gatt_connection_|. As the device address may change if the device is
577 // paired. The address in |gatt_connection_| is automatically updated in this
578 // case.
579 return gatt_connection_ ? gatt_connection_->GetDeviceAddress()
580 : remote_device().bluetooth_address;
581 }
582
583 BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() {
584 // It's not possible to simply use
585 // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
586 // address |GetDeviceAddress()|. For paired devices,
587 // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
588 // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
589 // bug in the way device::BluetoothAdapter is storing the devices (see
590 // crbug.com/497841).
591 std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
592 for (const auto& device : devices) {
593 if (device->GetAddress() == GetDeviceAddress())
594 return device;
595 }
596
597 return nullptr;
598 }
599
600 BluetoothRemoteGattService*
601 BluetoothLowEnergyWeaveClientConnection::GetRemoteService() {
602 BluetoothDevice* remote_device = GetRemoteDevice();
603 if (!remote_device) {
604 PA_LOG(WARNING) << "Remote device not found.";
605 return NULL;
606 }
607 if (remote_service_.id.empty()) {
608 std::vector<BluetoothRemoteGattService*> services =
609 remote_device->GetGattServices();
610 for (const auto& service : services)
611 if (service->GetUUID() == remote_service_.uuid) {
612 remote_service_.id = service->GetIdentifier();
613 break;
614 }
615 }
616 return remote_device->GetGattService(remote_service_.id);
617 }
618
619 BluetoothRemoteGattCharacteristic*
620 BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic(
621 const std::string& gatt_characteristic) {
622 BluetoothRemoteGattService* remote_service = GetRemoteService();
623 if (!remote_service) {
624 PA_LOG(WARNING) << "Remote service not found.";
625 return NULL;
626 }
627 return remote_service->GetCharacteristic(gatt_characteristic);
628 }
629
630 std::string BluetoothLowEnergyWeaveClientConnection::GetReasonForClose() {
631 switch (packet_receiver_->GetReasonForClose()) {
632 case ReasonForClose::CLOSE_WITHOUT_ERROR:
633 return "CLOSE_WITHOUT_ERROR";
634 case ReasonForClose::UNKNOWN_ERROR:
635 return "UNKNOWN_ERROR";
636 case ReasonForClose::NO_COMMON_VERSION_SUPPORTED:
637 return "NO_COMMON_VERSION_SUPPORTED";
638 case ReasonForClose::RECEIVED_PACKET_OUT_OF_SEQUENCE:
639 return "RECEIVED_PACKET_OUT_OF_SEQUENCE";
640 case ReasonForClose::APPLICATION_ERROR:
641 return "APPLICATION_ERROR";
642 default:
643 NOTREACHED();
644 }
645 }
646
647 } // namespace weave
648
649 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698