blob: 08b4b94bb0f03c9e95bd9914a5b75a1850acc41f [file] [log] [blame]
// Copyright 2018 The Fuchsia 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 "fake_client.h"
#include <zircon/assert.h>
#include "src/connectivity/bluetooth/core/bt-host/gatt/client.h"
namespace bt {
namespace gatt {
namespace testing {
using att::StatusCallback;
FakeClient::FakeClient(async_dispatcher_t* dispatcher)
: dispatcher_(dispatcher), weak_ptr_factory_(this) {
ZX_DEBUG_ASSERT(dispatcher_);
}
fxl::WeakPtr<Client> FakeClient::AsWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
uint16_t FakeClient::mtu() const {
// TODO(armansito): Return a configurable value.
return att::kLEMinMTU;
}
void FakeClient::ExchangeMTU(MTUCallback callback) {
auto task = [status = exchange_mtu_status_, mtu = server_mtu_,
callback = std::move(callback)] { callback(status, mtu); };
async::PostTask(dispatcher_, std::move(task));
}
void FakeClient::DiscoverPrimaryServices(ServiceCallback svc_callback,
StatusCallback status_callback) {
async::PostTask(dispatcher_, [this, svc_callback = std::move(svc_callback),
status_callback = std::move(status_callback)] {
for (const auto& svc : services_) {
svc_callback(svc);
}
status_callback(service_discovery_status_);
});
}
void FakeClient::DiscoverCharacteristics(att::Handle range_start,
att::Handle range_end,
CharacteristicCallback chrc_callback,
StatusCallback status_callback) {
last_chrc_discovery_start_handle_ = range_start;
last_chrc_discovery_end_handle_ = range_end;
chrc_discovery_count_++;
async::PostTask(dispatcher_, [this, range_start, range_end,
chrc_callback = std::move(chrc_callback),
status_callback = std::move(status_callback)] {
for (const auto& chrc : chrcs_) {
if (chrc.handle >= range_start && chrc.handle <= range_end) {
chrc_callback(chrc);
}
}
status_callback(chrc_discovery_status_);
});
}
void FakeClient::DiscoverDescriptors(att::Handle range_start,
att::Handle range_end,
DescriptorCallback desc_callback,
StatusCallback status_callback) {
last_desc_discovery_start_handle_ = range_start;
last_desc_discovery_end_handle_ = range_end;
desc_discovery_count_++;
att::Status status;
if (!desc_discovery_status_target_ ||
desc_discovery_count_ == desc_discovery_status_target_) {
status = desc_discovery_status_;
}
async::PostTask(dispatcher_, [this, status, range_start, range_end,
desc_callback = std::move(desc_callback),
status_callback = std::move(status_callback)] {
for (const auto& desc : descs_) {
if (desc.handle >= range_start && desc.handle <= range_end) {
desc_callback(desc);
}
}
status_callback(status);
});
}
void FakeClient::ReadRequest(att::Handle handle, ReadCallback callback) {
if (read_request_callback_) {
read_request_callback_(handle, std::move(callback));
}
}
void FakeClient::ReadBlobRequest(att::Handle handle, uint16_t offset,
ReadCallback callback) {
if (read_blob_request_callback_) {
read_blob_request_callback_(handle, offset, std::move(callback));
}
}
void FakeClient::WriteRequest(att::Handle handle, const ByteBuffer& value,
StatusCallback callback) {
if (write_request_callback_) {
write_request_callback_(handle, value, std::move(callback));
}
}
void FakeClient::WriteWithoutResponse(att::Handle handle,
const ByteBuffer& value) {
if (write_without_rsp_callback_) {
write_without_rsp_callback_(handle, value);
}
}
void FakeClient::SendNotification(bool indicate, att::Handle handle,
const ByteBuffer& value) {
if (notification_callback_) {
notification_callback_(indicate, handle, value);
}
}
void FakeClient::SetNotificationHandler(NotificationCallback callback) {
notification_callback_ = std::move(callback);
}
} // namespace testing
} // namespace gatt
} // namespace bt