D-Bus API Quick Reference¶
D-Bus Quick Intro¶
D-Bus is a protocol, part of the freedesktop project, it is designed easier IPC on linux. It is a beautiful idea thus that for applications want to call functions in another program, they do not need to link against that service, they can simply issue a call on the dbus instead. D-Bus acts like Mediator pattern. DBus has implementations in many programming languages.
A DBus service firstly has a destination name which looks like this: org.freedesktop.DBus, then under this name, there are the object paths like */org/freedesktop/DBus*, then through the object path, we get to interface for its methods, properties and signals. We demostrate the usage through the
dbus-send --session --type=method_call --print-reply --dest=org.gnome.Rhythmbox /org/gnome/Rhythmbox/Player org.freedesktop.DBus.Introspectable.Introspect
This command sends a message to Rhythmbox for getting its available methods.
org.freedesktop.DBus.Introspectable.Introspect is the convention method to query the available methods in an interface.
There are two main dbus APIs, the “low level dbus c api” and the “systemd bus” API, the first one is more portable (available on freebsd, OSX through homebrew as well). Nevertheless, the api is not easy to use, that is why I created the tdbus (tiny dbus) project for easier usage.
In general, we touch the most the three parts of the API,
DBus Connection APIs¶
DBusConnection, as its name pronounced, maintains a connection to the DBus daemon. To work with it, DBus API provides 3 major routines to work with it; read, write and dispatch. The most simple case would be simply calling
dbus_connection_send_with_reply_and_block, it does all three things. But usually a software with a mainloop which polls on fds, DBus provides callbacks for
DBusDispatchFunction. For instance, we get the fd for a
dbus_watch_get_unix_fd; for Timeout, one can use timerfd for creating pollable fds. Note that
DBusConnection also has a
dbus_connection_get_unix_fd, but it is not pollable. For monitoring
DBusConnection, we need to create a fake
eventfd then call
wl_event_source_check for dispatching
DBus Message APIs¶
The messaging API is a subsystem itself. There is two concepts,
DBusSignature. Remember when we said dbus allows you to call functions? The signature here is the function argument types.
Those two provides iterators and sub-iterators, we call
dbus_signature_next to aquire next element,
dbus_message_iter_recurse for get into sub-types. We can also validate the signature by
dbus_signature_validate_single. Work with iterators is not particular easy, thus dbus has a shorthand for basic types.
dbus_message_append_args (message, DBUS_TYPE_INT32, &v_INT32, DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_INVALID);
For writing basic arguments,
dbus_message_get_args (message, DBUS_TYPE_INT32, &v_INT32, DBUS_TYPE_STRING, &v_STRING, DBUS_TYPE_INVALID);
Creating a DBusServer needs a little additional work. Firstly we need to call
dbus_bus_request_name to DBus Daemon to see if the service name is taken, then all we need to do is simply fill up the
DBusObjectPathVTable for answering the method calls and unregister handler which can be simply blank.
How to answer the method calls is totally the freedom of the server, except there are two mandatary methods, namely
Introspect (quering methods) and
Get (quering properties) for any usable dbus service.