blob: 0db6d0fdb80fbe50c1d3daa9ebb654b872089ef1 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "device/bluetooth/floss/floss_gatt_manager_client.h"
#include "base/logging.h"
#include "base/notreached.h"
namespace floss {
namespace {
constexpr char kCharacteristics[] = "characteristics";
constexpr char kDescriptors[] = "descriptors";
constexpr char kIncludedServices[] = "included_services";
constexpr char kInstanceId[] = "instance_id";
constexpr char kKeySize[] = "key_size";
constexpr char kPermissions[] = "permissions";
constexpr char kProperties[] = "properties";
constexpr char kServiceType[] = "service_type";
constexpr char kUuid[] = "uuid";
constexpr char kWriteType[] = "write_type";
} // namespace
namespace {
// Randomly generated UUID for use in this client.
constexpr char kDefaultGattManagerClientUuid[] =
"e060b902508c485f8b0e27639c7f2d41";
// Default to not requesting eatt support with gatt client.
constexpr bool kDefaultEattSupport = false;
void HandleResponse(const char* method, DBusResult<Void> result) {
if (!result.has_value()) {
LOG(ERROR) << "Call failed: " << method << ": " << result.error();
return;
}
DVLOG(1) << method << " succeeded.";
}
} // namespace
// Template specializations for dbus parsing
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader, LePhy* phy) {
uint32_t value;
if (FlossDBusClient::ReadDBusParam(reader, &value)) {
*phy = static_cast<LePhy>(value);
return true;
}
return false;
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const LePhy*) {
static DBusTypeInfo info{"u", "LePhy"};
return info;
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const LePhy& phy) {
uint32_t value = static_cast<uint32_t>(phy);
WriteDBusParam(writer, value);
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
GattStatus* status) {
uint32_t value;
if (FlossDBusClient::ReadDBusParam(reader, &value)) {
*status = static_cast<GattStatus>(value);
return true;
}
return false;
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const GattStatus& status) {
int32_t value = static_cast<int32_t>(status);
WriteDBusParam(writer, value);
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const GattStatus*) {
static DBusTypeInfo info{"u", "GattStatus"};
return info;
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
GattWriteRequestStatus* status) {
uint32_t value;
if (FlossDBusClient::ReadDBusParam(reader, &value)) {
*status = static_cast<GattWriteRequestStatus>(value);
return true;
}
return false;
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const GattWriteRequestStatus*) {
static DBusTypeInfo info{"u", "GattWriteRequestStatus"};
return info;
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const AuthRequired& auth_req) {
int32_t value = static_cast<int32_t>(auth_req);
WriteDBusParam(writer, value);
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
WriteType* write_type) {
uint32_t value;
if (FlossDBusClient::ReadDBusParam(reader, &value)) {
*write_type = static_cast<WriteType>(value);
return true;
}
return false;
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const WriteType*) {
static DBusTypeInfo info{"u", "WriteType"};
return info;
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const WriteType& write_type) {
uint32_t value = static_cast<uint32_t>(write_type);
WriteDBusParam(writer, value);
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const GattService& service) {
dbus::MessageWriter array(nullptr);
writer->OpenArray("{sv}", &array);
WriteDictEntry(&array, kUuid, service.uuid);
WriteDictEntry(&array, kInstanceId, service.instance_id);
WriteDictEntry(&array, kServiceType, service.service_type);
WriteDictEntry(&array, kCharacteristics, service.characteristics);
WriteDictEntry(&array, kIncludedServices, service.included_services);
writer->CloseContainer(&array);
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const GattCharacteristic& characteristic) {
dbus::MessageWriter array(nullptr);
writer->OpenArray("{sv}", &array);
WriteDictEntry(&array, kInstanceId, characteristic.instance_id);
WriteDictEntry(&array, kProperties, characteristic.properties);
WriteDictEntry(&array, kPermissions, characteristic.permissions);
WriteDictEntry(&array, kKeySize, characteristic.key_size);
WriteDictEntry(&array, kWriteType, characteristic.write_type);
WriteDictEntry(&array, kDescriptors, characteristic.descriptors);
writer->CloseContainer(&array);
}
template <>
void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer,
const GattDescriptor& descriptor) {
dbus::MessageWriter array(nullptr);
writer->OpenArray("{sv}", &array);
WriteDictEntry(&array, kUuid, descriptor.uuid);
WriteDictEntry(&array, kInstanceId, descriptor.instance_id);
WriteDictEntry(&array, kPermissions, descriptor.permissions);
writer->CloseContainer(&array);
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
GattDescriptor* descriptor) {
static FlossDBusClient::StructReader<GattDescriptor> struct_reader({
{kUuid, CreateFieldReader(&GattDescriptor::uuid)},
{kInstanceId, CreateFieldReader(&GattDescriptor::instance_id)},
{kPermissions, CreateFieldReader(&GattDescriptor::permissions)},
});
return struct_reader.ReadDBusParam(reader, descriptor);
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const GattDescriptor*) {
static DBusTypeInfo info{"a{sv}", "GattDescriptor"};
return info;
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
GattCharacteristic* characteristic) {
static FlossDBusClient::StructReader<GattCharacteristic> struct_reader({
{kUuid, CreateFieldReader(&GattCharacteristic::uuid)},
{kInstanceId, CreateFieldReader(&GattCharacteristic::instance_id)},
{kProperties, CreateFieldReader(&GattCharacteristic::properties)},
{kKeySize, CreateFieldReader(&GattCharacteristic::key_size)},
{kWriteType, CreateFieldReader(&GattCharacteristic::write_type)},
{kDescriptors, CreateFieldReader(&GattCharacteristic::descriptors)},
});
return struct_reader.ReadDBusParam(reader, characteristic);
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const GattCharacteristic*) {
static DBusTypeInfo info{"a{sv}", "GattCharacteristic"};
return info;
}
template <>
bool FlossDBusClient::ReadDBusParam(dbus::MessageReader* reader,
GattService* service) {
static FlossDBusClient::StructReader<GattService> struct_reader({
{kUuid, CreateFieldReader(&GattService::uuid)},
{kInstanceId, CreateFieldReader(&GattService::instance_id)},
{kServiceType, CreateFieldReader(&GattService::service_type)},
{kCharacteristics, CreateFieldReader(&GattService::characteristics)},
{kIncludedServices, CreateFieldReader(&GattService::included_services)},
});
return struct_reader.ReadDBusParam(reader, service);
}
template <>
const DBusTypeInfo& GetDBusTypeInfo(const GattService*) {
static DBusTypeInfo info{"a{sv}", "GattService"};
return info;
}
GattDescriptor::GattDescriptor() = default;
GattDescriptor::~GattDescriptor() = default;
GattCharacteristic::GattCharacteristic() = default;
GattCharacteristic::GattCharacteristic(const GattCharacteristic&) = default;
GattCharacteristic::~GattCharacteristic() = default;
GattService::GattService() = default;
GattService::GattService(const GattService&) = default;
GattService::~GattService() = default;
const char FlossGattManagerClient::kExportedCallbacksPath[] =
"/org/chromium/bluetooth/gattclient";
// static
std::unique_ptr<FlossGattManagerClient> FlossGattManagerClient::Create() {
return std::make_unique<FlossGattManagerClient>();
}
FlossGattManagerClient::FlossGattManagerClient() = default;
FlossGattManagerClient::~FlossGattManagerClient() {
if (bus_) {
gatt_client_exported_callback_manager_.UnexportCallback(
dbus::ObjectPath(kExportedCallbacksPath));
gatt_server_exported_callback_manager_.UnexportCallback(
dbus::ObjectPath(kExportedCallbacksPath));
}
}
void FlossGattManagerClient::AddObserver(FlossGattClientObserver* observer) {
gatt_client_observers_.AddObserver(observer);
}
void FlossGattManagerClient::AddServerObserver(
FlossGattServerObserver* observer) {
gatt_server_observers_.AddObserver(observer);
}
void FlossGattManagerClient::RemoveObserver(FlossGattClientObserver* observer) {
gatt_client_observers_.RemoveObserver(observer);
}
void FlossGattManagerClient::RemoveServerObserver(
FlossGattServerObserver* observer) {
gatt_server_observers_.RemoveObserver(observer);
}
void FlossGattManagerClient::Connect(ResponseCallback<Void> callback,
const std::string& remote_device,
const BluetoothTransport& transport,
bool is_direct) {
// Opportunistic connections should be false because we want connections to
// immediately fail with timeout if it doesn't work out.
const bool opportunistic = false;
// We want a phy to be chosen automatically.
const LePhy phy = LePhy::kInvalid;
CallGattMethod<Void>(std::move(callback), gatt::kClientConnect, client_id_,
remote_device, is_direct, transport, opportunistic, phy);
}
void FlossGattManagerClient::Disconnect(ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kClientDisconnect, client_id_,
remote_device);
}
void FlossGattManagerClient::BeginReliableWrite(
ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kBeginReliableWrite,
client_id_, remote_device);
}
void FlossGattManagerClient::EndReliableWrite(ResponseCallback<Void> callback,
const std::string& remote_device,
bool execute) {
CallGattMethod<Void>(std::move(callback), gatt::kEndReliableWrite, client_id_,
remote_device, execute);
}
void FlossGattManagerClient::Refresh(ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kRefreshDevice, client_id_,
remote_device);
}
void FlossGattManagerClient::DiscoverAllServices(
ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kDiscoverServices, client_id_,
remote_device);
}
void FlossGattManagerClient::DiscoverServiceByUuid(
ResponseCallback<Void> callback,
const std::string& remote_device,
const device::BluetoothUUID& uuid) {
CallGattMethod<Void>(std::move(callback), gatt::kDiscoverServiceByUuid,
client_id_, remote_device, uuid.canonical_value());
}
void FlossGattManagerClient::ReadCharacteristic(
ResponseCallback<Void> callback,
const std::string& remote_device,
const int32_t handle,
const AuthRequired auth_required) {
CallGattMethod<Void>(std::move(callback), gatt::kReadCharacteristic,
client_id_, remote_device, handle, auth_required);
}
void FlossGattManagerClient::ReadUsingCharacteristicUuid(
ResponseCallback<Void> callback,
const std::string& remote_device,
const device::BluetoothUUID& uuid,
const int32_t start_handle,
const int32_t end_handle,
const AuthRequired auth_required) {
CallGattMethod<Void>(std::move(callback), gatt::kReadUsingCharacteristicUuid,
client_id_, remote_device, uuid.canonical_value(),
start_handle, end_handle, auth_required);
}
void FlossGattManagerClient::WriteCharacteristic(
ResponseCallback<GattWriteRequestStatus> callback,
const std::string& remote_device,
const int32_t handle,
const WriteType write_type,
const AuthRequired auth_required,
const std::vector<uint8_t> data) {
CallGattMethod(std::move(callback), gatt::kWriteCharacteristic, client_id_,
remote_device, handle, write_type, auth_required, data);
}
void FlossGattManagerClient::ReadDescriptor(ResponseCallback<Void> callback,
const std::string& remote_device,
const int32_t handle,
const AuthRequired auth_required) {
CallGattMethod<Void>(std::move(callback), gatt::kReadDescriptor, client_id_,
remote_device, handle, auth_required);
}
void FlossGattManagerClient::WriteDescriptor(ResponseCallback<Void> callback,
const std::string& remote_device,
const int32_t handle,
const AuthRequired auth_required,
const std::vector<uint8_t> data) {
CallGattMethod<Void>(std::move(callback), gatt::kWriteDescriptor, client_id_,
remote_device, handle, auth_required, data);
}
void FlossGattManagerClient::RegisterForNotification(
ResponseCallback<GattStatus> callback,
const std::string& remote_device,
const int32_t handle) {
const bool enable_notification = true;
CallGattMethod<Void>(
base::BindOnce(&FlossGattManagerClient::OnRegisterNotificationResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
enable_notification),
gatt::kRegisterForNotification, client_id_, remote_device, handle,
enable_notification);
}
void FlossGattManagerClient::UnregisterNotification(
ResponseCallback<GattStatus> callback,
const std::string& remote_device,
const int32_t handle) {
const bool enable_notification = false;
CallGattMethod<Void>(
base::BindOnce(&FlossGattManagerClient::OnRegisterNotificationResponse,
weak_ptr_factory_.GetWeakPtr(), std::move(callback),
enable_notification),
gatt::kRegisterForNotification, client_id_, remote_device, handle,
enable_notification);
}
void FlossGattManagerClient::ReadRemoteRssi(ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kReadRemoteRssi, client_id_,
remote_device);
}
void FlossGattManagerClient::ConfigureMTU(ResponseCallback<Void> callback,
const std::string& remote_device,
const int32_t mtu) {
CallGattMethod<Void>(std::move(callback), gatt::kConfigureMtu, client_id_,
remote_device, mtu);
}
void FlossGattManagerClient::UpdateConnectionParameters(
ResponseCallback<Void> callback,
const std::string& remote_device,
const int32_t min_interval,
const int32_t max_interval,
const int32_t latency,
const int32_t timeout,
const uint16_t min_ce_len,
const uint16_t max_ce_len) {
CallGattMethod<Void>(std::move(callback), gatt::kConnectionParameterUpdate,
client_id_, remote_device, min_interval, max_interval,
latency, timeout, min_ce_len, max_ce_len);
}
void FlossGattManagerClient::UnregisterServer(ResponseCallback<Void> callback) {
CallGattMethod<Void>(std::move(callback), gatt::kUnregisterServer,
server_id_);
}
void FlossGattManagerClient::ServerConnect(
ResponseCallback<Void> callback,
const std::string& remote_device,
const BluetoothTransport& transport) {
// Connect immediately, instead of when next seen.
constexpr bool is_direct = true;
CallGattMethod<Void>(std::move(callback), gatt::kServerConnect, server_id_,
remote_device, is_direct, transport);
}
void FlossGattManagerClient::ServerDisconnect(
ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kServerDisconnect, server_id_,
remote_device);
}
void FlossGattManagerClient::ServerSetPreferredPhy(
ResponseCallback<Void> callback,
const std::string& remote_device,
LePhy tx_phy,
LePhy rx_phy,
int32_t phy_options) {
CallGattMethod<Void>(std::move(callback), gatt::kServerSetPreferredPhy,
server_id_, remote_device, tx_phy, rx_phy, phy_options);
}
void FlossGattManagerClient::ServerReadPhy(ResponseCallback<Void> callback,
const std::string& remote_device) {
CallGattMethod<Void>(std::move(callback), gatt::kServerReadPhy, server_id_,
remote_device);
}
void FlossGattManagerClient::AddService(ResponseCallback<Void> callback,
GattService service) {
CallGattMethod<Void>(std::move(callback), gatt::kAddService, server_id_,
service);
}
void FlossGattManagerClient::RemoveService(ResponseCallback<Void> callback,
int32_t handle) {
CallGattMethod<Void>(std::move(callback), gatt::kRemoveService, server_id_,
handle);
}
void FlossGattManagerClient::ClearServices(ResponseCallback<Void> callback) {
CallGattMethod<Void>(std::move(callback), gatt::kClearServices, server_id_);
}
void FlossGattManagerClient::SendResponse(ResponseCallback<Void> callback,
const std::string& remote_device,
int32_t request_id,
GattStatus status,
int32_t offset,
std::vector<uint8_t> value) {
CallGattMethod<Void>(std::move(callback), gatt::kSendResponse, server_id_,
remote_device, request_id, status, offset, value);
}
void FlossGattManagerClient::ServerSendNotification(
ResponseCallback<Void> callback,
const std::string& remote_device,
int32_t handle,
bool confirm,
std::vector<uint8_t> value) {
CallGattMethod<Void>(std::move(callback), gatt::kServerSendNotification,
server_id_, remote_device, handle, confirm, value);
}
void FlossGattManagerClient::Init(dbus::Bus* bus,
const std::string& service_name,
const int adapter_index,
base::OnceClosure on_ready) {
// Set field variables.
bus_ = bus;
service_name_ = service_name;
gatt_adapter_path_ = GenerateGattPath(adapter_index);
// Initialize DBus object proxy.
dbus::ObjectProxy* object_proxy =
bus_->GetObjectProxy(service_name_, gatt_adapter_path_);
if (!object_proxy) {
LOG(ERROR)
<< "FlossGattManagerClient couldn't init. Object proxy was null.";
return;
}
// Register all callbacks.
gatt_client_exported_callback_manager_.Init(bus_.get());
gatt_server_exported_callback_manager_.Init(bus_.get());
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnClientRegistered,
&FlossGattClientObserver::GattClientRegistered);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnClientConnectionState,
&FlossGattClientObserver::GattClientConnectionState);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnPhyUpdate, &FlossGattClientObserver::GattPhyUpdate);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnPhyRead, &FlossGattClientObserver::GattPhyRead);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnSearchComplete, &FlossGattClientObserver::GattSearchComplete);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnCharacteristicRead,
&FlossGattClientObserver::GattCharacteristicRead);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnCharacteristicWrite,
&FlossGattClientObserver::GattCharacteristicWrite);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnExecuteWrite, &FlossGattClientObserver::GattExecuteWrite);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnDescriptorRead, &FlossGattClientObserver::GattDescriptorRead);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnDescriptorWrite, &FlossGattClientObserver::GattDescriptorWrite);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnNotify, &FlossGattClientObserver::GattNotify);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnReadRemoteRssi, &FlossGattClientObserver::GattReadRemoteRssi);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnConfigureMtu, &FlossGattClientObserver::GattConfigureMtu);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnConnectionUpdated,
&FlossGattClientObserver::GattConnectionUpdated);
gatt_client_exported_callback_manager_.AddMethod(
gatt::kOnServiceChanged, &FlossGattClientObserver::GattServiceChanged);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerRegistered,
&FlossGattServerObserver::GattServerRegistered);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerConnectionState,
&FlossGattServerObserver::GattServerConnectionState);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerServiceAdded,
&FlossGattServerObserver::GattServerServiceAdded);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerServiceRemoved,
&FlossGattServerObserver::GattServerServiceRemoved);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerCharacteristicReadRequest,
&FlossGattServerObserver::GattServerCharacteristicReadRequest);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerDescriptorReadRequest,
&FlossGattServerObserver::GattServerDescriptorReadRequest);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerCharacteristicWriteRequest,
&FlossGattServerObserver::GattServerCharacteristicWriteRequest);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerDescriptorWriteRequest,
&FlossGattServerObserver::GattServerDescriptorWriteRequest);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnExecuteWrite, &FlossGattServerObserver::GattServerExecuteWrite);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerNotificationSent,
&FlossGattServerObserver::GattServerNotificationSent);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerMtuChanged,
&FlossGattServerObserver::GattServerMtuChanged);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnPhyUpdate, &FlossGattServerObserver::GattServerPhyUpdate);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnPhyRead, &FlossGattServerObserver::GattServerPhyRead);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnConnectionUpdated,
&FlossGattServerObserver::GattServerConnectionUpdate);
gatt_server_exported_callback_manager_.AddMethod(
gatt::kOnServerSubrateChange,
&FlossGattServerObserver::GattServerSubrateChange);
// Export callbacks.
if (!gatt_client_exported_callback_manager_.ExportCallback(
dbus::ObjectPath(kExportedCallbacksPath),
weak_ptr_factory_.GetWeakPtr(),
base::BindOnce(&FlossGattManagerClient::RegisterClient,
weak_ptr_factory_.GetWeakPtr()))) {
LOG(ERROR) << "Unable to successfully export FlossGattClientObserver.";
return;
}
if (!gatt_server_exported_callback_manager_.ExportCallback(
dbus::ObjectPath(kExportedCallbacksPath),
weak_ptr_factory_.GetWeakPtr(),
base::BindOnce(&FlossGattManagerClient::RegisterServer,
weak_ptr_factory_.GetWeakPtr()))) {
LOG(ERROR) << "Unable to successfully export FlossGattServerObserver.";
return;
}
property_msft_supported_.Init(this, bus_, service_name_, gatt_adapter_path_,
dbus::ObjectPath(kExportedCallbacksPath),
base::DoNothing());
// Everything is queued for registration so save |on_ready| for later.
on_ready_ = std::move(on_ready);
}
void FlossGattManagerClient::RegisterClient() {
// Finish registering client. We will get gatt client id via
// |GattClientRegistered|.
CallGattMethod<Void>(
base::BindOnce(&HandleResponse, gatt::kRegisterClient),
gatt::kRegisterClient, std::string(kDefaultGattManagerClientUuid),
dbus::ObjectPath(kExportedCallbacksPath), kDefaultEattSupport);
}
void FlossGattManagerClient::RegisterServer() {
// Finish registering server. We will get gatt server id via
// |GattClientRegistered|.
CallGattMethod<Void>(
base::BindOnce(&HandleResponse, gatt::kRegisterServer),
gatt::kRegisterServer, std::string(kDefaultGattManagerClientUuid),
dbus::ObjectPath(kExportedCallbacksPath), kDefaultEattSupport);
}
void FlossGattManagerClient::CompleteInit() {
if (client_id_ && server_id_ && on_ready_) {
std::move(on_ready_).Run();
}
}
void FlossGattManagerClient::GattClientRegistered(GattStatus status,
int32_t client_id) {
if (client_id_ != 0) {
LOG(ERROR) << "Unexpected GattClientRegistered with id = " << client_id
<< " when we already have id = " << client_id_;
return;
}
if (status != GattStatus::kSuccess) {
LOG(ERROR) << "RegisterClient failed with status = "
<< static_cast<uint32_t>(status);
return;
}
client_id_ = client_id;
CompleteInit();
}
void FlossGattManagerClient::GattClientConnectionState(GattStatus status,
int32_t client_id,
bool connected,
std::string address) {
if (client_id != client_id_) {
return;
}
for (auto& observer : gatt_client_observers_) {
observer.GattClientConnectionState(status, client_id, connected, address);
}
}
void FlossGattManagerClient::GattPhyUpdate(std::string address,
LePhy tx,
LePhy rx,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattPhyUpdate(address, tx, rx, status);
}
}
void FlossGattManagerClient::GattPhyRead(std::string address,
LePhy tx,
LePhy rx,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattPhyRead(address, tx, rx, status);
}
}
void FlossGattManagerClient::GattSearchComplete(
std::string address,
const std::vector<GattService>& services,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattSearchComplete(address, services, status);
}
}
void FlossGattManagerClient::GattCharacteristicRead(
std::string address,
GattStatus status,
int32_t handle,
const std::vector<uint8_t>& data) {
for (auto& observer : gatt_client_observers_) {
observer.GattCharacteristicRead(address, status, handle, data);
}
}
void FlossGattManagerClient::GattCharacteristicWrite(std::string address,
GattStatus status,
int32_t handle) {
for (auto& observer : gatt_client_observers_) {
observer.GattCharacteristicWrite(address, status, handle);
}
}
void FlossGattManagerClient::GattExecuteWrite(std::string address,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattExecuteWrite(address, status);
}
}
void FlossGattManagerClient::GattDescriptorRead(
std::string address,
GattStatus status,
int32_t handle,
const std::vector<uint8_t>& data) {
for (auto& observer : gatt_client_observers_) {
observer.GattDescriptorRead(address, status, handle, data);
}
}
void FlossGattManagerClient::GattDescriptorWrite(std::string address,
GattStatus status,
int32_t handle) {
for (auto& observer : gatt_client_observers_) {
observer.GattDescriptorWrite(address, status, handle);
}
}
void FlossGattManagerClient::GattNotify(std::string address,
int32_t handle,
const std::vector<uint8_t>& data) {
for (auto& observer : gatt_client_observers_) {
observer.GattNotify(address, handle, data);
}
}
void FlossGattManagerClient::GattReadRemoteRssi(std::string address,
int32_t rssi,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattReadRemoteRssi(address, rssi, status);
}
}
void FlossGattManagerClient::GattConfigureMtu(std::string address,
int32_t mtu,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattConfigureMtu(address, mtu, status);
}
}
void FlossGattManagerClient::GattConnectionUpdated(std::string address,
int32_t interval,
int32_t latency,
int32_t timeout,
GattStatus status) {
for (auto& observer : gatt_client_observers_) {
observer.GattConnectionUpdated(address, interval, latency, timeout, status);
}
}
void FlossGattManagerClient::GattServiceChanged(std::string address) {
for (auto& observer : gatt_client_observers_) {
observer.GattServiceChanged(address);
}
}
// TODO(b/193685841) - Floss currently doesn't emit a callback when
// a notification registers. Once a callback is available, we should report that
// via the callback here instead.
void FlossGattManagerClient::OnRegisterNotificationResponse(
ResponseCallback<GattStatus> callback,
bool is_registering,
DBusResult<Void> result) {
if (!result.has_value()) {
std::move(callback).Run(GattStatus::kError);
return;
}
std::move(callback).Run(GattStatus::kSuccess);
}
void FlossGattManagerClient::GattServerRegistered(GattStatus status,
int32_t server_id) {
if (server_id_ != 0) {
LOG(ERROR) << "Unexpected GattServerRegistered with id = " << server_id
<< " when we already have id = " << server_id_;
return;
}
if (status != GattStatus::kSuccess) {
LOG(ERROR) << "RegisterServer failed with status = "
<< static_cast<uint32_t>(status);
return;
}
server_id_ = server_id;
CompleteInit();
}
void FlossGattManagerClient::GattServerConnectionState(GattStatus status,
int32_t server_id,
bool connected,
std::string address) {
if (server_id != server_id_) {
return;
}
for (auto& observer : gatt_server_observers_) {
observer.GattServerConnectionState(status, server_id, connected, address);
}
}
void FlossGattManagerClient::GattServerServiceAdded(GattStatus status,
GattService service) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerServiceAdded(status, service);
}
}
void FlossGattManagerClient::GattServerServiceRemoved(GattStatus status,
int32_t handle) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerServiceRemoved(status, handle);
}
}
void FlossGattManagerClient::GattServerCharacteristicReadRequest(
std::string address,
int32_t request_id,
int32_t offset,
bool is_long,
int32_t handle) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerCharacteristicReadRequest(address, request_id, offset,
is_long, handle);
}
}
void FlossGattManagerClient::GattServerDescriptorReadRequest(
std::string address,
int32_t request_id,
int32_t offset,
bool is_long,
int32_t handle) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerDescriptorReadRequest(address, request_id, offset,
is_long, handle);
}
}
void FlossGattManagerClient::GattServerCharacteristicWriteRequest(
std::string address,
int32_t request_id,
int32_t offset,
int32_t length,
bool is_prepared_write,
bool needs_response,
int32_t handle,
std::vector<uint8_t> value) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerCharacteristicWriteRequest(
address, request_id, offset, length, is_prepared_write, needs_response,
handle, value);
}
}
void FlossGattManagerClient::GattServerDescriptorWriteRequest(
std::string address,
int32_t request_id,
int32_t offset,
int32_t length,
bool is_prepared_write,
bool needs_response,
int32_t handle,
std::vector<uint8_t> value) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerDescriptorWriteRequest(address, request_id, offset,
length, is_prepared_write,
needs_response, handle, value);
}
}
void FlossGattManagerClient::GattServerExecuteWrite(std::string address,
int32_t request_id,
bool execute_write) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerExecuteWrite(address, request_id, execute_write);
}
}
void FlossGattManagerClient::GattServerNotificationSent(std::string address,
GattStatus status) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerNotificationSent(address, status);
}
}
void FlossGattManagerClient::GattServerMtuChanged(std::string address,
int32_t mtu) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerMtuChanged(address, mtu);
}
}
void FlossGattManagerClient::GattServerPhyUpdate(std::string address,
LePhy tx_phy,
LePhy rx_phy,
GattStatus status) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerPhyUpdate(address, tx_phy, rx_phy, status);
}
}
void FlossGattManagerClient::GattServerPhyRead(std::string address,
LePhy tx_phy,
LePhy rx_phy,
GattStatus status) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerPhyRead(address, tx_phy, rx_phy, status);
}
}
void FlossGattManagerClient::GattServerConnectionUpdate(std::string address,
int32_t interval,
int32_t latency,
int32_t timeout,
GattStatus status) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerConnectionUpdate(address, interval, latency, timeout,
status);
}
}
void FlossGattManagerClient::GattServerSubrateChange(std::string address,
int32_t subrate_factor,
int32_t latency,
int32_t continuation_num,
int32_t timeout,
GattStatus status) {
for (auto& observer : gatt_server_observers_) {
observer.GattServerSubrateChange(address, subrate_factor, latency,
continuation_num, timeout, status);
}
}
} // namespace floss