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

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: addressed minor style comments 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 close 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 void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() {
288 PA_LOG(INFO) << "Connection completed. Time elapsed: "
289 << base::TimeTicks::Now() - start_time_;
290 SetSubStatus(SubStatus::CONNECTED);
291 }
292
293 void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
294 device::BluetoothDevice::ConnectErrorCode error_code) {
295 DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
296 PA_LOG(WARNING) << "Error creating GATT connection to "
297 << remote_device().bluetooth_address
298 << " error code: " << error_code;
299 DestroyConnection();
300 }
301
302 void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated(
303 std::unique_ptr<device::BluetoothGattConnection> gatt_connection) {
304 DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
305 PA_LOG(INFO) << "GATT connection with " << gatt_connection->GetDeviceAddress()
306 << " created.";
307 PrintTimeElapsed();
308
309 // Informing |bluetooth_trottler_| a new connection was established.
310 bluetooth_throttler_->OnConnection(this);
311
312 gatt_connection_ = gatt_connection;
313 SetSubStatus(SubStatus::WAITING_CHARACTERISTICS);
314 characteristic_finder_.reset(CreateCharacteristicsFinder(
315 base::Bind(
316 &BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound,
317 weak_ptr_factory_.GetWeakPtr()),
318 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
319 OnCharacteristicsFinderError,
320 weak_ptr_factory_.GetWeakPtr())));
321 }
322
323 BluetoothLowEnergyCharacteristicsFinder*
324 BluetoothLowEnergyWeaveClientConnection::CreateCharacteristicsFinder(
325 const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback&
326 success_callback,
327 const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback&
328 error_callback) {
329 return new BluetoothLowEnergyCharacteristicsFinder(
330 adapter_, GetRemoteDevice(), remote_service_, tx_characteristic_,
331 rx_characteristic_, success_callback, error_callback);
332 }
333
334 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound(
335 const RemoteAttribute& service,
336 const RemoteAttribute& tx_characteristic,
337 const RemoteAttribute& rx_characteristic) {
338 PA_LOG(INFO) << "Remote chacteristics found.";
339 PrintTimeElapsed();
340
341 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
342 remote_service_ = service;
343 tx_characteristic_ = tx_characteristic;
344 rx_characteristic_ = rx_characteristic;
345
346 SetSubStatus(SubStatus::CHARACTERISTICS_FOUND);
347 StartNotifySession();
348 }
349
350 void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFinderError(
351 const RemoteAttribute& tx_characteristic,
352 const RemoteAttribute& rx_characteristic) {
353 DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
354 PA_LOG(WARNING) << "Connection error, missing characteristics for SmartLock "
355 "service.\n"
356 << (tx_characteristic.id.empty()
357 ? tx_characteristic.uuid.canonical_value()
358 : "")
359 << ", "
360 << (rx_characteristic.id.empty()
361 ? ", " + rx_characteristic.uuid.canonical_value()
362 : "")
363 << " not found.";
364
365 DestroyConnection();
366 }
367
368 void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() {
369 DCHECK(sub_status() == SubStatus::CHARACTERISTICS_FOUND);
370 BluetoothRemoteGattCharacteristic* characteristic =
371 GetGattCharacteristic(rx_characteristic_.id);
372 CHECK(characteristic);
373
374 // This is a workaround for crbug.com/507325. If |characteristic| is already
375 // notifying |characteristic->StartNotifySession()| will fail with
376 // GATT_ERROR_FAILED.
377 if (characteristic->IsNotifying()) {
378 PA_LOG(INFO) << characteristic->GetUUID().canonical_value()
379 << " already notifying.";
380 SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
381 SendConnectionRequest();
382 return;
383 }
384
385 SetSubStatus(SubStatus::WAITING_NOTIFY_SESSION);
386 characteristic->StartNotifySession(
387 base::Bind(
388 &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted,
389 weak_ptr_factory_.GetWeakPtr()),
390 base::Bind(&BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError,
391 weak_ptr_factory_.GetWeakPtr()));
392 }
393
394 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
395 std::unique_ptr<BluetoothGattNotifySession> notify_session) {
396 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
397 PA_LOG(INFO) << "Notification session started "
398 << notify_session->GetCharacteristicIdentifier();
399 PrintTimeElapsed();
400
401 SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
402 notify_session_ = notify_session;
403
404 SendConnectionRequest();
405 }
406
407 void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError(
408 BluetoothRemoteGattService::GattErrorCode error) {
409 DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
410 PA_LOG(WARNING) << "Error starting notification session: " << error;
411 DestroyConnection();
412 }
413
414 void BluetoothLowEnergyWeaveClientConnection::StopNotifySession() {
415 if (notify_session_) {
416 notify_session_->Stop(base::Bind(&base::DoNothing));
417 notify_session_.reset();
418 }
419 }
420
421 void BluetoothLowEnergyWeaveClientConnection::SendConnectionRequest() {
422 if (sub_status() == SubStatus::NOTIFY_SESSION_READY) {
423 PA_LOG(INFO) << "Sending connection request to the server";
424 SetSubStatus(SubStatus::WAITING_CONNECTION_RESPONSE);
425
426 WriteRequest write_request =
427 WriteRequest(packet_generator_->CreateConnectionRequest(),
428 WriteRequestType::CONNECTION_REQUEST);
429
430 WriteRemoteCharacteristic(write_request);
431 }
432 }
433
434 void BluetoothLowEnergyWeaveClientConnection::WriteRemoteCharacteristic(
435 const WriteRequest& request) {
436 write_requests_queue_.push(request);
437 ProcessNextWriteRequest();
438 }
439
440 void BluetoothLowEnergyWeaveClientConnection::ProcessNextWriteRequest() {
441 BluetoothRemoteGattCharacteristic* characteristic =
442 GetGattCharacteristic(tx_characteristic_.id);
443 if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ &&
444 characteristic) {
445 write_remote_characteristic_pending_ = true;
446 WriteRequest next_request = write_requests_queue_.front();
447
448 PA_LOG(INFO) << "Writing to characteristic " << value.size() << " bytes";
449 characteristic->WriteRemoteCharacteristic(
450 next_request.value,
451 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
452 OnRemoteCharacteristicWritten,
453 weak_ptr_factory_.GetWeakPtr(), next_request.request_type,
454 next_request.message_counter),
455 base::Bind(&BluetoothLowEnergyWeaveClientConnection::
456 OnWriteRemoteCharacteristicError,
457 weak_ptr_factory_.GetWeakPtr(), next_request.request_type,
458 next_request.message_counter));
459 }
460 }
461
462 void BluetoothLowEnergyWeaveClientConnection::OnRemoteCharacteristicWritten(
463 WriteRequestType request_type,
464 int message_counter) {
465 PA_LOG(INFO) << "Characteristic written.";
466
467 switch (request_type) {
468 case WriteRequestType::REGULAR:
469 case WriteRequestType::CONNECTION_REQUEST:
470 break;
471 case WriteRequestType::MESSAGE_COMPLETE:
472 OnDidSendMessage(*map_to_message_[message_counter], true);
473 map_to_message_.erase(message_counter);
474 break;
475 case WriteRequestType::CONNECTION_CLOSE:
476 DestroyConnection();
477 break;
478 default:
479 NOTREACHED();
480 }
481
482 // Removes the top of queue (already processed) and process the next request.
483 DCHECK(!write_requests_queue_.empty());
484 write_requests_queue_.pop();
485 write_remote_characteristic_pending_ = false;
486 ProcessNextWriteRequest();
487 }
488
489 void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
490 WriteRequestType request_type,
491 int message_counter,
492 BluetoothRemoteGattService::GattErrorCode error) {
493 PA_LOG(WARNING) << "Error " << error << " writing characteristic: "
494 << tx_characteristic_.uuid.canonical_value();
495
496 write_remote_characteristic_pending_ = false;
497
498 // Increases the number of failed attempts and retry.
499 DCHECK(!write_requests_queue_.empty());
500 if (++write_requests_queue_.front().number_of_failed_attempts >=
501 max_number_of_write_attempts_) {
502 switch (request_type) {
503 case WriteRequestType::REGULAR:
504 case WriteRequestType::MESSAGE_COMPLETE:
505 OnDidSendMessage(*map_to_message_[message_counter], false);
506 map_to_message_.erase(message_counter);
507 break;
508 case WriteRequestType::CONNECTION_CLOSE:
509 case WriteRequestType::CONNECTION_REQUEST:
510 break;
511 default:
512 NOTREACHED();
513 }
514
515 // If the previous write failed that many times, probably can't write a
516 // connection close either, so just destroy the connection.
517 DestroyConnection();
518 } else {
519 ProcessNextWriteRequest();
520 }
521 }
522
523 void BluetoothLowEnergyWeaveClientConnection::OnPacketReceiverError() {
524 PA_LOG(ERROR) << "Received erroneous packet. Closing connection.";
525
526 WriteRequest request(packet_generator_->CreateConnectionClose(
527 packet_receiver_->GetReasonToClose()),
528 WriteRequestType::CONNECTION_CLOSE);
529
530 // Skip all other writes that's not in progress.
531
532 // C++ queue does not have a clear method.
533 // According to stackoverflow
534 // "http://stackoverflow.com/questions/709146/how-do-i-clear-the-stdqueue-
535 // efficiently"
536 std::queue<WriteRequest> empty;
537 std::swap(write_requests_queue_, empty);
538
539 if (write_remote_characteristic_pending_) {
540 // Add the in progress write back to the queue.
541 write_requests_queue_.push(empty.front());
542 }
543
544 WriteRemoteCharacteristic(request);
545 }
546
547 void BluetoothLowEnergyWeaveClientConnection::PrintTimeElapsed() {
548 PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_;
549 }
550
551 std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() {
552 // When the remote device is connected we should rely on the address given by
553 // |gatt_connection_|. As the device address may change if the device is
554 // paired. The address in |gatt_connection_| is automatically updated in this
555 // case.
556 return gatt_connection_ ? gatt_connection_->GetDeviceAddress()
557 : remote_device().bluetooth_address;
558 }
559
560 BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() {
561 // It's not possible to simply use
562 // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
563 // address |GetDeviceAddress()|. For paired devices,
564 // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
565 // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
566 // bug in the way device::BluetoothAdapter is storing the devices (see
567 // crbug.com/497841).
568 std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
569 for (const auto& device : devices) {
570 if (device->GetAddress() == GetDeviceAddress())
571 return device;
572 }
573
574 return nullptr;
575 }
576
577 BluetoothRemoteGattService*
578 BluetoothLowEnergyWeaveClientConnection::GetRemoteService() {
579 BluetoothDevice* remote_device = GetRemoteDevice();
580 if (!remote_device) {
581 PA_LOG(WARNING) << "Remote device not found.";
582 return NULL;
583 }
584 if (remote_service_.id.empty()) {
585 std::vector<BluetoothRemoteGattService*> services =
586 remote_device->GetGattServices();
587 for (const auto& service : services)
588 if (service->GetUUID() == remote_service_.uuid) {
589 remote_service_.id = service->GetIdentifier();
590 break;
591 }
592 }
593 return remote_device->GetGattService(remote_service_.id);
594 }
595
596 BluetoothRemoteGattCharacteristic*
597 BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic(
598 const std::string& gatt_characteristic) {
599 BluetoothRemoteGattService* remote_service = GetRemoteService();
600 if (!remote_service) {
601 PA_LOG(WARNING) << "Remote service not found.";
602 return NULL;
603 }
604 return remote_service->GetCharacteristic(gatt_characteristic);
605 }
606
607 std::string BluetoothLowEnergyWeaveClientConnection::GetReasonForClose() {
608 switch (packet_receiver_->GetReasonForClose()) {
609 case ReasonForClose::CLOSE_WITHOUT_ERROR:
610 return "CLOSE_WITHOUT_ERROR";
611 case ReasonForClose::UNKNOWN_ERROR:
612 return "UNKNOWN_ERROR";
613 case ReasonForClose::NO_COMMON_VERSION_SUPPORTED:
614 return "NO_COMMON_VERSION_SUPPORTED";
615 case ReasonForClose::RECEIVED_PACKET_OUT_OF_SEQUENCE:
616 return "RECEIVED_PACKET_OUT_OF_SEQUENCE";
617 case ReasonForClose::APPLICATION_ERROR:
618 return "APPLICATION_ERROR";
619 default:
620 NOTREACHED();
621 }
622 }
623
624 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
625 const Packet& val,
626 WriteRequestType request_type,
627 int message_counter)
628 : value(val),
629 request_type(request_type),
630 message_counter(message_counter),
631 number_of_failed_attempts(0) {}
632
633 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
634 const Packet& val,
635 WriteRequestType request_type)
636 : value(val),
637 request_type(request_type),
638 message_counter(kDefaultMessageCounter),
639 number_of_failed_attempts(0) {}
640
641 BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
642 const WriteRequest& other) = default;
643
644 BluetoothLowEnergyWeaveClientConnection::WriteRequest::~WriteRequest() {}
645
646 } // namespace weave
647
648 } // namespace proximity_auth
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698