Accéder au contenu principal

D-BUS, un bus de messagerie pour UNIX (et Windows)

Introduction

J'ai déjà parlé dans un billet précédent de JMX qui peut être utilisé en Java pour surveiller une application ou faire des appels distants. Je vais parlé ici d'un autre système de communication assez répandu sous UNIX, mais pourtant pas très connu : D-Bus.

D-Bus est un système de communication interprocess qui permet d'échanger des messages entre deux applications sur la même machine. Il est en cela comparable à CORBA (Unix et Windows) ou COM/DCOM (Windows) car il permet de piloter une application à distance et ajoute également un mécanisme de signalisation. L'avantage de D-BUS est sa légèreté car il utilise un simple "démon" pour la communication et il peut être utilisé par différents langages (C, C++, Java, Python). La communication entre les processus s'effectue à l'aide de Sockets Unix ou TCP.

D-Bus est essentiellement utilisé par Gnome pour ses applications graphiques, ainsi que par un certain nombre d'applications multimédia. Il permet par exemple de recevoir une notification lorsqu'un CD est inséré dans le lecteur, lorsque le volume est augmenté ou diminué, lorsqu'une connexion Bluetooth est détectée, etc. Son usage peut également être détourné pour une utilisation embarquée.

Je vais principalement m’intéresser ici à la compilation sous Windows et à son utilisation en Java.

Compilation de D-Bus sous Windows

Les versions compilées de D-Bus sont livrées nativement avec Cygwin qui est un environnement sous Windows permettant de compiler et d'exécuter des applications POSIX (Unix pour simplifier). Dans l'environnement Cygwin, la plupart des librairies et fichiers d'entêtes sont disponibles pour ré-compiler sous Windows des applications initialement livrées pour Linux. Il existe également MINGW qui est un environnement minimaliste pour la compilation d'application Unix sous Windows, mais il manque souvent des librairies et des fichiers d'entêtes nécessaires à la compilation. Dans mon cas, j'ai donc utilisé Cygwin dans sa version 64 bits.

1. Récupérez D-Bus
D-Bus peut être téléchargé à l'adresse suivante : http://dbus.freedesktop.org/releases/dbus/
J'ai récupéré la version 1.7.10 pour mes tests.

2. Décompressez le fichier récupéré
Le fichier dbus-1.7.10.tar.gz doit être décompressé à l'aide de
gunzip dbus-1.7.10.tar.gz

, puis détarré avec la commande
tar xvf dbus-1.7.10.tar

Vous pouvez également utiliser la commande
tar xvfz dbus-1.7.10.tar.gz
qui effectue les deux opérations en même temps.

Si vous souhaitez faire l'opération graphiquement, l'utilitaire 7-Zip permet d'effectuer ces 2 opérations.

3. Lancez la configuration, puis la compilation à l'aide des 3 opérations "classiques"
./configure
make
make install

La compilation prend un certain temps. L'installation finale s'effectue dans les répertoires /usr/local/bin pour les binaires, /usr/local/lib pour les libraries et /usr/local/include pour les fichiers d'entêtes. Sous Windows, ces répertoires sont situés dans le répertoire de Cygwin (ex : "C:\cygwin64").

4. Lancez le démon
Le démon D-Bus est lancé avec la commande
dbus-launch.exe
Cette commande lance le processus "/usr/local/bin/dbus-daemon" en tâche de fond un peu comme un Service Windows. C'est la seule application nécessaire au fonctionnement de D-Bus. Notez bien l'adresse de la session du bus qui est affichée. Cette adresse sera nécessaire pour communiquer avec l'application.
DBUS_SESSION_BUS_ADDRESS=unix:path=/tmp/dbus-fnxsbC2zqt,guid=23719b0a709e4557a7195ee952d92e32

Les autres applications livrées avec D-Bus sont :
- dbus-send : permet d'envoyer des messages ou des signaux vers un process
- dbus-monitor : permet d'écouter tous les évènements échangés sur le bus
- dbus-cleanup-sockets : permet de nettoyer les sockets créés dans le répertoire /tmp.

Utilisation de D-Bus en Java sous Windows


Une librairie développée par Matthew Johnson, pour l'utilisation de D-Bus en Java est disponible sous http://dbus.freedesktop.org/releases/dbus-java/. La dernière version 2.10 date de 2009 mais reste fonctionnelle. La documentation est disponible sous http://dbus.freedesktop.org/doc/dbus-java/dbus-java.pdf. Cette dernière est relativement lourde et pas très simple à utiliser. Il existe un autre tutoriel http://rm5248.com/d-bus-tutorial qui explique de manière très simple l'utilisation de D-Bus en Java et en C++.

