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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
Index: components/proximity_auth/ble/bluetooth_low_energy_weave_client_connection.cc
diff --git a/components/proximity_auth/ble/bluetooth_low_energy_weave_client_connection.cc b/components/proximity_auth/ble/bluetooth_low_energy_weave_client_connection.cc
new file mode 100644
index 0000000000000000000000000000000000000000..3fde2722609660df66b3ee9544bea3494e224ec2
--- /dev/null
+++ b/components/proximity_auth/ble/bluetooth_low_energy_weave_client_connection.cc
@@ -0,0 +1,639 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/proximity_auth/ble/bluetooth_low_energy_weave_client_connection.h"
+
+#include <utility>
+
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
+#include "components/proximity_auth/bluetooth_throttler.h"
+#include "components/proximity_auth/connection_finder.h"
+#include "components/proximity_auth/logging/logging.h"
+#include "components/proximity_auth/wire_message.h"
+#include "device/bluetooth/bluetooth_gatt_connection.h"
+
+using device::BluetoothAdapter;
+using device::BluetoothDevice;
+using device::BluetoothGattConnection;
+using device::BluetoothRemoteGattService;
+using device::BluetoothRemoteGattCharacteristic;
+using device::BluetoothGattNotifySession;
+using device::BluetoothUUID;
+
+namespace proximity_auth {
+namespace weave {
+namespace {
+
+typedef BluetoothLowEnergyWeavePacketReceiver::State ReceiverState;
+
+// The UUID of the TX characteristic used to transmit data to the server.
+const char kTXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000101";
+
+// The UUID of the RX characteristic used to receive data from the server.
+const char kRXCharacteristicUUID[] = "00000100-0004-1000-8000-001A11000102";
+
+} // namespace
+
+BluetoothLowEnergyWeaveClientConnection::
+ BluetoothLowEnergyWeaveClientConnection(
+ const RemoteDevice& device,
+ scoped_refptr<device::BluetoothAdapter> adapter,
+ const BluetoothUUID remote_service_uuid,
+ BluetoothThrottler* bluetooth_throttler,
+ int max_number_of_write_attempts)
+ : Connection(device),
+ adapter_(adapter),
+ remote_service_({remote_service_uuid, ""}),
+ packet_generator_(
+ BluetoothLowEnergyWeavePacketGenerator::Factory::NewInstance()),
+ packet_receiver_(
+ BluetoothLowEnergyWeavePacketReceiver::Factory::NewInstance(
+ BluetoothLowEnergyWeavePacketReceiver::ReceiverType::CLIENT)),
+ tx_characteristic_({BluetoothUUID(kTXCharacteristicUUID), ""}),
+ rx_characteristic_({BluetoothUUID(kRXCharacteristicUUID), ""}),
+ bluetooth_throttler_(bluetooth_throttler),
+ task_runner_(base::ThreadTaskRunnerHandle::Get()),
+ sub_status_(SubStatus::DISCONNECTED),
+ write_remote_characteristic_pending_(false),
+ max_number_of_write_attempts_(max_number_of_write_attempts),
+ weak_ptr_factory_(this) {
+ DCHECK(adapter_);
+ DCHECK(adapter_->IsInitialized());
+
+ adapter_->AddObserver(this);
+}
+
+BluetoothLowEnergyWeaveClientConnection::
+ ~BluetoothLowEnergyWeaveClientConnection() {
+ // Since the destructor can be called at anytime, it would be unwise to send a
+ // connection close since we might not be connected at all.
+ DestroyConnection();
+
+ if (adapter_) {
+ adapter_->RemoveObserver(this);
+ adapter_ = NULL;
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::Connect() {
+ DCHECK(sub_status() == SubStatus::DISCONNECTED);
+
+ SetSubStatus(SubStatus::WAITING_GATT_CONNECTION);
+ base::TimeDelta throttler_delay = bluetooth_throttler_->GetDelay();
+ PA_LOG(INFO) << "Connecting in " << throttler_delay;
+
+ start_time_ = base::TimeTicks::Now();
+
+ // If necessary, wait to create a new GATT connection.
+ //
+ // Avoid creating a new GATT connection immediately after a given device was
+ // disconnected. This is a workaround for crbug.com/508919.
+ if (!throttler_delay.is_zero()) {
+ task_runner_->PostDelayedTask(
+ FROM_HERE,
+ base::Bind(
+ &BluetoothLowEnergyWeaveClientConnection::CreateGattConnection,
+ weak_ptr_factory_.GetWeakPtr()),
+ throttler_delay);
+ return;
+ }
+
+ CreateGattConnection();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::CreateGattConnection() {
+ DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
+
+ BluetoothDevice* remote_device = GetRemoteDevice();
+ if (remote_device) {
+ PA_LOG(INFO) << "Creating GATT connection with "
+ << remote_device->GetAddress();
+
+ remote_device->CreateGattConnection(
+ base::Bind(
+ &BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::
+ OnCreateGattConnectionError,
+ weak_ptr_factory_.GetWeakPtr()));
+ } else {
+ SetSubStatus(SubStatus::DISCONNECTED);
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::Disconnect() {
+ if (sub_status_ == SubStatus::CONNECTED) {
+ // Friendly disconnect by sending a connection close and then destroy the
+ // the connection once the connection close has been sent.
+ WriteRequest request(packet_generator_->CreateConnectionClose(
+ ReasonForClose::CLOSE_WITHOUT_ERROR),
+ WriteRequestType::CONNECTION_CLOSE);
+ WriteRemoteCharacteristic(request);
+ } else {
+ DestroyConnection();
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::DestroyConnection() {
+ if (sub_status() != SubStatus::DISCONNECTED) {
+ weak_ptr_factory_.InvalidateWeakPtrs();
+ StopNotifySession();
+ characteristic_finder_.reset();
+ if (gatt_connection_) {
+ PA_LOG(INFO) << "Disconnect from device "
+ << gatt_connection_->GetDeviceAddress();
+
+ // Destroying BluetoothGattConnection also disconnects it.
+ gatt_connection_.reset();
+ }
+
+ // Only transition to the DISCONNECTED state after perfoming all necessary
+ // operations. Otherwise, it'll trigger observers that can pontentially
+ // destroy the current instance (causing a crash).
+ SetSubStatus(SubStatus::DISCONNECTED);
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::SetSubStatus(
+ SubStatus new_sub_status) {
+ sub_status_ = new_sub_status;
+
+ // Sets the status of parent class proximity_auth::Connection accordingly.
+ if (new_sub_status == SubStatus::CONNECTED) {
+ SetStatus(Status::CONNECTED);
+ } else if (new_sub_status == SubStatus::DISCONNECTED) {
+ SetStatus(Status::DISCONNECTED);
+ } else {
+ SetStatus(Status::IN_PROGRESS);
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::SetTaskRunnerForTesting(
+ scoped_refptr<base::TaskRunner> task_runner) {
+ task_runner_ = task_runner;
+}
+
+void BluetoothLowEnergyWeaveClientConnection::SendMessageImpl(
+ std::unique_ptr<WireMessage> message) {
+ PA_LOG(INFO) << "Sending message " << message->Serialize();
+ std::string serialized_msg = message->Serialize();
+
+ std::vector<Packet> packets =
+ packet_generator_->EncodeDataMessage(serialized_msg);
+
+ std::shared_ptr<WireMessage> request_message(message.release());
+
+ for (uint32_t i = 0; i < packets.size(); ++i) {
+ WriteRequestType request_type = (i == packets.size() - 1)
+ ? WriteRequestType::MESSAGE_COMPLETE
+ : WriteRequestType::REGULAR;
+ WriteRequest request(packets[i], request_type, request_message);
+ WriteRemoteCharacteristic(request);
+ }
+}
+
+// Changes in the GATT connection with the remote device should be observed
+// here. If the GATT connection is dropped, we should call DestroyConnection()
+// anyway, so the object can notify its observers.
+void BluetoothLowEnergyWeaveClientConnection::DeviceChanged(
+ BluetoothAdapter* adapter,
+ BluetoothDevice* device) {
+ DCHECK(device);
+ if (sub_status() == SubStatus::DISCONNECTED ||
+ device->GetAddress() != GetDeviceAddress())
+ return;
+
+ if (sub_status() != SubStatus::WAITING_GATT_CONNECTION &&
+ !device->IsConnected()) {
+ PA_LOG(INFO) << "GATT connection dropped " << GetDeviceAddress()
+ << "\ndevice connected: " << device->IsConnected()
+ << "\ngatt connection: "
+ << (gatt_connection_ ? gatt_connection_->IsConnected()
+ : false);
+ DestroyConnection();
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::DeviceRemoved(
+ BluetoothAdapter* adapter,
+ BluetoothDevice* device) {
+ DCHECK(device);
+ if (sub_status_ == SubStatus::DISCONNECTED ||
+ device->GetAddress() != GetDeviceAddress())
+ return;
+
+ PA_LOG(INFO) << "Device removed " << GetDeviceAddress();
+ DestroyConnection();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::GattCharacteristicValueChanged(
+ BluetoothAdapter* adapter,
+ BluetoothRemoteGattCharacteristic* characteristic,
+ const Packet& value) {
+ DCHECK_EQ(adapter, adapter_.get());
+ if (sub_status() != SubStatus::WAITING_CONNECTION_RESPONSE &&
+ sub_status() != SubStatus::CONNECTED)
+ return;
+
+ PA_LOG(INFO) << "Characteristic value changed: "
+ << characteristic->GetUUID().canonical_value();
+
+ if (characteristic->GetIdentifier() == rx_characteristic_.id) {
+ ReceiverState state = packet_receiver_->ReceivePacket(value);
+
+ PA_LOG(INFO) << "\nReceiver State: " << state;
+ switch (state) {
+ case ReceiverState::DATA_READY:
+ OnBytesReceived(packet_receiver_->GetDataMessage());
+ break;
+ case ReceiverState::CONNECTION_CLOSED:
+ PA_LOG(ERROR) << "Connection closed due to: " << GetReasonForClose();
+ DestroyConnection();
+ break;
+ case ReceiverState::ERROR_DETECTED:
+ OnPacketReceiverError();
+ break;
+ case ReceiverState::WAITING:
+ // Receiver state should have changed from CONNECTING to WAITING if
+ // a proper connection response had been received.
+ // The max packet size selected from the connection response will be
+ // used to generate future data packets.
+ packet_generator_->SetMaxPacketSize(
+ packet_receiver_->GetMaxPacketSize());
+ DCHECK(sub_status() == SubStatus::WAITING_CONNECTION_RESPONSE);
+ CompleteConnection();
+ break;
+ case ReceiverState::RECEIVING_DATA:
+ // Normal in between states, so do nothing.
+ break;
+ default:
+ NOTREACHED();
+ }
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::CompleteConnection() {
+ PA_LOG(INFO) << "Connection completed. Time elapsed: "
+ << base::TimeTicks::Now() - start_time_;
+ SetSubStatus(SubStatus::CONNECTED);
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnCreateGattConnectionError(
+ device::BluetoothDevice::ConnectErrorCode error_code) {
+ DCHECK(sub_status_ == SubStatus::WAITING_GATT_CONNECTION);
+ PA_LOG(WARNING) << "Error creating GATT connection to "
+ << remote_device().bluetooth_address
+ << " error code: " << error_code;
+ DestroyConnection();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnGattConnectionCreated(
+ std::unique_ptr<device::BluetoothGattConnection> gatt_connection) {
+ DCHECK(sub_status() == SubStatus::WAITING_GATT_CONNECTION);
+ PA_LOG(INFO) << "GATT connection with " << gatt_connection->GetDeviceAddress()
+ << " created.";
+ PrintTimeElapsed();
+
+ // Informing |bluetooth_trottler_| a new connection was established.
+ bluetooth_throttler_->OnConnection(this);
+
+ gatt_connection_ = std::move(gatt_connection);
+ SetSubStatus(SubStatus::WAITING_CHARACTERISTICS);
+ characteristic_finder_.reset(CreateCharacteristicsFinder(
+ base::Bind(
+ &BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::
+ OnCharacteristicsFinderError,
+ weak_ptr_factory_.GetWeakPtr())));
+}
+
+BluetoothLowEnergyCharacteristicsFinder*
+BluetoothLowEnergyWeaveClientConnection::CreateCharacteristicsFinder(
+ const BluetoothLowEnergyCharacteristicsFinder::SuccessCallback&
+ success_callback,
+ const BluetoothLowEnergyCharacteristicsFinder::ErrorCallback&
+ error_callback) {
+ return new BluetoothLowEnergyCharacteristicsFinder(
+ adapter_, GetRemoteDevice(), remote_service_, tx_characteristic_,
+ rx_characteristic_, success_callback, error_callback);
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFound(
+ const RemoteAttribute& service,
+ const RemoteAttribute& tx_characteristic,
+ const RemoteAttribute& rx_characteristic) {
+ PA_LOG(INFO) << "Remote chacteristics found.";
+ PrintTimeElapsed();
+
+ DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
+ remote_service_ = service;
+ tx_characteristic_ = tx_characteristic;
+ rx_characteristic_ = rx_characteristic;
+
+ SetSubStatus(SubStatus::CHARACTERISTICS_FOUND);
+ StartNotifySession();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnCharacteristicsFinderError(
+ const RemoteAttribute& tx_characteristic,
+ const RemoteAttribute& rx_characteristic) {
+ DCHECK(sub_status() == SubStatus::WAITING_CHARACTERISTICS);
+ PA_LOG(WARNING) << "Connection error, missing characteristics for SmartLock "
+ "service.\n"
+ << (tx_characteristic.id.empty()
+ ? tx_characteristic.uuid.canonical_value()
+ : "")
+ << ", "
+ << (rx_characteristic.id.empty()
+ ? ", " + rx_characteristic.uuid.canonical_value()
+ : "")
+ << " not found.";
+
+ DestroyConnection();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::StartNotifySession() {
+ DCHECK(sub_status() == SubStatus::CHARACTERISTICS_FOUND);
+ BluetoothRemoteGattCharacteristic* characteristic =
+ GetGattCharacteristic(rx_characteristic_.id);
+ CHECK(characteristic);
+
+ // This is a workaround for crbug.com/507325. If |characteristic| is already
+ // notifying |characteristic->StartNotifySession()| will fail with
+ // GATT_ERROR_FAILED.
+ if (characteristic->IsNotifying()) {
+ PA_LOG(INFO) << characteristic->GetUUID().canonical_value()
+ << " already notifying.";
+ SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
+ SendConnectionRequest();
+ return;
+ }
+
+ SetSubStatus(SubStatus::WAITING_NOTIFY_SESSION);
+ characteristic->StartNotifySession(
+ base::Bind(
+ &BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError,
+ weak_ptr_factory_.GetWeakPtr()));
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionStarted(
+ std::unique_ptr<BluetoothGattNotifySession> notify_session) {
+ DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
+ PA_LOG(INFO) << "Notification session started "
+ << notify_session->GetCharacteristicIdentifier();
+ PrintTimeElapsed();
+
+ SetSubStatus(SubStatus::NOTIFY_SESSION_READY);
+ notify_session_ = std::move(notify_session);
+
+ SendConnectionRequest();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnNotifySessionError(
+ BluetoothRemoteGattService::GattErrorCode error) {
+ DCHECK(sub_status() == SubStatus::WAITING_NOTIFY_SESSION);
+ PA_LOG(WARNING) << "Error starting notification session: " << error;
+ DestroyConnection();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::StopNotifySession() {
+ if (notify_session_) {
+ notify_session_->Stop(base::Bind(&base::DoNothing));
+ notify_session_.reset();
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::SendConnectionRequest() {
+ if (sub_status() == SubStatus::NOTIFY_SESSION_READY) {
+ PA_LOG(INFO) << "Sending connection request to the server";
+ SetSubStatus(SubStatus::WAITING_CONNECTION_RESPONSE);
+
+ WriteRequest write_request(packet_generator_->CreateConnectionRequest(),
+ WriteRequestType::CONNECTION_REQUEST);
+
+ WriteRemoteCharacteristic(write_request);
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::WriteRemoteCharacteristic(
+ const WriteRequest& request) {
+ write_requests_queue_.push(request);
+ PA_LOG(ERROR) << "you got " << request.message.get();
+ ProcessNextWriteRequest();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::ProcessNextWriteRequest() {
+ BluetoothRemoteGattCharacteristic* characteristic =
+ GetGattCharacteristic(tx_characteristic_.id);
+ if (!write_requests_queue_.empty() && !write_remote_characteristic_pending_ &&
+ characteristic) {
+ write_remote_characteristic_pending_ = true;
+ const WriteRequest& next_request = write_requests_queue_.front();
+
+ PA_LOG(INFO) << "Writing to characteristic " << next_request.value.size()
+ << " bytes";
+ characteristic->WriteRemoteCharacteristic(
+ next_request.value,
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::
+ OnRemoteCharacteristicWritten,
+ weak_ptr_factory_.GetWeakPtr()),
+ base::Bind(&BluetoothLowEnergyWeaveClientConnection::
+ OnWriteRemoteCharacteristicError,
+ weak_ptr_factory_.GetWeakPtr()));
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnRemoteCharacteristicWritten() {
+ PA_LOG(INFO) << "Characteristic written.";
+
+ DCHECK(!write_requests_queue_.empty());
+
+ const WriteRequest& request = write_requests_queue_.front();
+
+ switch (request.request_type) {
+ case WriteRequestType::REGULAR:
+ case WriteRequestType::CONNECTION_REQUEST:
+ break;
+ case WriteRequestType::MESSAGE_COMPLETE:
+ OnDidSendMessage(*request.message, true);
+ break;
+ case WriteRequestType::CONNECTION_CLOSE:
+ DestroyConnection();
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ // Removes the top of queue (already processed) and process the next request.
+ write_requests_queue_.pop();
+ write_remote_characteristic_pending_ = false;
+ ProcessNextWriteRequest();
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnWriteRemoteCharacteristicError(
+ BluetoothRemoteGattService::GattErrorCode error) {
+ PA_LOG(WARNING) << "Error " << error << " writing characteristic: "
+ << tx_characteristic_.uuid.canonical_value();
+
+ write_remote_characteristic_pending_ = false;
+
+ DCHECK(!write_requests_queue_.empty());
+ WriteRequest* request = &write_requests_queue_.front();
+
+ // Increases the number of failed attempts and retry.
+
+ if (++request->number_of_failed_attempts >= max_number_of_write_attempts_) {
+ switch (request->request_type) {
+ case WriteRequestType::REGULAR:
+ case WriteRequestType::MESSAGE_COMPLETE:
+ OnDidSendMessage(*request->message, false);
+ break;
+ case WriteRequestType::CONNECTION_CLOSE:
+ case WriteRequestType::CONNECTION_REQUEST:
+ break;
+ default:
+ NOTREACHED();
+ }
+
+ // If the previous write failed that many times, probably can't write a
+ // connection close either, so just destroy the connection.
+ DestroyConnection();
+ } else {
+ ProcessNextWriteRequest();
+ }
+}
+
+void BluetoothLowEnergyWeaveClientConnection::OnPacketReceiverError() {
+ PA_LOG(ERROR) << "Received erroneous packet. Closing connection.";
+
+ WriteRequest request(packet_generator_->CreateConnectionClose(
+ packet_receiver_->GetReasonToClose()),
+ WriteRequestType::CONNECTION_CLOSE);
+
+ // Skip all other writes that's not in progress.
+
+ // C++ queue does not have a clear method.
+ // According to stackoverflow
+ // "http://stackoverflow.com/questions/709146/how-do-i-clear-the-stdqueue-
+ // efficiently"
+ std::queue<WriteRequest> empty;
+ std::swap(write_requests_queue_, empty);
+
+ if (write_remote_characteristic_pending_) {
+ // Add the in progress write back to the queue.
+ write_requests_queue_.push(empty.front());
+ }
+
+ WriteRemoteCharacteristic(request);
+}
+
+void BluetoothLowEnergyWeaveClientConnection::PrintTimeElapsed() {
+ PA_LOG(INFO) << "Time elapsed: " << base::TimeTicks::Now() - start_time_;
+}
+
+std::string BluetoothLowEnergyWeaveClientConnection::GetDeviceAddress() {
+ // When the remote device is connected we should rely on the address given by
+ // |gatt_connection_|. As the device address may change if the device is
+ // paired. The address in |gatt_connection_| is automatically updated in this
+ // case.
+ return gatt_connection_ ? gatt_connection_->GetDeviceAddress()
+ : remote_device().bluetooth_address;
+}
+
+BluetoothDevice* BluetoothLowEnergyWeaveClientConnection::GetRemoteDevice() {
+ // It's not possible to simply use
+ // |adapter_->GetDevice(GetDeviceAddress())| to find the device with MAC
+ // address |GetDeviceAddress()|. For paired devices,
+ // BluetoothAdapter::GetDevice(XXX) searches for the temporary MAC address
+ // XXX, whereas |GetDeviceAddress()| is the real MAC address. This is a
+ // bug in the way device::BluetoothAdapter is storing the devices (see
+ // crbug.com/497841).
+ std::vector<BluetoothDevice*> devices = adapter_->GetDevices();
+ for (const auto& device : devices) {
+ if (device->GetAddress() == GetDeviceAddress())
+ return device;
+ }
+
+ return nullptr;
+}
+
+BluetoothRemoteGattService*
+BluetoothLowEnergyWeaveClientConnection::GetRemoteService() {
+ BluetoothDevice* remote_device = GetRemoteDevice();
+ if (!remote_device) {
+ PA_LOG(WARNING) << "Remote device not found.";
+ return NULL;
+ }
+ if (remote_service_.id.empty()) {
+ std::vector<BluetoothRemoteGattService*> services =
+ remote_device->GetGattServices();
+ for (const auto& service : services)
+ if (service->GetUUID() == remote_service_.uuid) {
+ remote_service_.id = service->GetIdentifier();
+ break;
+ }
+ }
+ return remote_device->GetGattService(remote_service_.id);
+}
+
+BluetoothRemoteGattCharacteristic*
+BluetoothLowEnergyWeaveClientConnection::GetGattCharacteristic(
+ const std::string& gatt_characteristic) {
+ BluetoothRemoteGattService* remote_service = GetRemoteService();
+ if (!remote_service) {
+ PA_LOG(WARNING) << "Remote service not found.";
+ return NULL;
+ }
+ return remote_service->GetCharacteristic(gatt_characteristic);
+}
+
+std::string BluetoothLowEnergyWeaveClientConnection::GetReasonForClose() {
+ switch (packet_receiver_->GetReasonForClose()) {
+ case ReasonForClose::CLOSE_WITHOUT_ERROR:
+ return "CLOSE_WITHOUT_ERROR";
+ case ReasonForClose::UNKNOWN_ERROR:
+ return "UNKNOWN_ERROR";
+ case ReasonForClose::NO_COMMON_VERSION_SUPPORTED:
+ return "NO_COMMON_VERSION_SUPPORTED";
+ case ReasonForClose::RECEIVED_PACKET_OUT_OF_SEQUENCE:
+ return "RECEIVED_PACKET_OUT_OF_SEQUENCE";
+ case ReasonForClose::APPLICATION_ERROR:
+ return "APPLICATION_ERROR";
+ default:
+ NOTREACHED();
+ return "";
+ }
+}
+
+BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
+ const Packet& val,
+ WriteRequestType request_type,
+ std::shared_ptr<WireMessage> message)
+ : value(val),
+ request_type(request_type),
+ message(message),
+ number_of_failed_attempts(0) {}
+
+BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
+ const Packet& val,
+ WriteRequestType request_type)
+ : value(val),
+ request_type(request_type),
+ message(nullptr),
+ number_of_failed_attempts(0) {}
+
+BluetoothLowEnergyWeaveClientConnection::WriteRequest::WriteRequest(
+ const WriteRequest& other) = default;
+
+BluetoothLowEnergyWeaveClientConnection::WriteRequest::~WriteRequest() {}
+
+} // namespace weave
+
+} // namespace proximity_auth

Powered by Google App Engine
This is Rietveld 408576698