Meego Wiki
Views
From MeeGo wiki
(Difference between revisions)
Jump to: navigation, search
m (moved DBus: an overview to D-Bus: an overview: Use correct punctuation)
Line 1: Line 1:
== Introduction ==
== Introduction ==
-
D-Bus is an Inter Process Communication (IPC) system, providing a mechanism for applications running on a single machine to "talk" to each other. Due to its focus on being a message bus for local applications, D-Bus has some nice features compared to alternative IPC mechanisms: these include the capability to autostart applications which are not yet active but which have been sent a message; and the ability to ensure that only a single instance of an application is ever running.
+
D-Bus is an Inter Process Communication (IPC) system, providing a mechanism for applications running on a single machine to "talk" to each other. Due to its focus on being a message bus for local applications, D-Bus has some nice features compared to alternative IPC mechanisms: these include the capability to autostart applications which are not active but which have been sent a message; and the ability to ensure that only a single instance of an application is ever running.
-
<h3>Message buses</h3>
+
=== Message buses ===
-
<p>The core D-Bus protocol is a 2-way, asynchronous, binary protocol. While it is possible to use for direct application to application communication (using libdbus - not recommended), the most common usage of the protocol is via a D-Bus message bus server. The server is connected to each client using D-Bus, and routes each message from the application which sent it its intended recipient. Each application which exposes its capabilities on the bus is known as a <strong>service</strong>. (An application doesn't have to expose any services to make use of the bus: it can just send messages to other applications which <em>do</em> provide services.)</p>
+
The core D-Bus protocol is a 2-way, asynchronous, binary protocol. While it is possible to use for direct application to application communication (using libdbus - not recommended), the most common usage of the protocol is via a D-Bus message bus server. The server is connected to each client using D-Bus, and routes each message from the application which sent it its intended recipient. Each application which exposes its capabilities on the bus is known as a '''service'''. (An application doesn't have to expose any services to make use of the bus: it can just send messages to other applications which ''do'' provide services.)
<img src="http://moblin.org/sites/all/files/message_bus.png" alt="D-Bus message bus" title="D-Bus message bus" />
<img src="http://moblin.org/sites/all/files/message_bus.png" alt="D-Bus message bus" title="D-Bus message bus" />
-
<p>There are actually multiple D-Bus message buses running on Moblin (and on your average Linux system) at any one time, of two types:</p>
+
There are actually multiple D-Bus message buses running on Moblin (and on your average Linux system) at any one time, of two types:
-
<ol>
+
* The ''system bus'' is a machine-global, single instance of the daemon with security restrictions on what messages it will accept. It's used for system-wide communication and communication between the user desktop and the operating system.
-
<li>The System bus is a machine-global, single instance of the daemon with security restrictions on what messages it will accept. It's used for system-wide communication and communication between the user desktop and the operating system.</li>
+
* A ''session bus'' is created for each user session. It allows applications within that user session to communicate. Most MeeGo D-Bus services (connman etc.) communicate via the session bus.
-
<li>Session buses are created per user session. They allow applications within that user session to communicate. Most Moblin D-Bus services (Bognor Regis etc.) communicate via the session bus.</li>
+
-
</ol>
+
-
<h3>Services, trees, interfaces, and objects</h3>
+
=== Services, trees, interfaces, and objects ===
-
<p>Services on a D-Bus expose a tree of objects to interact with. Each service has a root path; from the root come branches, one for each object provided by that service. Each object on a service tree is addressable by an <strong>object path</strong>.</p>
+
Services on a D-Bus expose a tree of objects to interact with. Each service has a root path; from the root come branches, one for each object provided by that service. Each object on a service tree is addressable by an ''object path''.
-
<p>Object paths are typically in a reverse-domain name format, akin to Java package names; for example, org.moblin.connman for the ConnMan root path.</p>
+
Object paths are typically in a reverse-domain name format, akin to Java package names; for example, <code>org.moblin.connman</code> for the ConnMan root path.
-
<p>Interfaces are the contract between an object and its callers, much like interfaces in Java, GObject etc.. An interface, as in most object-oriented programming environments, defines the methods and properties an object exposes. In addition, D-Bus interfaces can also contain signals. Signals provide a way for objects to notify other objects about events which happen to them: for example, a <em>Door</em> interface might provide a signal to other objects when it is opened, perhaps called <strong>door-opened</strong>. (A nearby <em>Doorman</em> object might listen out for <strong>door-opened</strong> signals, so it knows when people come into the building.)</p>
+
Interfaces are the contract between an object and its callers, much like interfaces in Java, GObject etc.. An interface, as in most object-oriented programming environments, defines the methods and properties an object exposes. In addition, D-Bus interfaces can also contain signals. Signals provide a way for objects to notify other objects about events which happen to them: for example, a <code>Door</code> interface might provide a signal to other objects when it is opened, perhaps called <code>door-opened</code>. (A nearby <code>Doorman</code> object might listen out for <code>door-opened</code> signals, so it knows when people come into the building.)
-
<p>Each D-Bus object implements one or more interfaces. Most implement two standard interfaces as a minimum, <em>org.freedesktop.DBus.Introspectable</em> and <em>org.freedesktop.DBus.Properties</em>:</p>
+
Each D-Bus object implements one or more interfaces. Most implement two standard interfaces as a minimum, <code>org.freedesktop.DBus.Introspectable</code> and <code>org.freedesktop.DBus.Properties</code>:
-
<ol>
+
* The <code>Introspectable</code> interface specifies a single method, <code>Introspect()</code>. Calling this method on an object returns a string of XML which defines the interfaces (and the properties, signals and methods of those interfaces) implemented by that object.
-
<li>
+
* The <code>Properties</code> interface specifies three standard methods for getting and setting an object's properties: <code>Get()</code>, <code>GetAll()</code>, and <code>Set()</code>.
-
The <em>Introspectable</em> interface specifies a single method, <em>Introspect()</em>. Calling this method on an object returns a string of XML which defines the interfaces (and the properties, signals and methods of those interfaces) implemented by that object.
+
** <code>Get()</code> takes the interface name and a property name as arguments and returns the value of the specified property.
-
</li>
+
** <code>GetAll()</code> takes the interface name and returns a dictionary of property name  to value mappings.
-
<li>
+
** <code>Set()</code> takes the interface name, a property name and the value to set for the property as arguments.
-
The <em>Properties</em> interface specifies three standard methods for getting and setting an object's properties: <em>Get()</em>, <em>GetAll()</em>, and <em>Set()</em>.
+
-
<ul>
+
-
<li><em>Get()</em> takes the interface name and a property name as arguments and returns the value of the specified property.</li>
+
-
<li><em>GetAll()</em> takes the interface name and returns a dictionary of property name  to value mappings.</li>
+
-
<li><em>Set()</em> takes the interface name, a property name and the value to set for the property as arguments.</li>
+
-
</ul>
+
-
</li>
+
-
</ol>
+
-
<h4>Investigating and debugging D-Bus services</h4>
+
== Investigating and debugging D-Bus services ==
-
<p>Often the easiest way to get started investigating a service on the Bus is to use D-Feet, a graphical D-Bus debugging tool.</p>
+
Often the easiest way to get started investigating a service on the Bus is to use D-Feet, a graphical D-Bus debugging tool.
<img src="/sites/all/files/u208/d-feet_fullth.png" preset="0" class="nofloat" alt="D-Feet screenshot" />
<img src="/sites/all/files/u208/d-feet_fullth.png" preset="0" class="nofloat" alt="D-Feet screenshot" />
-
<p>Using D-Feet, one can browse the tree of objects available for each service.</p>
+
Using D-Feet, one can browse the tree of objects available for each service.
-
<p>D-Feet uses the <em>Introspect()</em> method of the <em>Introspection</em> interface to determine what methods, properties and signals an object implements. It even allows execution of the available methods using a Python-like syntax for specifying arguments.</p>
+
D-Feet uses the <code>Introspect()</code> method of the <code>Introspection</code> interface to determine what methods, properties and signals an object implements. It even allows execution of the available methods using a Python-like syntax for specifying arguments.
-
<p>D-Feet is available in the Moblin package repositories and can be installed with:</p>
+
D-Feet is available in the MeeGo package repositories and can be installed with:
<code>
<code>
Line 56: Line 46:
</code>
</code>
-
<h3>Interacting with the bus programatically using high-level bindings</h3>
+
== Interacting with the bus programatically using high-level bindings ==
-
<p>High level bindings for D-Bus tend to provide a mechanism for proxying remote objects: so instead of having to deal with message sending directly, objects on the bus can be proxied to local objects in the application. From there, a program can interact with objects on the bus by calling methods on the proxied object.</p>
+
High level bindings for D-Bus tend to provide a mechanism for proxying remote objects: so instead of having to deal with message sending directly, objects on the bus can be proxied to local objects in the application. From there, a program can interact with objects on the bus by calling methods on the proxied object.
-
<h4>D-Bus GLib</h4>
+
===D-Bus GLib===
-
<p>The D-Bus GLib bindings (<em>yum install dbus-glib-devel</em>) offer a high-level, GObject-like binding for interacting with the D-Bus message bus.</p>
+
The D-Bus GLib bindings (<code>yum install dbus-glib-devel</code>) offer a high-level, GObject-like binding for interacting with the D-Bus message bus.
-
<p>Below is an example of using the bindings to determine the online state of a Moblin system using the D-Bus service provided by the ConnMan connectivity daemon.</p>
+
Below is an example of using the bindings to determine the online state of a Moblin system using the D-Bus service provided by the ConnMan connectivity daemon.
-
<p>Note: this code is also available in the <a href="http://git.moblin.org/cgit.cgi/moblin-sdk-examples/">moblin-sdk-examples git repository</a>: <a href="http://git.moblin.org/cgit.cgi/moblin-sdk-examples/tree/examples/dbus-glib/amionline.c">amionline.c</a></p>
+
<pre>
-
 
+
-
<code>
+
/*
/*
  * amionline.c
  * amionline.c
Line 82: Line 70:
#define CONNMAN_SERVICE          "org.moblin.connman"
#define CONNMAN_SERVICE          "org.moblin.connman"
#define CONNMAN_MANAGER_PATH      "/"
#define CONNMAN_MANAGER_PATH      "/"
-
#define CONNMAN_MANAGER_INTERFACE   CONNMAN_SERVICE ".Manager"
+
#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
-
static GMainLoop   *main_loop;
+
static GMainLoop *main_loop;
static void
static void
Line 95: Line 83:
dbus_g_proxy_end_call (proxy,
dbus_g_proxy_end_call (proxy,
-
                  call,
+
                              call,
-
      &error,
+
                              &error,
                               G_TYPE_STRING,
                               G_TYPE_STRING,
-
      &state,
+
                              &state,
                               G_TYPE_INVALID);
                               G_TYPE_INVALID);
g_print ("Network state changed, it is now %s\n",
g_print ("Network state changed, it is now %s\n",
-
      state);
+
state);
g_main_loop_quit (main_loop);
g_main_loop_quit (main_loop);
Line 115: Line 103:
main_loop = g_main_loop_new (NULL,
main_loop = g_main_loop_new (NULL,
-
                              TRUE);
+
                                    TRUE);
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
-
                      NULL);
+
                                    NULL);
proxy = dbus_g_proxy_new_for_name (connection,
proxy = dbus_g_proxy_new_for_name (connection,
-
                          CONNMAN_SERVICE,
+
                                          CONNMAN_SERVICE,
-
                          CONNMAN_MANAGER_PATH,
+
                                          CONNMAN_MANAGER_PATH,
-
                          CONNMAN_MANAGER_INTERFACE);
+
                                          CONNMAN_MANAGER_INTERFACE);
dbus_g_proxy_begin_call (proxy,
dbus_g_proxy_begin_call (proxy,
-
                  "GetState",
+
                                "GetState",
-
                  _method_call_notify_cb,
+
                                _method_call_notify_cb,
-
                  main_loop,
+
                                main_loop,
-
                  NULL,
+
                                NULL,
-
                  G_TYPE_INVALID);
+
                                G_TYPE_INVALID);
g_main_loop_run (main_loop);
g_main_loop_run (main_loop);
}
}
-
</code>
+
</pre>

Revision as of 11:41, 22 June 2010

Contents

Introduction

D-Bus is an Inter Process Communication (IPC) system, providing a mechanism for applications running on a single machine to "talk" to each other. Due to its focus on being a message bus for local applications, D-Bus has some nice features compared to alternative IPC mechanisms: these include the capability to autostart applications which are not active but which have been sent a message; and the ability to ensure that only a single instance of an application is ever running.

Message buses

The core D-Bus protocol is a 2-way, asynchronous, binary protocol. While it is possible to use for direct application to application communication (using libdbus - not recommended), the most common usage of the protocol is via a D-Bus message bus server. The server is connected to each client using D-Bus, and routes each message from the application which sent it its intended recipient. Each application which exposes its capabilities on the bus is known as a service. (An application doesn't have to expose any services to make use of the bus: it can just send messages to other applications which do provide services.)

<img src="http://moblin.org/sites/all/files/message_bus.png" alt="D-Bus message bus" title="D-Bus message bus" />

There are actually multiple D-Bus message buses running on Moblin (and on your average Linux system) at any one time, of two types:

  • The system bus is a machine-global, single instance of the daemon with security restrictions on what messages it will accept. It's used for system-wide communication and communication between the user desktop and the operating system.
  • A session bus is created for each user session. It allows applications within that user session to communicate. Most MeeGo D-Bus services (connman etc.) communicate via the session bus.

Services, trees, interfaces, and objects

Services on a D-Bus expose a tree of objects to interact with. Each service has a root path; from the root come branches, one for each object provided by that service. Each object on a service tree is addressable by an object path.

Object paths are typically in a reverse-domain name format, akin to Java package names; for example, org.moblin.connman for the ConnMan root path.

Interfaces are the contract between an object and its callers, much like interfaces in Java, GObject etc.. An interface, as in most object-oriented programming environments, defines the methods and properties an object exposes. In addition, D-Bus interfaces can also contain signals. Signals provide a way for objects to notify other objects about events which happen to them: for example, a Door interface might provide a signal to other objects when it is opened, perhaps called door-opened. (A nearby Doorman object might listen out for door-opened signals, so it knows when people come into the building.)

Each D-Bus object implements one or more interfaces. Most implement two standard interfaces as a minimum, org.freedesktop.DBus.Introspectable and org.freedesktop.DBus.Properties:

  • The Introspectable interface specifies a single method, Introspect(). Calling this method on an object returns a string of XML which defines the interfaces (and the properties, signals and methods of those interfaces) implemented by that object.
  • The Properties interface specifies three standard methods for getting and setting an object's properties: Get(), GetAll(), and Set().
    • Get() takes the interface name and a property name as arguments and returns the value of the specified property.
    • GetAll() takes the interface name and returns a dictionary of property name to value mappings.
    • Set() takes the interface name, a property name and the value to set for the property as arguments.

Investigating and debugging D-Bus services

Often the easiest way to get started investigating a service on the Bus is to use D-Feet, a graphical D-Bus debugging tool.

<img src="/sites/all/files/u208/d-feet_fullth.png" preset="0" class="nofloat" alt="D-Feet screenshot" />

Using D-Feet, one can browse the tree of objects available for each service.

D-Feet uses the Introspect() method of the Introspection interface to determine what methods, properties and signals an object implements. It even allows execution of the available methods using a Python-like syntax for specifying arguments.

D-Feet is available in the MeeGo package repositories and can be installed with:

sudo yum install d-feet

Interacting with the bus programatically using high-level bindings

High level bindings for D-Bus tend to provide a mechanism for proxying remote objects: so instead of having to deal with message sending directly, objects on the bus can be proxied to local objects in the application. From there, a program can interact with objects on the bus by calling methods on the proxied object.

D-Bus GLib

The D-Bus GLib bindings (yum install dbus-glib-devel) offer a high-level, GObject-like binding for interacting with the D-Bus message bus.

Below is an example of using the bindings to determine the online state of a Moblin system using the D-Bus service provided by the ConnMan connectivity daemon.

/*
 * amionline.c
 * Uses dbus-glib to ask ConnMan whether there is an active internet connection
 * Compile with:
 * gcc -o amionline amionline.c `pkg-config --libs --cflags glib-2.0 gthread-2.0 dbus-glib-1`
 */

#include <glib.h>
#include <dbus/dbus-glib.h>
#include <dbus/dbus.h>

#define CONNMAN_SERVICE           "org.moblin.connman"
#define CONNMAN_MANAGER_PATH      "/"
#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"

static	GMainLoop *main_loop;

static void
_method_call_notify_cb (DBusGProxy *proxy,
			DBusGProxyCall *call,
			gpointer user_data)
{
	GError *error = NULL;
	gchar *state = NULL;

	dbus_g_proxy_end_call (proxy,
                               call,
                               &error,
                               G_TYPE_STRING,
                               &state,
                               G_TYPE_INVALID);

	g_print ("Network state changed, it is now %s\n",
		 state);

	g_main_loop_quit (main_loop);
}

int
main (int    argc,
      char **argv)
{
	DBusGConnection *connection;
	DBusGProxy *proxy;

	main_loop = g_main_loop_new (NULL,
                                     TRUE);

	connection = dbus_g_bus_get (DBUS_BUS_SYSTEM,
                                     NULL);
	proxy = dbus_g_proxy_new_for_name (connection,
                                           CONNMAN_SERVICE,
                                           CONNMAN_MANAGER_PATH,
                                           CONNMAN_MANAGER_INTERFACE);

	dbus_g_proxy_begin_call (proxy,
                                 "GetState",
                                 _method_call_notify_cb,
                                 main_loop,
                                 NULL,
                                 G_TYPE_INVALID);

	g_main_loop_run (main_loop);
}
Personal tools