Avant de pouvoir utiliser l'API Java, il faut compiler la librairie fournie. C'est là que les choses se gâtent. La librairie dbus-java s'appuie sur une autre librairie de Matthew Johnson permettant l'utilisation des Sockets Unix utilisées dans D-Sub. Cette librairie nécessaire à la compilation, ainsi qu'à l'exécution des applications Java est disponible à l'adresse http://www.matthew.ath.cx/projects/java/libmatthew-java-0.8.tar.gz https://src.fedoraproject.org/repo/pkgs/libmatthew-java/libmatthew-java-0.8.tar.gz/8455b8751083ce25c99c2840609271f5/libmatthew-java-0.8.tar.gz. Cette librairie combine du code en Java et en C pour l'utilisation des sockets et s'appuie donc sur JNI (Java Native Interface).

Pour la compilation sous Unix, décompressez cette librairie et lancez "make".
Sous Cygwin, il vous faut faire les modifications suivantes :
1. export JAVA_HOME=c:/jdk1.7.0_25. Notez bien le "/" à la place du "\". Les fichiers nécessaires à JNI sont disponibles dans le répertoire c:/jdk1.7.0_25/include et c:/jdk1.7.0_25/include/win32.

2. Modifiez le Makefile pour faire référence à win32 à la place de linux. L'option -fpic doit également être supprimée sous Windows. Repérez les variables suivantes et remplacez les.
INCLUDES+=-I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/win32
CFLAGS+=-Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at
CSHAREFLAG+=-fno-stack-protector
LDSHAREFLAGS+= -Wall -D_JNI_IMPLEMENTATION_ -Wl,--kill-at -shared

3. Lancez la compilation de la librarie libmatthew-java
make

Le résultat de cette compilation fournira un 6 libraries java (cgi-0.6.jar, debug-disable-1.1.jar, debug-enable-1.1.jar, hexdump-0.2.jar, io-0.1.jar, unix-0.5.jar) et 2 libraries JNI (libcgi-java.so, libunix-java.so). Les librairies hexdump-0.2.jar et unix-0.5.jar sont nécessaires pour la compilation de dsub-java. La librairie libunix-java.so doit être renommée en unix-java.dll et est nécessaire pour l'exécution des applications Java.

4. Vous pouvez ensuite décompiler la librairie dbusjava, et le recompiler avec compile.bat après avoir mis les bons settings. Vous pouvez alternativement, créer un projet Eclipse incluant tous les sources de manière à créer une librairie unique dbusjava.jar incluant tous les fichiers nécessaires. C'est ce que j'ai fait. Le projet complet est disponible ici.

5. Il y a une difficulté supplémentaire pour l'exécution des fichiers sous Windows. Les librairies JNI utilisées avec Java ne sont pas compatibles avec Cygwin qui charge des dlls particulières. Vous obtiendrez ainsi l'erreur suivante.

$ java -jar lib/dbusjava.jar org.freedesktop.dbus.viewer.DBusViewer
      1 [main] java (7236) C:\jdk1.7.0_25\bin\java.exe: *** fatal error - cygheap base mismatch detected - 0x1802DB410/0xD19B410.
This problem is probably due to using incompatible versions of the cygwin DLL.
Search for cygwin1.dll using the Windows Start->Find/Search facility
and delete all but the most recent version.  The most recent version *should*
reside in x:\cygwin\bin, where 'x' is the drive on which you have
installed the cygwin distribution.  Rebooting is also suggested if you
are unable to find another cygwin DLL.
Exception in thread "DBus Loader" java.lang.UnsatisfiedLinkError: C:\Java_Dev_1\dbusjava\unix-java.dll: L'accès à cet emplacement de la mémoire n'est pas valide
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary1(ClassLoader.java:1957)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1882)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1872)
        at java.lang.Runtime.loadLibrary0(Runtime.java:849)
        at java.lang.System.loadLibrary(System.java:1087)
        at cx.ath.matthew.unix.UnixSocket.<clinit>(UnixSocket.java:40)
        at org.freedesktop.dbus.Transport.connect(Transport.java:772)
        at org.freedesktop.dbus.Transport.<init>(Transport.java:737)
        at org.freedesktop.dbus.DBusConnection.<init>(DBusConnection.java:299)
        at org.freedesktop.dbus.DBusConnection.getConnection(DBusConnection.java:282)
        at org.freedesktop.dbus.viewer.DBusViewer$2.run(DBusViewer.java:139)
        at java.lang.Thread.run(Thread.java:724)

