usvi / libruuvitag

The Unlicense
0 stars 0 forks source link

Make simple DBUS Bluez connection from .so #3

Open usvi opened 1 year ago

usvi commented 1 year ago

We need to make a simple DBUS Bluez connection from the .so file

usvi commented 1 year ago

The documentation is very bad for beginners. My best bet is to take this:

https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/client

And slaughter it until it works.

usvi commented 1 year ago

Is this even real? The client is built on some kind of dbus wrappers (gdbus.h) which is not even published?

usvi commented 1 year ago

I have no idea what I am doing anymore

29637 sudo apt-get install libdbus-glib-1-dev 29640 sudo apt-get remove --purge libdbus-glib-1-dev 29641 sudo apt-get install libdbus-glib-1-dev 29644 sudo apt-get remove --purge libdbus-glib-1-dev 29683 apt-cache search glib-dev 29684 apt-cache search libglib-dev 29685 apt-cache search libglib 29686 sudo apt-get libglib2.0-dev 29687 sudo apt-get install libglib2.0-dev 29689 sudo apt-get remove libglib2.0-dev --purge 29692 sudo apt-get install libglib2.0-dev 29702 pkg-config --cflags glib-2.0 29703 pkg-config --libs glib-2.0 29723 pkg-config --cflags glib-2.0 34266 pkg-config --cflags glib-2.0 34269 history | grep glib 34270 sudo apt-get install libglib2.0 34271 history | grep glib

usvi commented 1 year ago

https://dbus.freedesktop.org/doc/dbus-tutorial.html

"GLib APIs

The recommended GLib API for D-Bus is GDBus, which has been distributed with GLib since version 2.26. It is not documented here. See the GLib documentation for details of how to use GDBus.

An older API, dbus-glib, also exists. It is deprecated and should not be used in new code. Whenever possible, porting existing code from dbus-glib to GDBus is also recommended."

usvi commented 1 year ago

It looks like GLib GDBus has nothing to do with bluez gdbus.h. Look what this says:

https://dbus.freedesktop.org/doc/dbus-glib/

"

dbus-glib is a deprecated API for use of D-Bus from GLib applications. Do not use it in new code.

Since version 2.26, GLib's accompanying GIO library provides a high-level API for D-Bus, "GDBus", based on an independent reimplementation of the D-Bus protocol. The maintainers of D-Bus recommend that GLib applications should use GDBus instead of dbus-glib."

So what is needed is checking out gio.h , then porting bluez client code to it.

Probably other good gio examples also exist.

usvi commented 1 year ago

https://stackoverflow.com/questions/36986621/is-gdbus-part-of-bluez-glib-or-neither

usvi commented 1 year ago

This looks worth taking a look:

https://www.linumiz.com/bluetooth-list-devices-using-gdbus/

usvi commented 1 year ago

https://gist.github.com/parthitce/eb6b751df3235f7247babc4c9aba41d8

usvi commented 1 year ago

https://stackoverflow.com/questions/51269129/minimal-gdbus-client

usvi commented 1 year ago

https://stackoverflow.com/questions/38953175/connect-to-a-bluetooth-le-device-using-bluez-python-dbus-interface

usvi commented 1 year ago

dbus-monitor --system "type='signal',sender='org.bluez'"

usvi commented 1 year ago

Where does the initial come from?

~$ bluetoothctl [NEW] Controller 00:15:83:FF:A6:DE ESLD [default] Agent registered [bluetooth]# quit Agent unregistered [DEL] Controller 00:15:83:FF:A6:DE ESLD [default]

usvi commented 1 year ago
static void print_adapter(GDBusProxy *proxy, const char *description):

        bt_shell_printf("%s%s%sController %s %s %s\n",
                            description ? "[" : "",
                description ? : "",
                                description ? "] " : "",
                                address, name,
                default_ctrl &&
                                default_ctrl->proxy == proxy ?
                "[default]" : "");

