News: Stay up to date

The Étoilé community is an active group of developers, designers, testers and users. New work is being done every day. Visit often to find out what we've been up to.


GSoC Progress: DBusKit

Posted on 19 July 2010 by Niels Grewe

As David pointed out earlier, both Eric and I got the opportunity to participate in Google's Summer of Code programme with projects for GNUstep. Since GSoC "midterms" are just over, I'd like to talk a bit about the progress I've been making.

D-Bus and Distributed Objects

My project for this summer is to bring D-Bus support to GNUstep. D-Bus is, as you might know, an IPC mechanism that has been widely adopted on the *nix desktop: If you are sitting in front of a Gnome or KDE desktop, you most certainly also have D-Bus installed. GNUstep has traditionally had a different, but very powerful means of doing IPC that is called "Distributed Objects" (DO, which in fact dates back to the OpenStep spec). It allows you to refer to a distant object (running in a different process) just like you would to a local object. You can just get a proxy to the remote object by calling the appropriate method on NSConnection and just send messages to it as usual:

id thermometer = [NSConnection rootProxyForConnectionWithRegisteredName: @"TemperatureServer"
                                                                       host: @""];
temp = [thermometer temperature];

That's just it. You can even use every return value from the root proxy just as you would normally. Actually the system is very intelligent about that: If process A accesses an object from process B and that object returns a remote object it got from A, DO will be smart enough not to do a round trip ABA, but will return the local object instead. Thus, for native IPC needs, GNUstep already has everything one could wish for.

But D-Bus support is still a useful thing for GNUstep because many services on a modern *nix desktop are exposed via D-Bus: If you re-configure your WiFi card on the fly, it's probably through NetworkManager, and if your media player inhibits the power saving functions of your laptop when watching a movie, this is probably done through upower (or HAL). All theses services use D-Bus to provide their functions to other applications.

Using D-Bus from Objective-C

The goal of my project is to make accessing and providing D-Bus services from within an Objective-C application as easy as using Distributed Objects. So you would just do

id thermometer = [NSConnection rootProxyForDBusConnectionWithRegisteredName: @""
                                                                            bus: DKDBusSystemBus];

And while I'm not quite there yet, the DBusKit framework that provides D-Bus support is starting to get useful. It already manages basic method invocations on D-Bus object, albeit that support is at present limited to the object at the root of an object graph. E.g. you can get a list with all names registered on D-Bus with the following lines of code:

NSConnection *conn = [NSConnection connectionWithReceivePort: [DKPort port]
                                                    sendPort: [[DKPort alloc] initWithRemote: @"org.freedesktop.DBus"]];
id dbus = [conn rootProxy];
NSArray *names = [dbus ListNames];

The present implementation is very flexible in the way it interacts with D-Bus. For example, all the following method declarations are valid ways to invoke the D-Bus method NameHasOwner() on the org.freedesktop.DBus object:

- (NSNumber*)NameHasOwner: (NSString*)name;
- (NSNumber*)NameHasOwner: (char*)name;
- (BOOL)NameHasOwner: (NSString*)name;
- (BOOL)NameHasOwner: (char*)name;

So you are free to choose whether you want plain C types or Objective-C objects (though this isn't possible for collection D-Bus values yet: these will always be returned as objects). Of course you have to provide the method signatures for the D-Bus methods you want to call (e.g. in a protocol declaration), but in the future I will provide a little tool that will do that for you.


So what remains to do for the second half of GSoC? Apart from the better integration, I will tackle the task of exposing Objective-C objects on D-Bus. This will involve designing a tool that allows you to generate annotated D-Bus introspection data from Objective-C interface or protocol declarations so that you can easily customise what methods an object will expose via D-Bus. Also D-Bus supports not only method calls, but also signals and properties, both of which can easily be mapped to notifications and properties on the Objective-C side. So stay tuned for updates on D-Bus support in GNUstep.

Further reading

If you want to play around with the code, you can find it in the modules/dev-libs/dbuskit directory of the GNUstep SVN tree this also includes an example that exposes the Apertium machine-translation system (which has a D-Bus interface) as a GNUstep service. This is accessible from every GNUstep application and allows you to translate selected text on the fly. Information about the Distributed Objects system can be found in the GNUstep Base Programming Manual, the Apple documentation or an tutorial by Nicola Pero. If you want to learn more about D-Bus, Dan Williams has an excellent introductory post about it.