Il faut donc utiliser un launcher Java spécial qui permet de lancer les applications Java utilisant des librairies JNI compilées avec Cygwin dans l'environnement Cygwin. Ce launcher a été construit à partir des sources récupérés sur le site https://code.google.com/p/jessies/source/browse/salma-hayek/trunk/native/all/java-launcher/java-launcher.cpp. J'ai extrait le code source correspondant ainsi que la version compilée ici.  Ce launcher  peut être utilisé pour d'autres projets utilisant des libraries JNI. L'utilisation se fait à peu près comme le compilateur Java classique.
./javalauncher.exe -cp lib/dbusjava.jar org.freedesktop.dbus.viewer.DBusViewer

Voici dans un premier temps les différentes étapes pour la compilation du projet. Je continuerai avec les différentes utilisations.





Commentaires

Posts les plus consultés de ce blog

Utilisez votre tablette Android comme second écran pour Linux (Raspberry Pi, MK908II)

Les tablettes Android atteignent désormais des prix qui défient toute concurrence. On trouve désormais des modèles à 39 € TTC en super marché, soit à peine plus cher que le Raspberry PI, mais avec un écran. Ces modèles souvent mono-core 1Ghz ou 1,4 Ghz avec 512 ou 1Go de mémoire ne sont très probablement pas utilisables pour une utilisation régulière sur Internet et ne sont en aucun point comparables à leur équivalent de marque (Samsung, Sony, LG, HTC, Lenovo, etc). Plusieurs tutoriels indiquent comment connecter utiliser une tablette Android comme second écran ( http://www.linux-magazine.com/Online/Blogs/Productivity-Sauce/Use-an-Android-Device-as-Screen-and-Input-for-Raspberry-Pi ). Ces méthodes utilisent généralement l'USB Tethering qui n'est malheureusement disponible que sur les téléphones ou tablettes avec un accès mobile (3G ou 4G) inclus. Dans ce billet, je vais vous montrer comment se connecter à une tablette en utilisant le mode Debug adb (Android Debug Bridge...

Ardublock ou S4A pour développer graphiquement

Si vous n'aimez pas le développement en C, ou C# sur les micro-contrôleurs, vous pouvez vous essayer au développement graphique avec Ardublock. Historique Cet environnement de développement est issu d' OpenBlocks développé par le MIT qui se positionne lui même dans la suite du langage Logo de Seymour Papert . Le langage Logo est un langage issu de l'Intelligence Artificielle dans les années 1970 dont l'objectif était de faciliter l'apprentissage de la programmation à de jeunes enfants par le biais du pilotage d'une tortue munie d'un crayon. Les ordres étaient relativement simples : avance de 90 cm, tourne à droite de 90°, etc. Ceci, permettait de réaliser des dessins assez simple, de piloter un petit robot et d'apprendre la programmation. C'était cependant un langage textuel. Exemple pour tracer un carré : POUR CARRE REPETE 4 [AV 100 TD 90] FIN   Son digne successeur, le langage Scratch désormais intégré à l'image Raspbian du Raspberry Pi...

Hack du RoboSapien en Infra-Rouge

Mon fils a eu un RoboSapien V1 il y a une dizaine d'années. Il prenait la poussière sur le haut d'une armoire, jusqu'à ce que j'ai envie de le ramener à la vie. Il était temps, les piles étaient en train de commencer à couler et vu le nombre de servo moteurs qu'il contient, ses jours étaient comptés. Mais non, j'ai réussi à contenir mon irrésistible envie de tout démonter et j'ai décidé de passer par la télécommande Infrarouge pour le piloter. Le protocole est assez similaire de celui d'une télécommande infrarouge classique avec cependant quelques petites différences. Il est correctement expliqué sur les sites http://www.aibohack.com/robosap/ir_codes.htm et http://www.markcra.com/robot/ir_codes.php . Je vais traduire en français pour ceux qui auraient un peu de difficulté. Il existe des librairies Arduino, mais comme d'habitude, pas toujours de librairie en C#. Voici les choses importantes à connaitre sur le protocole : Le protocole envoie...