static void adapter_added(GDBusProxy *proxy)
{
        struct adapter *adapter;
        adapter = find_ctrl(ctrl_list, g_dbus_proxy_get_path(proxy));
        if (!adapter)
                adapter = adapter_new(proxy);

        adapter->proxy = proxy;

        print_adapter(proxy, COLORED_NEW);
    bt_shell_set_env(g_dbus_proxy_get_path(proxy), proxy);
}

static void proxy_added(GDBusProxy *proxy, void *user_data)
{
    const char *interface;

        interface = g_dbus_proxy_get_interface(proxy);

    if (!strcmp(interface, "org.bluez.Device1")) {
                device_added(proxy);
    } else if (!strcmp(interface, "org.bluez.Adapter1")) {
                adapter_added(proxy);

main.c:
    if (endpoint_option)
                bt_shell_set_env("AUTO_REGISTER_ENDPOINT",
                                        (void *)endpoint_option);

        admin_add_submenu();
    player_add_submenu();

        client = g_dbus_client_new(dbus_conn, "org.bluez", "/org/bluez");

        g_dbus_client_set_connect_watch(client, connect_handler, NULL);
    g_dbus_client_set_disconnect_watch(client, disconnect_handler, NULL);
        g_dbus_client_set_signal_watch(client, message_handler, NULL);

        g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
                                                    property_changed, NULL);

    g_dbus_client_set_ready_watch(client, client_ready, NULL);

    status = bt_shell_run();
usvi commented 1 year ago

Newer example has:

g_dbus_connection_call(con, "org.bluez", / TODO Find the adapter path runtime / "/org/bluez/hci0", "org.bluez.Adapter1", method, param, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, method_cb, (void *)method);

The interface being:

void g_dbus_connection_call(GDBusConnection connection, const gchar bus_name, const gchar object_path, const gchar interface_name, const gchar method_name, GVariant parameters, const GVariantType reply_type, GDBusCallFlags flags, gint timeout_msec, GCancellable cancellable, GAsyncReadyCallback callback, gpointer user_data);

usvi commented 1 year ago

Maybe call GetManagedObjects on / ?

usvi commented 1 year ago

Ah finally, this is a proxy:

https://dbus.freedesktop.org/doc/dbus-tutorial.html

A proxy object is a convenient native object created to represent a remote object in another process. The low-level DBus API involves manually creating a method call message, sending it, then manually receiving and processing the method reply message. Higher-level bindings provide proxies as an alternative. Proxies look like a normal native object; but when you invoke a method on the proxy object, the binding converts it into a DBus method call message, waits for the reply message, unpacks the return value, and returns it from the native method..

In pseudocode, programming without proxies might look like this:

      Message message = new Message("/remote/object/path", "MethodName", arg1, arg2);
      Connection connection = getBusConnection();
      connection.send(message);
      Message reply = connection.waitForReply(message);
      if (reply.isError()) {

      } else {
         Object returnValue = reply.getReturnValue();
      }

Programming with proxies might look like this:

      Proxy proxy = new Proxy(getBusConnection(), "/remote/object/path");
      Object returnValue = proxy.MethodName(arg1, arg2);
usvi commented 1 year ago

dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/' org.freedesktop.DBus.ObjectManager.GetManagedObjects

usvi commented 1 year ago

Another thing from the guy:

https://gist.github.com/parthitce/300b91186bcefbb8ed4798c8eab8d265

usvi commented 1 year ago

Interesting. All calls are "by default" asynchronous, requiring callbacks. Synchronous calls are used with _sync variants.

See https://www.freedesktop.org/software/gstreamer-sdk/data/docs/latest/gio/GDBusProxy.html

usvi commented 1 year ago

Now the question quickly becomes: What should we qualify as interfaces? The library init should have a syntax. Maybe:

Listen On parameter: "+CURRENT+ADDED-hci1+00:15:83:FF:A6:DE"

Minus denies, plus accepts, last has effect. So it will be a chain. Maybe even a linked list.

Update the list on start and on remove and on add. Always subscribe only on individual /org/bluez/hciX devices.

On startup:

  1. Reset subscriptions
  2. Gather a list of hciX/MAC pairs
  3. For each pair: Result after chain (CURRENT indicates positive positional match) => subscribe

On change:

  1. Reset subscriptions
  2. Gather a list of hciX/MAC pairs
  3. For each pair: Result after chain (ADDED indicates positive positional match) => subscribe
usvi commented 1 year ago

For first, we can just make the hci/MAC lister.

usvi commented 1 year ago

Bt adapter has this:

org.bluez.Adapter1

A device seen via adapter has this:

org.bluez.Device1

usvi commented 1 year ago

Output of terminal dbus command when 2 adapters connected

method return time=1672609063.209344 sender=:1.289 -> destination=:1.3051 serial=489 reply_serial=2
   array [
      dict entry(
         object path "/org/bluez"
         array [
            dict entry(
               string "org.freedesktop.DBus.Introspectable"
               array [
               ]
            )
            dict entry(
               string "org.bluez.AgentManager1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.ProfileManager1"
               array [
               ]
            )
         ]
      )
      dict entry(
         object path "/org/bluez/hci1"
         array [
            dict entry(
               string "org.freedesktop.DBus.Introspectable"
               array [
               ]
            )
            dict entry(
               string "org.bluez.Adapter1"
               array [
                  dict entry(
                     string "Address"
                     variant                         string "48:51:C5:72:67:75"
                  )
                  dict entry(
                     string "AddressType"
                     variant                         string "public"
                  )
                  dict entry(
                     string "Name"
                     variant                         string "ESLD #2"
                  )
                  dict entry(
                     string "Alias"
                     variant                         string "ESLD #2"
                  )
                  dict entry(
                     string "Class"
                     variant                         uint32 786432
                  )
                  dict entry(
                     string "Powered"
                     variant                         boolean true
                  )
                  dict entry(
                     string "Discoverable"
                     variant                         boolean false
                  )
                  dict entry(
                     string "DiscoverableTimeout"
                     variant                         uint32 180
                  )
                  dict entry(
                     string "Pairable"
                     variant                         boolean true
                  )
                  dict entry(
                     string "PairableTimeout"
                     variant                         uint32 0
                  )
                  dict entry(
                     string "Discovering"
                     variant                         boolean false
                  )
                  dict entry(
                     string "UUIDs"
                     variant                         array [
                           string "00001112-0000-1000-8000-00805f9b34fb"
                           string "00001801-0000-1000-8000-00805f9b34fb"
                           string "0000110e-0000-1000-8000-00805f9b34fb"
                           string "00001800-0000-1000-8000-00805f9b34fb"
                           string "00001200-0000-1000-8000-00805f9b34fb"
                           string "0000110c-0000-1000-8000-00805f9b34fb"
                           string "0000110a-0000-1000-8000-00805f9b34fb"
                           string "0000110b-0000-1000-8000-00805f9b34fb"
                           string "00001108-0000-1000-8000-00805f9b34fb"
                        ]
                  )
                  dict entry(
                     string "Modalias"
                     variant                         string "usb:v1D6Bp0246d0530"
                  )
               ]
            )
            dict entry(
               string "org.freedesktop.DBus.Properties"
               array [
               ]
            )
            dict entry(
               string "org.bluez.GattManager1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.LEAdvertisingManager1"
               array [
                  dict entry(
                     string "ActiveInstances"
                     variant                         byte 0
                  )
                  dict entry(
                     string "SupportedInstances"
                     variant                         byte 5
                  )
                  dict entry(
                     string "SupportedIncludes"
                     variant                         array [
                           string "tx-power"
                           string "appearance"
                           string "local-name"
                        ]
                  )
               ]
            )
            dict entry(
               string "org.bluez.Media1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.NetworkServer1"
               array [
               ]
            )
         ]
      )
      dict entry(
         object path "/org/bluez/hci0"
         array [
            dict entry(
               string "org.freedesktop.DBus.Introspectable"
               array [
               ]
            )
            dict entry(
               string "org.bluez.Adapter1"
               array [
                  dict entry(
                     string "Address"
                     variant                         string "00:15:83:FF:A6:DE"
                  )
                  dict entry(
                     string "AddressType"
                     variant                         string "public"
                  )
                  dict entry(
                     string "Name"
                     variant                         string "ESLD"
                  )
                  dict entry(
                     string "Alias"
                     variant                         string "ESLD"
                  )
                  dict entry(
                     string "Class"
                     variant                         uint32 786432
                  )
                  dict entry(
                     string "Powered"
                     variant                         boolean true
                  )
                  dict entry(
                     string "Discoverable"
                     variant                         boolean false
                  )
                  dict entry(
                     string "DiscoverableTimeout"
                     variant                         uint32 180
                  )
                  dict entry(
                     string "Pairable"
                     variant                         boolean true
                  )
                  dict entry(
                     string "PairableTimeout"
                     variant                         uint32 0
                  )
                  dict entry(
                     string "Discovering"
                     variant                         boolean false
                  )
                  dict entry(
                     string "UUIDs"
                     variant                         array [
                           string "00001112-0000-1000-8000-00805f9b34fb"
                           string "00001801-0000-1000-8000-00805f9b34fb"
                           string "0000110e-0000-1000-8000-00805f9b34fb"
                           string "00001800-0000-1000-8000-00805f9b34fb"
                           string "00001200-0000-1000-8000-00805f9b34fb"
                           string "0000110c-0000-1000-8000-00805f9b34fb"
                           string "0000110a-0000-1000-8000-00805f9b34fb"
                           string "0000110b-0000-1000-8000-00805f9b34fb"
                           string "00001108-0000-1000-8000-00805f9b34fb"
                        ]
                  )
                  dict entry(
                     string "Modalias"
                     variant                         string "usb:v1D6Bp0246d0530"
                  )
               ]
            )
            dict entry(
               string "org.freedesktop.DBus.Properties"
               array [
               ]
            )
            dict entry(
               string "org.bluez.GattManager1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.LEAdvertisingManager1"
               array [
                  dict entry(
                     string "ActiveInstances"
                     variant                         byte 0
                  )
                  dict entry(
                     string "SupportedInstances"
                     variant                         byte 5
                  )
                  dict entry(
                     string "SupportedIncludes"
                     variant                         array [
                           string "tx-power"
                           string "appearance"
                           string "local-name"
                        ]
                  )
               ]
            )
            dict entry(
               string "org.bluez.Media1"
               array [
               ]
            )
            dict entry(
               string "org.bluez.NetworkServer1"
               array [
               ]
            )
         ]
      )
   ]
usvi commented 1 year ago
dbus-send --system --print-reply --type=method_call --dest='org.bluez' '/org/bluez/hci0' org.bluez.Adapter1.GetDiscoveryFilters
method return time=1672614657.780228 sender=:1.289 -> destination=:1.3119 serial=687 reply_serial=2
   array [
      string "UUIDs"
      string "RSSI"
      string "Pathloss"
      string "Transport"
      string "DuplicateData"
   ]
usvi commented 1 year ago

I guess I also need org.freedesktop.DBus.ObjectManager.InterfacesAdded

usvi commented 1 year ago
    client->added_watch = g_dbus_add_signal_watch(connection, service,
                                                client->root_path,
                                                DBUS_INTERFACE_OBJECT_MANAGER,
                                                "InterfacesAdded",
                                                interfaces_added,
                                                client, NULL);
usvi commented 1 year ago

https://www.linumiz.com/bluetooth-removedevice-to-remove-the-device/

usvi commented 1 year ago

Worth checking:

https://stackoverflow.com/questions/36210133/getting-results-from-g-variant-new

usvi commented 1 year ago

Remember, we possibly need org.bluez.Device1

usvi commented 1 year ago

I think we are kind of finishing on this soon.

usvi commented 1 year ago

Extremely helpful command:

sudo dbus-monitor --system "type='signal',sender='org.bluez'"

usvi commented 1 year ago

And finally, here is our magic:

signal time=1672772401.041013 sender=:1.3493 -> destination=(null destination) serial=76 path=/org/bluez/hci0/dev_CD_99_36_8E_6E_70; interface=org.freedesktop.DBus.Properties; member=PropertiesChanged
   string "org.bluez.Device1"
   array [
      dict entry(
         string "ManufacturerData"
         variant             array [
               dict entry(
                  uint16 1177
                  variant                      array of bytes [
                        05 11 b0 2d 9a c9 d7 ff cc ff f8 04 08 c3 76 4a 14 bf
                        cd 99 36 8e 6e 70
                     ]
               )
            ]
      )
   ]
   array [
   ]
usvi commented 1 year ago

Lets analyze memory usage of different backends.

usvi commented 1 year ago

"Full" program with Glib Gio:

==69008== 
==69008== HEAP SUMMARY:
==69008==     in use at exit: 127,068 bytes in 1,536 blocks
==69008==   total heap usage: 5,408 allocs, 3,872 frees, 310,602 bytes allocated
==69008== 
==69008== LEAK SUMMARY:
==69008==    definitely lost: 48 bytes in 1 blocks
==69008==    indirectly lost: 8,978 bytes in 248 blocks
==69008==      possibly lost: 2,400 bytes in 26 blocks
==69008==    still reachable: 104,770 bytes in 1,180 blocks
==69008==                       of which reachable via heuristic:
==69008==                         length64           : 768 bytes in 15 blocks
==69008==                         newarray           : 1,728 bytes in 28 blocks
==69008==         suppressed: 0 bytes in 0 blocks
==69008== Rerun with --leak-check=full to see details of leaked memory
==69008== 
==69008== For counts of detected and suppressed errors, rerun with: -v
==69008== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
usvi commented 1 year ago

Only system bus connect and release, Glib / Gio:

==69194== LEAK SUMMARY:
==69194==    definitely lost: 0 bytes in 0 blocks
==69194==    indirectly lost: 0 bytes in 0 blocks
==69194==      possibly lost: 2,400 bytes in 26 blocks
==69194==    still reachable: 100,941 bytes in 1,103 blocks
==69194==                       of which reachable via heuristic:
==69194==                         length64           : 768 bytes in 15 blocks
==69194==                         newarray           : 1,728 bytes in 28 blocks
==69194==         suppressed: 0 bytes in 0 blocks
==69194== 
==69194== For counts of detected and suppressed errors, rerun with: -v
==69194== ERROR SUMMARY: 26 errors from 26 contexts (suppressed: 0 from 0)
usvi commented 1 year ago

Only system bus connect and release, libdbus-1:

==69469== LEAK SUMMARY:
==69469==    definitely lost: 0 bytes in 0 blocks
==69469==    indirectly lost: 0 bytes in 0 blocks
==69469==      possibly lost: 0 bytes in 0 blocks
==69469==    still reachable: 10,220 bytes in 81 blocks
==69469==         suppressed: 0 bytes in 0 blocks
==69469== 
==69469== For counts of detected and suppressed errors, rerun with: -v
==69469== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
usvi commented 1 year ago

Libsystemd sd-bus:

==69536== LEAK SUMMARY:
==69536==    definitely lost: 0 bytes in 0 blocks
==69536==    indirectly lost: 0 bytes in 0 blocks
==69536==      possibly lost: 0 bytes in 0 blocks
==69536==    still reachable: 7,736 bytes in 12 blocks
==69536==         suppressed: 0 bytes in 0 blocks
==69536== 
==69536== For counts of detected and suppressed errors, rerun with: -v
==69536== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
usvi commented 1 year ago

To me it looks like glib is total garbage, libdbus-1 doing much better (but lots of blocks used) and then finally sd-bus not being perfect but best of the available ones. Maybe going with sd-bus.

usvi commented 1 year ago

Ah, realized sd-bus is probably so deeply married to systemd that better to use libdbus-1.

usvi commented 1 year ago

" https://stackoverflow.com/questions/9378593/dbuswatch-and-dbustimeout-examples#comment96600576_44095756

Everybody voted for the example above, but this has the correct behavior of calling dbus_connection_get_dispatch_status() when you are done setting everything up and then triggering a dispatch if (status == DBUS_DISPATCH_DATA_REMAINS). –  TaborKelly Feb 28, 2019 at 2:07 "

usvi commented 1 year ago

"These next two operations require reading messages from the bus and handling them. There is not a simple way in the C API as of 0.50 to do this. Because DBUS is designed to use OO bindings and an event based model all the methods that handle the messages on the wire use callbacks. I have submitted a patch which should make it into the next release which allows messages to be read and marshalled from the wire in a non-blocking operation. This is the dbus_connection_read_write() method, which is required to use the code on this page. "

usvi commented 1 year ago

We should make our own messages for startup and shutdown. And the startup message would set everything up.

usvi commented 1 year ago

Ah, realized sd-bus is probably so deeply married to systemd that better to use libdbus-1.

Actually, this does not matter. I'm using bluez, so I am in anyways married to Linux at this point. Only thing is if I can do proper teardown.

usvi commented 1 year ago

Ah, realized sd-bus is probably so deeply married to systemd that better to use libdbus-1.

Actually, this does not matter. I'm using bluez, so I am in anyways married to Linux at this point. Only thing is if I can do proper teardown.

Actually there is value in doing it with libdbus-1. It would be a demonstration of custom event loop, very minimal in aspects.

usvi commented 1 year ago

"ou are missing the event loop which is otherwise available by default if you choose to go with one of the bindings. When you get a call to add_watch, libdbus expects that the application will attach an IO handler to it. The IOHandler added by application will watch for an activity on the fd (filedescriptor) queried for the watch. Whenever there is an activity on that file descriptor, the IOHandler will trigger a callback with appropriate flags that you need to convert to DBUS flags before calling dbus_watch_handle.

Suggest that you use glib if you don't know how to use event loops. I am able to get it if I use libUV or libEV as low footprint event loop."

usvi commented 1 year ago

Seems it is easier to start from the core and then work upwards in call chain.

usvi commented 1 year ago
signal time=1688937441.975826 sender=:1.3423 -> destination=(null destination) serial=190 path=/; interface=org.freedesktop.DBus.ObjectManager; member=InterfacesAdded
   object path "/org/bluez/hci0"
   array [
      dict entry(
         string "org.freedesktop.DBus.Introspectable"
         array [
         ]
      )
      dict entry(
         string "org.bluez.Adapter1"
         array [
            dict entry(
               string "Address"
               variant                   string "00:15:83:FF:A6:DE"
            )
            dict entry(
               string "AddressType"
               variant                   string "public"
            )
            dict entry(
               string "Name"
               variant                   string "ESLD"
            )
            dict entry(
               string "Alias"
               variant                   string "ESLD"
            )
            dict entry(
               string "Class"
               variant                   uint32 0
            )
            dict entry(
               string "Powered"
               variant                   boolean false
            )
            dict entry(
               string "Discoverable"
               variant                   boolean false
            )
            dict entry(
               string "DiscoverableTimeout"
               variant                   uint32 180
            )
            dict entry(
               string "Pairable"
               variant                   boolean false
            )
            dict entry(
               string "PairableTimeout"
               variant                   uint32 0
            )
            dict entry(
               string "Discovering"
               variant                   boolean false
            )
            dict entry(
               string "UUIDs"
               variant                   array [
                     string "00001112-0000-1000-8000-00805f9b34fb"
                     string "00001108-0000-1000-8000-00805f9b34fb"
                     string "00001801-0000-1000-8000-00805f9b34fb"
                     string "0000110e-0000-1000-8000-00805f9b34fb"
                     string "00001200-0000-1000-8000-00805f9b34fb"
                     string "0000110c-0000-1000-8000-00805f9b34fb"
                     string "00001800-0000-1000-8000-00805f9b34fb"
                  ]
            )
            dict entry(
               string "Modalias"
               variant                   string "usb:v1D6Bp0246d0530"
            )
         ]
      )
      dict entry(
         string "org.freedesktop.DBus.Properties"
         array [
         ]
      )
      dict entry(
         string "org.bluez.GattManager1"
         array [
         ]
      )
      dict entry(
         string "org.bluez.LEAdvertisingManager1"
         array [
            dict entry(
               string "ActiveInstances"
               variant                   byte 0
            )
            dict entry(
               string "SupportedInstances"
               variant                   byte 5
            )
            dict entry(
               string "SupportedIncludes"
               variant                   array [
                     string "tx-power"
                     string "appearance"
                     string "local-name"
                  ]
            )
         ]
      )
      dict entry(
         string "org.bluez.Media1"
         array [
         ]
      )
      dict entry(
         string "org.bluez.NetworkServer1"
         array [
         ]
      )
   ]
usvi commented 1 year ago

https://dbus.freedesktop.org/doc/api/html/group__DBusConnection.html#ga0556779e61aeb19eb9cf6b6466bd1b98

Marking this down:

"DBUS_WATCH_READABLE
As in POLLIN.

DBUS_WATCH_WRITABLE
As in POLLOUT.

DBUS_WATCH_ERROR
As in POLLERR (can't watch for this, but can be present in current state passed to dbus_watch_handle()).

DBUS_WATCH_HANGUP
As in POLLHUP (can't watch for it, but can be present in current state passed to dbus_watch_handle()). "

usvi commented 1 year ago

"dbus_watch_get_flags() unsigned int dbus_watch_get_flags ( DBusWatch * watch )

Gets flags from DBusWatchFlags indicating what conditions should be monitored on the file descriptor.

The flags returned will only contain DBUS_WATCH_READABLE and DBUS_WATCH_WRITABLE, never DBUS_WATCH_HANGUP or DBUS_WATCH_ERROR; all watches implicitly include a watch for hangups, errors, and other exceptional conditions."

usvi commented 1 year ago

Example use of wake up functionality:

 114             : /* dbus_connection_wakeup_main
 115             :  * D-BUS makes a callback to the wakeup_main function when
 116             :  * it has data available for dispatching.
 117             :  * In order to avoid blocking, this function will create a now()
 118             :  * timed event to perform the dispatch during the next iteration
 119             :  * through the mainloop
 120             :  */
 121           0 : static void sbus_conn_wakeup_main(void *data)
 122             : {
 123             :     struct sbus_connection *conn;
 124             :     struct timeval tv;
 125             :     struct tevent_timer *te;
 126             : 
 127           0 :     conn = talloc_get_type(data, struct sbus_connection);
 128             : 
 129           0 :     tv = tevent_timeval_current();
 130             : 
 131             :     /* D-BUS calls this function when it is time to do a dispatch */
 132           0 :     te = tevent_add_timer(conn->ev, conn, tv, sbus_dispatch, conn);
 133           0 :     if (te == NULL) {
 134           0 :         DEBUG(SSSDBG_OP_FAILURE,"Could not add dispatch event!\n");
 135             :         /* TODO: Calling exit here is bad */
 136           0 :         exit(1);
 137             :     }
 138           0 : }