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

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

Powered by Google App Engine
This is Rietveld 408576698