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

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

Powered by Google App Engine
This is Rietveld 408576698