3

I want to scan for changes of bluetooth devices under linux. I'm trying to implement this with the sdbus-c++ library version 1.40 and wrote following code:

// save to sdbus-example.cpp and compile with:
//     g++ -o sdbus-example sdbus-example.cpp $(pkg-config --cflags --libs sdbus-c++) 

#include <iostream>
#include <chrono>
#include <thread>
#include <exception>

#include <sdbus-c++/sdbus-c++.h>

int main()
{
    try {
        auto connection = sdbus::createSystemBusConnection();

        auto adapter =
            sdbus::createProxy(*connection, "org.bluez", "/org/bluez/hci0");

        std::string pattern =
            "type='signal'"
            ",sender='org.bluez'"
            ",interface='org.freedesktop.DBus.Properties'"
            ",member='PropertiesChanged'";

        std::cout << "pattern: " << pattern << std::endl;
        connection->addMatch(
            pattern,
            [](const auto &message) {
                auto objectPath = message.getPath();
                std::cout << "PATH: " << objectPath << std::endl;
            });

        adapter
            ->callMethod("StartDiscovery")
            .onInterface("org.bluez.Adapter1")
            .dontExpectReply();

        // Stop event loop after 10s
        std::thread stopThread(
            [&connection]() {
                std::cout << "Wait for 10s" << std::endl;
                using namespace std::literals::chrono_literals;
                std::this_thread::sleep_for(10s);
                connection->leaveEventLoop();
            });

        connection->enterEventLoop();

        adapter
            ->callMethod("StopDiscovery")
            .onInterface("org.bluez.Adapter1")
            .dontExpectReply();

        stopThread.join();
    }
    catch (const sdbus::Error& e) {
        std::cerr << "SDBUS ERROR: "
                  << e.getName()
                  << " / " <<  e.getMessage()
                  << std::endl;
        return 1;
    }
    catch (const std::exception &e) {
        std::cerr << "STD exception:: " << e.what() << std::endl;
    }

    return 0;
}

Any PropertiesChanged of org.bluez should be caught by connection->addMatch(). If i run the compiled program, the lambda of addMatch() will never be called. If i start dbus-monitor in parallel with the same pattern, it shows several messages:

dbus-monitor --system "type='signal',sender='org.bluez',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'"

The commands StartDiscovery and StopDiscovery appear to work and are also displayed by dbus-monitor, but the lambda of addMatch() did not see any of these messages.

What am I doing wrong? Do I need to activate something else on the connection so that the messages are processed?

1
  • 2
    When using a library, always include a link to the version you're using. Commented Oct 29 at 14:49

1 Answer 1

0

I find out by my self: The addMatch() method returns a slot instance. If this instance is destructed, the match rule is removed from the connection. This means that my code removes the rule immediately after it is created.

Quote from documentation:

Simply let go of the slot instance to uninstall the match rule from the bus connection. The slot must not outlive the connection for the slot is associated with it.

A working code is:

auto slot =
    connection->addMatch(
        pattern,
        [](const auto &message) {
            auto objectPath = message.getPath();
            std::cout << "PATH: " << objectPath << std::endl;
        });
...
connection->enterEventLoop();
slot.reset();
Sign up to request clarification or add additional context in comments.

4 Comments

What version of sdbus-c++ are you using? In the sources I found, the two-argument addMatch does not return a Slot, and the overload that does return Slot is attributed [[nodiscard]] which would have given you a diagnostic for discarding the return value.
Version 1.4.0 from TUXEDO 24.04 (UBUNTU/KUBUNTU clone).
It is also [[nodiscard]] in version 1.4.0, but my g++ version Ubuntu 13.3.0-6ubuntu2~24.04 does not warn at all. Even after adding options -Wall -Wpedantic 🤨
"does not warn at all" probably caused by stackoverflow.com/questions/67858389/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.