-
Notifications
You must be signed in to change notification settings - Fork 148
Description
Describe the bug
I'm trying to implement the BLE AdvertisementMonitor, and am getting a timeout when I call RegisterMonitor on org.bluez. It appears to be triggering a reverse GetManagedObjects on my service, which I thought would be handled by the Object Manager I created, but no luck.
To Reproduce
Here's the smallest reproducible version I could get. I can attach the glue files below if that would be helpful, but they were generated from the xml, so I don't expect the problem is there.
#include <signal.h>
#include <iostream>
#include <thread>
#include "adaptor/AdvertisementMonitor1_adaptor.h"
#include "proxy/AdvertisementMonitorManager1_proxy.h"
class ApplicationObjectManager
: public sdbus::AdaptorInterfaces<sdbus::ObjectManager_adaptor> {
public:
ApplicationObjectManager(sdbus::IConnection& connection,
sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) {
registerAdaptor();
}
~ApplicationObjectManager() { unregisterAdaptor(); }
};
class AdvertisementMonitor
: public sdbus::AdaptorInterfaces<org::bluez::AdvertisementMonitor1_adaptor,
sdbus::ManagedObject_adaptor,
sdbus::Properties_adaptor> {
public:
AdvertisementMonitor(sdbus::IConnection& connection,
sdbus::ObjectPath objectPath)
: AdaptorInterfaces(connection, std::move(objectPath)) {
registerAdaptor();
emitInterfacesAddedSignal({sdbus::InterfaceName{
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}});
}
~AdvertisementMonitor() {
emitInterfacesRemovedSignal({sdbus::InterfaceName{
org::bluez::AdvertisementMonitor1_adaptor::INTERFACE_NAME}});
unregisterAdaptor();
}
public:
void Release() override {}
void Activate() override {}
void DeviceFound(const sdbus::ObjectPath& device) override {}
void DeviceLost(const sdbus::ObjectPath& device) override {}
protected:
int16_t RSSILowThreshold() override { return 127; }
int16_t RSSIHighThreshold() override { return 127; }
uint16_t RSSILowTimeout() override { return 0; }
uint16_t RSSIHighTimeout() override { return 0; }
uint16_t RSSISamplingPeriod() override { return 0; }
std::string Type() override { return "or_patterns"; }
std::vector<sdbus::Struct<uint8_t, uint8_t, std::vector<uint8_t>>> Patterns()
override {
return {{0, 0xFF, {0x4c}}};
}
};
class AdvertisementMonitorManager
: public sdbus::ProxyInterfaces<
org::bluez::AdvertisementMonitorManager1_proxy> {
public:
AdvertisementMonitorManager(sdbus::IConnection& connection,
sdbus::ServiceName destination,
sdbus::ObjectPath objectPath)
: ProxyInterfaces{connection, std::move(destination),
std::move(objectPath)} {
registerProxy();
}
~AdvertisementMonitorManager() { unregisterProxy(); }
};
constexpr const char* BLUEZ_SERVICE = "org.bluez";
constexpr const char* DEVICE0 = "/org/bluez/hci0";
static std::atomic<bool> running{true};
static void sig_callback(int signum) {
std::cout << "Signal received, shutting down..." << std::endl;
running = false;
}
int main(int argc, char* argv[]) {
if (signal(SIGINT, sig_callback) == SIG_ERR) {
exit(-1);
}
auto connection = sdbus::createSystemBusConnection();
connection->enterEventLoopAsync();
auto application_object_manager = std::make_unique<ApplicationObjectManager>(
*connection, sdbus::ObjectPath{"/org/example"});
auto advertisement_monitor_manager =
std::make_unique<AdvertisementMonitorManager>(
*connection, sdbus::ServiceName{"org.bluez"},
sdbus::ObjectPath{"/org/bluez/hci0"});
advertisement_monitor_manager->RegisterMonitor(
sdbus::ObjectPath{"/org/example/monitor"});
std::cout << "Advertisement monitor registered. Press Ctrl+C to exit."
<< std::endl;
while (running) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
connection->leaveEventLoop();
return 0;
}Expected behavior
I expect RegisterMonitor to return normally.
Real (buggy) behavior
Here are logs from dbus-monitor:
// Register Monitor is called.
method call time=1750287421.989479 sender=:1.230 -> destination=org.bluez serial=2 path=/org/bluez/hci0; interface=org.bluez.AdvertisementMonitorManager1; member=RegisterMonitor
object path "/org/example/monitor"
method call time=1750287421.989673 sender=:1.166 -> destination=org.freedesktop.DBus serial=296 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
string "type='signal',sender='org.freedesktop.DBus',path='/org/freedesktop/DBus',interface='org.freedesktop.DBus',member='NameOwnerChanged',arg0=':1.230'"
method return time=1750287421.989686 sender=org.freedesktop.DBus -> destination=:1.166 serial=176 reply_serial=296
method call time=1750287421.989857 sender=:1.166 -> destination=org.freedesktop.DBus serial=297 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=GetNameOwner
string ":1.230"
method return time=1750287421.989867 sender=org.freedesktop.DBus -> destination=:1.166 serial=177 reply_serial=297
string ":1.230"
method call time=1750287421.989921 sender=:1.166 -> destination=org.freedesktop.DBus serial=298 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
string "type='signal',sender=':1.230',path='/org/example/monitor',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesAdded'"
method return time=1750287421.989931 sender=org.freedesktop.DBus -> destination=:1.166 serial=178 reply_serial=298
method call time=1750287421.990135 sender=:1.166 -> destination=org.freedesktop.DBus serial=299 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
string "type='signal',sender=':1.230',path='/org/example/monitor',interface='org.freedesktop.DBus.ObjectManager',member='InterfacesRemoved'"
method return time=1750287421.990162 sender=org.freedesktop.DBus -> destination=:1.166 serial=179 reply_serial=299
method call time=1750287421.990350 sender=:1.166 -> destination=org.freedesktop.DBus serial=300 path=/org/freedesktop/DBus; interface=org.freedesktop.DBus; member=AddMatch
string "type='signal',sender=':1.230',path_namespace='/org/example/monitor'"
method return time=1750287421.990378 sender=org.freedesktop.DBus -> destination=:1.166 serial=180 reply_serial=300
// Tries to GetManagedObjects
method call time=1750287421.990468 sender=:1.166 -> destination=:1.230 serial=301 path=/org/example/monitor; interface=org.freedesktop.DBus.ObjectManager; member=GetManagedObjects
// A while later, it errors out
error time=1750287447.016276 sender=:1.230 -> destination=:1.166 error_name=org.freedesktop.DBus.Error.UnknownObject reply_serial=301
string "Unknown object '/org/example/monitor'."
Additional context
Running on Ubuntu 24.04.2. I enabled experimental mode on bluetoothd, and have been able to add a monitor from bluetoothctl, so this should be working.
I'm building with Bazel, but I don't think that should matter?
cc_library(
name = "sdbus-cpp",
srcs = glob([
"src/*.h",
"src/*.c",
"src/*.cpp",
]),
hdrs = glob([
"include/sdbus-c++/**/*.h",
"include/sdbus-c++/**/*.inl",
]),
includes = ["include"],
copts = [
'-DSDBUS_HEADER=\"<systemd/sd-bus.h>\"',
],
linkopts = select({
"@//tools/toolchains:linux_aarch64_config": [],
"//conditions:default": [
"-lsystemd",
],
}),
)