Editing Documentation/Maemo 5 Developer Guide/DBus/DBus Basics

Warning: You are not logged in. Your IP address will be recorded in this page's edit history.

Warning: This page is 32 kilobytes long; some browsers may have problems editing pages approaching or longer than 32kb. Please consider breaking the page into smaller sections.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 32: Line 32:
In addition to the single system bus, a separate session bus for each desktop session can exist. Because all user applications in a Maemo-compatible device run with the same user ID, the device only has one session bus as well.
In addition to the single system bus, a separate session bus for each desktop session can exist. Because all user applications in a Maemo-compatible device run with the same user ID, the device only has one session bus as well.
-
A bus exists in the system in the form of a ''bus daemon'', a process that specializes in passing messages from one process to another. The daemon also forwards notifications to all applications on the bus. At the lowest level, D-Bus only supports point-to-point communication, normally using the local domain sockets (<code>AF_UNIX</code>) between the application and the bus daemon. The point-to-point aspect of D-Bus is, however, abstracted by the bus daemon, which implements the addressing and message passing functionality. This means that applications do not need to care about which specific process receives each method call or notification.
+
A bus exists in the system in the form of a ''bus daemon'', a process that specializes in passing messages from one process to another. The daemon also forwards notifications to all applications on the bus. At the lowest level, D-Bus only supports point-to-point communication, normally using the local domain sockets (AF_UNIX) between the application and the bus daemon. The point-to-point aspect of D-Bus is, however, abstracted by the bus daemon, which implements the addressing and message passing functionality. This means that applications do not need to care about which specific process receives each method call or notification.
According to the above-mentioned details, sending a message using D-Bus always involves the following steps (under normal conditions):
According to the above-mentioned details, sending a message using D-Bus always involves the following steps (under normal conditions):
Line 54: Line 54:
** Examples: <code>org.maemo.Alert</code> and <code>org.freedesktop.Notifications</code>.
** Examples: <code>org.maemo.Alert</code> and <code>org.freedesktop.Notifications</code>.
* Each service can contain multiple different objects, each of which provides a different (or the same) service. In order to separate one object from another, ''object paths'' are used. A personal information manager (PIM) information store, for example, might include separate objects to manage the contact information and synchronization.
* Each service can contain multiple different objects, each of which provides a different (or the same) service. In order to separate one object from another, ''object paths'' are used. A personal information manager (PIM) information store, for example, might include separate objects to manage the contact information and synchronization.
-
** Object paths look like file paths (elements separated with the '<code>/</code>' character).
+
** Object paths look like file paths (elements separated with the '/' character).
** In D-Bus, "lazy binding" can also be made, so that a specific function in the recipient is called on all remote method calls, irrespective of the object paths in the calls. This allows the on-demand targeting of method calls, so that the user can remove a specific object in an address book service (using an object path similar to <code>/org/maemo/AddressBook/Contacts/ShortName</code>). Due to the limitations on characters that can be put into the object path, this is not recommended. A better way is to supply the ShortName as a method call argument instead (as a UTF-8 formatted string).
** In D-Bus, "lazy binding" can also be made, so that a specific function in the recipient is called on all remote method calls, irrespective of the object paths in the calls. This allows the on-demand targeting of method calls, so that the user can remove a specific object in an address book service (using an object path similar to <code>/org/maemo/AddressBook/Contacts/ShortName</code>). Due to the limitations on characters that can be put into the object path, this is not recommended. A better way is to supply the ShortName as a method call argument instead (as a UTF-8 formatted string).
** The object path is usually formed using the same elements as in the well-known name, but replacing the dots with slashes, and appending a specific object name to the end. For example: <code>/org/maemo/Alert/Alerter</code>. This is the common convention, but it also solves a specific problem if a process could re-use an existing D-Bus connection without explicitly knowing about it (using a library that encapsulates D-Bus functionality). In such cases, using short names increases the risk of name-space collisions within that process.
** The object path is usually formed using the same elements as in the well-known name, but replacing the dots with slashes, and appending a specific object name to the end. For example: <code>/org/maemo/Alert/Alerter</code>. This is the common convention, but it also solves a specific problem if a process could re-use an existing D-Bus connection without explicitly knowing about it (using a library that encapsulates D-Bus functionality). In such cases, using short names increases the risk of name-space collisions within that process.
Line 128: Line 128:
<pre>
<pre>
-
[sbox-DIABLO_X86: ~] > run-standalone.sh dbus-send --print-reply  \
+
[sbox-DIABLO_X86: ~] > run-standalone.sh dbus-send --print-reply  \
-
--type=method_call --dest=org.freedesktop.Notifications  \
+
  --type=method_call --dest=org.freedesktop.Notifications  \
