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

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: added test with OnDidSendMessage observer 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.
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) {
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(
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;
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);
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()
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) {
391 BluetoothRemoteGattCharacteristic* characteristic =
392 GetGattCharacteristic(rx_characteristic_.id);
393 DCHECK(characteristic);
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);
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::REGULAR);
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...";
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 break;
493 case WriteRequestType::MESSAGE_COMPLETE:
494 OnDidSendMessage(*map_to_message_[message_counter], true);
495 map_to_message_.erase(message_counter);
496 break;
497 case WriteRequestType::CONNECTION_CLOSE:
498 DestroyConnection();
499 break;
500 default:
501 NOTREACHED();
502 }
503
504 // Removes the top of queue (already processed) and process the next request.
505 DCHECK(!write_requests_queue_.empty());
506 write_requests_queue_.pop();
507 write_remote_characteristic_pending_ = false;
508 ProcessNextWriteRequest();
509 }
510
511 void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
512 WriteRequestType request_type,
513 int message_counter,
514 BluetoothRemoteGattService::GattErrorCode error) {
515 PA_LOG(WARNING) << "Error " << error << " writing characteristic: "
516 << tx_characteristic_.uuid.canonical_value();
517
518 switch (request_type) {
519 case WriteRequestType::REGULAR:
520 break;
521 case WriteRequestType::MESSAGE_COMPLETE:
522 PA_LOG(ERROR) << "I'm here ";
Kyle Horimoto 2016/07/16 00:46:56 nit: Remove test logs.
jingxuy 2016/07/16 00:54:53 Done.
523 OnDidSendMessage(*map_to_message_[message_counter], false);
524 break;
525 case WriteRequestType::CONNECTION_CLOSE:
526 break;
527 default:
528 NOTREACHED();
529 }
530
531 write_remote_characteristic_pending_ = false;
532
533 // Increases the number of failed attempts and retry.
534 DCHECK(!write_requests_queue_.empty());
535 if (++write_requests_queue_.front().number_of_failed_attempts >=
536 max_number_of_write_attempts_) {
537 // If the previous write failed that many times, probably can't write a
538 // connection close either, so just destroy the connection.
539 DestroyConnection();
540 } else {
541 ProcessNextWriteRequest();
542 }
543 }
544
545 void BluetoothLowEnergyWeaveClientConnection::OnPacketReceiverError() {
546 PA_LOG(ERROR) << "Received erroneous packet. Closing connection.";
547
548 WriteRequest request(packet_generator_->CreateConnectionClose(
549 packet_receiver_->GetReasonToClose()),
550 WriteRequestType::CONNECTION_CLOSE);
551
552 // Skip all other writes that's not in progress.
553
554 // C++ queue does not have a clear method.
555 // According to stackoverflow
556 // "http://stackoverflow.com/questions/709146/how-do-i-clear-the-stdqueue-
557 // efficiently"
558 std::queue<WriteRequest> empty;
559 std::swap(write_requests_queue_, empty);
560
561 if (write_remote_characteristic_pending_) {
562 // Add the in progress write back to the queue.
563 write_requests_queue_.push(empty.front());
564 }
565
566 WriteRemoteCharacteristic(request);
567 }
568
569 void BluetoothLowEnergyWeaveClientConnection::PrintTimeElapsed() {
570 PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_;
571 }
572
573 std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() {
574 // When the remote device is connected we should rely on the address given by
575 // |gatt_connection_|. As the device address may change if the device is
576 // paired. The address in |gatt_connection_| is automatically updated in this
577 // case.
578 return gatt_connection_ ? gatt_connection_->GetDeviceAddress()
579 : remote_device().bluetooth_address;
580 }
581
582 BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() {
583 // It's not possible to simply use
584 // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
585 // address |GetDeviceAddress()|. For paired devices,
586 // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
587 // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
588 // bug in the way device::BluetoothAdapter is storing the devices (see
589 // crbug.com/497841).
590 std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
591 for (const auto& device : devices) {
592 if (device->GetAddress() == GetDeviceAddress())
593 return device;
594 }
595
596 return nullptr;
597 }
598
599 BluetoothRemoteGattService*
600 BluetoothLowEnergyWeaveClientConnection::GetRemoteService() {
601 BluetoothDevice* remote_device = GetRemoteDevice();
602 if (!remote_device) {
603 PA_LOG(WARNING) << "Remote device not found.";
604 return NULL;
605 }
606 if (remote_service_.id.empty()) {
607 std::vector<BluetoothRemoteGattService*> services =
608 remote_device->GetGattServices();
609 for (const auto& service : services)
610 if (service->GetUUID() == remote_service_.uuid) {
611 remote_service_.id = service->GetIdentifier();
612 break;
613 }
614 }
615 return remote_device->GetGattService(remote_service_.id);
616 }
617
618 BluetoothRemoteGattCharacteristic*
619 BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic(
620 const std::string& gatt_characteristic) {
621 BluetoothRemoteGattService* remote_service = GetRemoteService();
622 if (!remote_service) {
623 PA_LOG(WARNING) << "Remote service not found.";
624 return NULL;
625 }
626 return remote_service->GetCharacteristic(gatt_characteristic);
627 }
628
629 std::string BluetoothLowEnergyWeaveClientConnection::GetReasonForClose() {
630 switch (packet_receiver_->GetReasonForClose()) {
631 case ReasonForClose::CLOSE_WITHOUT_ERROR:
632 return "CLOSE_WITHOUT_ERROR";
633 case ReasonForClose::UNKNOWN_ERROR:
634 return "UNKNOWN_ERROR";
635 case ReasonForClose::NO_COMMON_VERSION_SUPPORTED:
636 return "NO_COMMON_VERSION_SUPPORTED";
637 case ReasonForClose::RECEIVED_PACKET_OUT_OF_SEQUENCE:
638 return "RECEIVED_PACKET_OUT_OF_SEQUENCE";
639 case ReasonForClose::APPLICATION_ERROR:
640 return "APPLICATION_ERROR";
641 default:
642 NOTREACHED();
643 }
644 }
645
646 } // namespace weave
647
648 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698