converted LeAdvertisementManager to use async internally and expose a sync API

This commit is contained in:
lasan
2026-03-20 17:03:57 +05:30
parent a7d52b09a2
commit 607d37a6b0
5 changed files with 89 additions and 22 deletions
@@ -107,11 +107,11 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
bool BleV2Medium::StartAdvertising(
const api::ble::BleAdvertisementData &advertising_data,
api::ble::AdvertiseParameters advertise_set_parameters) {
if (!advertising_data.is_extended_advertisement)
{
// can't send two LE advertisements at the same
return true;
}
//if (!advertising_data.is_extended_advertisement)
//{
// // can't send two LE advertisements at the same
// return true;
//}
if (!adapter_.IsEnabled()) {
LOG(WARNING) << "BLE cannot start advertising because the "
"bluetooth adapter is not enabled.";
@@ -135,10 +135,10 @@ BleV2Medium::BleV2Medium(BluetoothAdapter &adapter)
<< adapter_.GetObjectPath();
try {
adv_manager_->RegisterAdvertisement((*it)->getObject().getObjectPath(), {});
adv_manager_->RegisterAdvertisementSync((*it)->getObject().getObjectPath(), {});
} catch (const sdbus::Error &e) {
advs_.erase(it);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisement", e);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisementSync", e);
return false;
}
@@ -175,11 +175,11 @@ BleV2Medium::StartAdvertising(
// Keep async API surface, but register using the same typed DBus path as the
// working sync implementation to avoid signature mismatch (oa{sv} vs sa{sv}).
try {
adv_manager_->RegisterAdvertisement((*adv_it)->getObject().getObjectPath(), {});
adv_manager_->RegisterAdvertisementSync((*adv_it)->getObject().getObjectPath(), {});
shared_cb->start_advertising_result(absl::OkStatus());
} catch (const sdbus::Error &e) {
advs_.erase(adv_it);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisement", e);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "RegisterAdvertisementSync", e);
auto name = e.getName();
std::string msg = e.getMessage();
absl::Status status;
@@ -202,9 +202,9 @@ BleV2Medium::StartAdvertising(
<< (*adv_it)->getObject().getObjectPath();
absl::MutexLock lock(&advs_mutex_);
try {
adv_manager_->UnregisterAdvertisement((*adv_it)->getObject().getObjectPath());
adv_manager_->UnregisterAdvertisementSync((*adv_it)->getObject().getObjectPath());
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisement", e);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync", e);
return absl::UnknownError(e.getMessage());
}
advs_.erase(adv_it);
@@ -219,10 +219,10 @@ BleV2Medium::StartAdvertising(
try {
for (auto& adv: advs_)
{
adv_manager_->UnregisterAdvertisement(adv->getObject().getObjectPath());
adv_manager_->UnregisterAdvertisementSync(adv->getObject().getObjectPath());
}
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisement", e);
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_, "UnregisterAdvertisementSync", e);
return false;
}
@@ -15,6 +15,7 @@
#ifndef PLATFORM_IMPL_LINUX_API_BLUEZ_BLE_ADVERTISEMENT_H_
#define PLATFORM_IMPL_LINUX_API_BLUEZ_BLE_ADVERTISEMENT_H_
#include <future>
#include <sdbus-c++/AdaptorInterfaces.h>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/ProxyInterfaces.h>
@@ -111,6 +112,67 @@ class LEAdvertisementManager final
LEAdvertisementManager(LEAdvertisementManager&&) = delete;
LEAdvertisementManager& operator=(const LEAdvertisementManager&) = delete;
LEAdvertisementManager& operator=(LEAdvertisementManager&&) = delete;
// Synchronous wrapper for RegisterAdvertisement
void RegisterAdvertisementSync(const sdbus::ObjectPath& advertisement,
const std::map<std::string, sdbus::Variant>& options) {
std::promise<std::optional<sdbus::Error>> promise;
auto future = promise.get_future();
{
absl::MutexLock lock(&pending_ops_mutex_);
pending_register_op_ = std::move(promise);
}
RegisterAdvertisement(advertisement, options);
auto error = future.get();
if (error) {
throw *error;
}
}
// Synchronous wrapper for UnregisterAdvertisement
void UnregisterAdvertisementSync(const sdbus::ObjectPath& service) {
std::promise<std::optional<sdbus::Error>> promise;
auto future = promise.get_future();
{
absl::MutexLock lock(&pending_ops_mutex_);
pending_unregister_op_ = std::move(promise);
}
UnregisterAdvertisement(service);
auto error = future.get();
if (error) {
throw *error;
}
}
protected:
void onRegisterAdvertisementReply(std::optional<sdbus::Error> error) override {
absl::MutexLock lock(&pending_ops_mutex_);
if (pending_register_op_) {
pending_register_op_->set_value(std::move(error));
pending_register_op_.reset();
}
}
void onUnregisterAdvertisementReply(std::optional<sdbus::Error> error) override {
absl::MutexLock lock(&pending_ops_mutex_);
if (pending_unregister_op_) {
pending_unregister_op_->set_value(std::move(error));
pending_unregister_op_.reset();
}
}
private:
absl::Mutex pending_ops_mutex_;
std::optional<std::promise<std::optional<sdbus::Error>>> pending_register_op_
ABSL_GUARDED_BY(pending_ops_mutex_);
std::optional<std::promise<std::optional<sdbus::Error>>> pending_unregister_op_
ABSL_GUARDED_BY(pending_ops_mutex_);
};
} // namespace bluez
} // namespace linux
@@ -3,8 +3,8 @@
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp___home_lasan_Dev_nearby_latest_internal_platform_implementation_linux_generated_dbus_bluez_le_advertisement_manager_client_v2_h__proxy__H__
#define __sdbuscpp___home_lasan_Dev_nearby_latest_internal_platform_implementation_linux_generated_dbus_bluez_le_advertisement_manager_client_v2_h__proxy__H__
#ifndef __sdbuscpp__le_advertisement_manager_client_h__proxy__H__
#define __sdbuscpp__le_advertisement_manager_client_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
@@ -35,15 +35,18 @@ protected:
{
}
virtual void onRegisterAdvertisementReply(std::optional<sdbus::Error> error) = 0;
virtual void onUnregisterAdvertisementReply(std::optional<sdbus::Error> error) = 0;
public:
void RegisterAdvertisement(const sdbus::ObjectPath& advertisement, const std::map<std::string, sdbus::Variant>& options)
sdbus::PendingAsyncCall RegisterAdvertisement(const sdbus::ObjectPath& advertisement, const std::map<std::string, sdbus::Variant>& options)
{
m_proxy.callMethod("RegisterAdvertisement").onInterface(INTERFACE_NAME).withArguments(advertisement, options);
return m_proxy.callMethodAsync("RegisterAdvertisement").onInterface(INTERFACE_NAME).withArguments(advertisement, options).uponReplyInvoke([this](std::optional<sdbus::Error> error){ this->onRegisterAdvertisementReply(std::move(error)); });
}
void UnregisterAdvertisement(const sdbus::ObjectPath& service)
sdbus::PendingAsyncCall UnregisterAdvertisement(const sdbus::ObjectPath& service)
{
m_proxy.callMethod("UnregisterAdvertisement").onInterface(INTERFACE_NAME).withArguments(service);
return m_proxy.callMethodAsync("UnregisterAdvertisement").onInterface(INTERFACE_NAME).withArguments(service).uponReplyInvoke([this](std::optional<sdbus::Error> error){ this->onUnregisterAdvertisementReply(std::move(error)); });
}
public:
@@ -3,10 +3,12 @@
<node>
<interface name="org.bluez.LEAdvertisingManager1">
<method name="RegisterAdvertisement">
<annotation name="org.freedesktop.DBus.Method.Async" value="client" />
<arg name="advertisement" type="o" direction="in" />
<arg name="options" type="a{sv}" direction="in" />
</method>
<method name="UnregisterAdvertisement">
<annotation name="org.freedesktop.DBus.Method.Async" value="client" />
<arg name="service" type="o" direction="in" />
</method>
<property name="ActiveInstances" type="y" access="read" />
@@ -1065,7 +1065,7 @@ class LinuxFastInitiationManager final
advertising_parameters);
try {
adv_manager_->RegisterAdvertisement(advertisement_->getObject().getObjectPath(), {});
adv_manager_->RegisterAdvertisementSync(advertisement_->getObject().getObjectPath(), {});
} catch (const sdbus::Error& e) {
advertisement_.reset();
if (error_callback) {
@@ -1090,9 +1090,9 @@ class LinuxFastInitiationManager final
absl::MutexLock lock(&mutex_);
if (advertisement_ != nullptr && adv_manager_ != nullptr) {
try {
adv_manager_->UnregisterAdvertisement(advertisement_->getObject().getObjectPath());
adv_manager_->UnregisterAdvertisementSync(advertisement_->getObject().getObjectPath());
} catch (const sdbus::Error& e) {
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_.get(), "UnregisterAdvertisement",
DBUS_LOG_METHOD_CALL_ERROR(adv_manager_.get(), "UnregisterAdvertisementSync",
e);
}
advertisement_.reset();