-
/org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog  \
+
  /org/freedesktop/Notifications org.freedesktop.Notifications.SystemNoteDialog  \
-
string:'Hello, world!' uint32:0 string:'NAO OK!'
+
  string:'Hello, world!' uint32:0 string:'NAO OK!'
-
method return sender=:1.1 -> dest=:1.15
+
method return sender=:1.1 -> dest=:1.15
-
  uint32 4
+
    uint32 4
</pre>
</pre>
Line 140: Line 140:
Assuming that the above command is run while the application framework is already running, the end result looks like this:
Assuming that the above command is run while the application framework is already running, the end result looks like this:
-
[[Image:dbus-send-SystemNoteDialog.png|frame|center|alt=Screenshot of Note dialog showing text ‘Hello, world!’|System note dialog]]
+
[[Image:dbus-send-SystemNoteDialog.png|Image dbus-send-SystemNoteDialog]]
If the command is repeated multiple times, the notification service is capable of displaying only one dialog at a time. This makes sense because the dialog is modal. Furthermore, the method calls are queued, not lost; the notification service displays all of the requested dialogs. The service also acknowledges the RPC method call without delay (which is not always the obvious thing to do), giving a different return value each time (incrementing by one each time).
If the command is repeated multiple times, the notification service is capable of displaying only one dialog at a time. This makes sense because the dialog is modal. Furthermore, the method calls are queued, not lost; the notification service displays all of the requested dialogs. The service also acknowledges the RPC method call without delay (which is not always the obvious thing to do), giving a different return value each time (incrementing by one each time).
Line 160: Line 160:
At this point, this example ignores the warnings, and uses the library to implement a simple program that replicates the earlier <code>dbus-send</code> example. To do this with the minimum amount of code, the code does not process (or expect) any responses to the method call. However, the code demonstrates the bare minimum function calls that are needed to send messages on the bus.
At this point, this example ignores the warnings, and uses the library to implement a simple program that replicates the earlier <code>dbus-send</code> example. To do this with the minimum amount of code, the code does not process (or expect) any responses to the method call. However, the code demonstrates the bare minimum function calls that are needed to send messages on the bus.
-
The first step is to introduce the necessary header files. [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
The first step is to introduce the necessary header files. libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 177: Line 177:
Unlike the rest of the code in this material, the dbus example does not use GLib or other support libraries (other than libdbus). This explains why the example uses printf and other functions that are normally replaced with GLib equivalents.
Unlike the rest of the code in this material, the dbus example does not use GLib or other support libraries (other than libdbus). This explains why the example uses printf and other functions that are normally replaced with GLib equivalents.
-
Connecting to the session bus yields a <code>DBusConnection</code> structure: [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
Connecting to the session bus yields a <code>DBusConnection</code> structure: libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 217: Line 217:
Libdbus attempts to share the existing connection structures when the same process is connecting to the same bus. This is done to avoid the costly connection set-up time. Sharing connections is beneficial when the program is using libraries that would also open their own connections to the same buses.
Libdbus attempts to share the existing connection structures when the same process is connecting to the same bus. This is done to avoid the costly connection set-up time. Sharing connections is beneficial when the program is using libraries that would also open their own connections to the same buses.
-
To communicate errors, libdbus uses <code>DBusError</code> structures, whose contents are simple. The dbus_error_init is used for guaranteeing that the error structure contains a non-error state before connecting to the bus. If there is an error, it is handled in <code>terminateOnError</code>: [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
To communicate errors, libdbus uses <code>DBusError</code> structures, whose contents are simple. The dbus_error_init is used for guaranteeing that the error structure contains a non-error state before connecting to the bus. If there is an error, it is handled in <code>terminateOnError</code>: libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 256: Line 256:
</source>
</source>
-
libdbus also contains some utility functions so that everything does not have to be coded manually. One such utility is <code>dbus_bus_name_has_owner</code>, that checks whether there is at least some process that owns the given well-known name at that moment: [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
libdbus also contains some utility functions so that everything does not have to be coded manually. One such utility is <code>dbus_bus_name_has_owner</code>, that checks whether there is at least some process that owns the given well-known name at that moment: libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 288: Line 288:
</source>
</source>
-
Creating a method call using libdbus is slightly more tedious than using the higher-level interfaces. The process is separated into two steps: creating a message structure, and appending the arguments to the message: [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
Creating a method call using libdbus is slightly more tedious than using the higher-level interfaces. The process is separated into two steps: creating a message structure, and appending the arguments to the message: libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 335: Line 335:
When arguments are appended to the message, their content is copied, and possibly converted into a format that is sent over the connection to the daemon. This process is called marshaling, and is a common feature to most RPC systems. The method call requires two parameters (as before), the first being the text to be displayed, and the second being the style of the icon to be used. Parameters passed to libdbus are always passed by address. This is different from the higher level libraries.
When arguments are appended to the message, their content is copied, and possibly converted into a format that is sent over the connection to the daemon. This process is called marshaling, and is a common feature to most RPC systems. The method call requires two parameters (as before), the first being the text to be displayed, and the second being the style of the icon to be used. Parameters passed to libdbus are always passed by address. This is different from the higher level libraries.
-
The arguments are encoded, so that their type code is followed by the pointer where the marshaling functions can find the content. The argument list is terminated with <code>DBUS_TYPE_INVALID</code>, so that the function knows where the argument list ends (since the function prototype ends with an ellipsis, ...). [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
The arguments are encoded, so that their type code is followed by the pointer where the marshaling functions can find the content. The argument list is terminated with <code>DBUS_TYPE_INVALID</code>, so that the function knows where the argument list ends (since the function prototype ends with an ellipsis, ...). libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 350: Line 350:
Setting the no-reply-flag effectively tells the bus daemon that even if there is a reply coming back for this RPC method, it is not wanted. In this case, the daemon does not send a reply.
Setting the no-reply-flag effectively tells the bus daemon that even if there is a reply coming back for this RPC method, it is not wanted. In this case, the daemon does not send a reply.
-
Once the message is fully constructed, it can be added to the sending queue of the program. Messages are not sent immediately by libdbus. Normally this allows the message queue to accumulate to more than one message, and all of the messages are sent at once to the daemon. This in turn cuts down the number of the necessary context switches. In this case, this message is the only message that the program ever sends, so the send queue is instructed to be flushed immediately, which in turn instructs the library to send all messages to the daemon without a delay: [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
Once the message is fully constructed, it can be added to the sending queue of the program. Messages are not sent immediately by libdbus. Normally this allows the message queue to accumulate to more than one message, and all of the messages are sent at once to the daemon. This in turn cuts down the number of the necessary context switches. In this case, this message is the only message that the program ever sends, so the send queue is instructed to be flushed immediately, which in turn instructs the library to send all messages to the daemon without a delay: libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 369: Line 369:
</source>
</source>
-
After the message is sent, the reserved resources must be freed. Here, the first one to be freed is the message, and then the connection structure. [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/dbus-example.c libdbus-example/dbus-example.c]
+
After the message is sent, the reserved resources must be freed. Here, the first one to be freed is the message, and then the connection structure. libdbus-example/dbus-example.c
<source lang="c">
<source lang="c">
Line 426: Line 426:
The error message (about <code>/dev/dsp</code>) printed to the same terminal where AF was started is normal behavior (in SDK). Displaying the Note dialog normally also causes an "Alert" sound to be played. The sound system has not been setup in the SDK, so the notification component complains about failing to open the sound device.
The error message (about <code>/dev/dsp</code>) printed to the same terminal where AF was started is normal behavior (in SDK). Displaying the Note dialog normally also causes an "Alert" sound to be played. The sound system has not been setup in the SDK, so the notification component complains about failing to open the sound device.
-
[[Image:libdbus-example.png|frame|center|alt=Screenshot of message ‘Hello World!’|The friendly error message, using low-level D-Bus]]
+
[[Image:libdbus-example.png|Image libdbus-example]]The friendly error message, using low-level D-Bus
-
To get libdbus integrated into makefiles, use pkg-config. One possible solution is presented below (see section [[Documentation/Maemo 5 Developer Guide/GNU Build System#GNU Make and Makefiles|GNU Make and Makefiles]] in chapter [[Documentation/Maemo 5 Developer Guide/GNU Build System|GNU Build System]], if necessary): [https://vcs.maemo.org/svn/maemoexamples/trunk/libdbus-example/Makefile libdbus-example/Makefile]
+
To get libdbus integrated into makefiles, use pkg-config. One possible solution is presented below (see section [[Documentation/Maemo 5 Developer Guide/GNU Build System#GNU Make and Makefiles|GNU Make and Makefiles]] in chapter [[Documentation/Maemo 5 Developer Guide/GNU Build System|GNU Build System]], if necessary): libdbus-example/Makefile
<source lang="make">
<source lang="make">

Learn more about Contributing to the wiki.


Please note that all contributions to maemo.org wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see maemo.org wiki:Copyrights for details). Do not submit copyrighted work without permission!


Cancel | Editing help (opens in new window)