The ability of a program to examine the properties of an exported D-Bus object at runtime is called introspection. With the component gb.dbus, Gambas has the ability to analyze and map in a suitable form a service, its objects, interfaces and their methods and properties as well as declared signals on the D-Bus.
If you want to use Inter-Process-Communication (IPC) via the D-Bus in your Gambas programs, then it is good to know:
For example, the standard interface org.freedesktop.DBus.Introspectable has the Introspect() method, which you can use to import an existing interface description into an XML document. For the d-bus-enabled network manager, for example, call these two commands:
$ dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager org.freedesktop.DBus.Introspectable.Introspect > nwm.xml
$ xed $HOME/nwm.xml
This is the shortened content of the D-Bus interface description of the network manager:
method return sender=:1.5 -> dest=:1.71 reply_serial=2 string "<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN" "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"> <node> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg name="data" direction="out" type="s"/> </method> </interface> <interface name="org.freedesktop.DBus.Properties"> <method name="Get"> <arg name="interface" direction="in" type="s"/> <arg name="propname" direction="in" type="s"/> <arg name="value" direction="out" type="v"/> </method> ... <method name="GetAll"> <arg name="interface" direction="in" type="s"/> <arg name="props" direction="out" type="a{sv}"/> ' type steht für Datentyp </method> </interface> ... <node name="DHCP4Config"/> <node name="IP6Config"/> <node name="Settings"/> </node>
In the next four sections, further applications for the console programs dbus-send, qdbus and dbus-monitor will be presented:
$ qdbus --help Usage: qdbus [--system | --address ADDRESS] [--literal] [servicename] [path] [method] [args]
(1) Output of the list of all D-Bus names of applications (services) on the system bus:
$ qdbus --system | grep -v ':' ... org.freedesktop.ConsoleKit ... org.freedesktop.NetworkManager org.freedesktop.PolicyKit1 org.freedesktop.DBus
Alternatively, you can also work with the dbus-send program:
SYNTAX: $ dbus-send --session --print-reply –dest=DienstName /Objekt-Pfad Schnittstelle
$ dbus-send --session --print-reply --dest=org.freedesktop.DBus /org/freedesktop/DBus \ org.freedesktop.DBus.ListActivatableNames
(2) This will display a list of all interfaces for a selected service from (1):
$ qdbus --system org.freedesktop.NetworkManager ... /org/freedesktop/NetworkManager /org/freedesktop/NetworkManager/ActiveConnection ... /org/freedesktop/NetworkManager/IP6Config/0 /org/freedesktop/NetworkManager/Settings/0
(3) Here is the list of all methods, properties and signals for a selected interface (2):
$ qdbus --system org.freedesktop.NetworkManager /org/freedesktop/NetworkManager method QString org.freedesktop.DBus.Introspectable.Introspect() method QDBusVariant org.freedesktop.DBus.Properties.Get(QString interface, QString propname) ... property read bool org.freedesktop.NetworkManager.NetworkingEnabled property read QString org.freedesktop.NetworkManager.Version … signal void org.freedesktop.NetworkManager.DeviceAdded(QDBusObjectPath) signal void org.freedesktop.NetworkManager.DeviceRemoved(QDBusObjectPath) … method uint org.freedesktop.NetworkManager.state()
Alternatively, you can also work with the dbus-send program here:
$ dbus-send --system --print-reply --dest=org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.DBus.Introspectable.Introspect
(4) For example, selected network properties can be read out for the network manager. However, this requires that you already know exactly the names of the properties determined in point (3):
$ qdbus --system org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.Version 0.9.8.8
$ qdbus --system org.freedesktop.NetworkManager /org/freedesktop/NetworkManager org.freedesktop.NetworkManager.NetworkingEnabled true
Much more convenient than in the console, you can work out the information on the applications registered on the D-Bus either with the DBusExplorer gambas program from Benoît Minisini and Fabien Bodard or the d-feet console program.
How to work successfully with the Gambas program DBusExplorer:
The project by Fabien Bodard and Benoît Minisini was adapted by the author in such a way that interfaces (interfaces) are now also color-coded in the GUI:
Figure 24.9.0.2.1: DBusExplorer
The extended project DBus-Explorer can be found in the download area.
A program with similar functionality is d-feet, which also goes on interface track search for the D-Bus. The program is the author's favorite. The special feature of this program is the possibility that after a double click on a property (Figure 24.9.0.2.2) its current value is displayed behind the property. With the methods, however, a dialog opens in which you can enter suitable arguments for the parameters with which you can then call the selected method. But you should only do this if you know exactly what the method does!
Figure 24.9.0.2.2: Program d-feet
The author primarily uses the two programs d-feet and dbus-monitor for an introspection. The following is recommended for the d-feet program:
With the correct addresses and an interface description for a specific d-bus-capable application, you can, for example, read its properties or remotely control the application via method calls. With the following command (method Stop; without argument) you shut down your computer via the D-Bus (!), for example:
$ dbus-send --system --print-reply --dest=org.freedesktop.ConsoleKit /org/freedesktop/ConsoleKit/Manager \ org.freedesktop.ConsoleKit.Manager.Stop
This tells you the host name for the system:
$ qdbus --system org.freedesktop.NetworkManager \ /org/freedesktop/NetworkManager/Settings \ org.freedesktop.NetworkManager.Settings.Hostname linux
An overview of all programs registered on the D-Bus is also generated by the DBusView gambas program, which is presented in Chapter 24.9.2.1:
Figure 24.9.0.2.3: Registered applications on the Session D-Bus and on the System D-Bus
After startup, the dbus-monitor diagnostic program outputs all messages sent by the applications registered on the bus. However, there are so many of them that you should use suitable filters for the output, for example, if you are only interested in the message type:
$ dbus-monitor
Example with a simple filter:
$ dbus-monitor | grep 'type' string "eavesdrop=true,type='method_call'" string "eavesdrop=true,type='method_return'" string "eavesdrop=true,type='error'" ...
It becomes really interesting when you look at the signals sent by the application org.gtk.vfs.UDisks2VolumeMonitor with the object path /org/gtk/Private/RemoteVolumeMonitor when a USB stick is inserted. You receive this information, for example, for the signal with the signal name “VolumeAdded” (the signal name is also called a member), from which you can also read the signatures of the arguments of the signal:
$ dbus-monitor … signal time=1523464912.402058 sender=:1.28 -> destination=(null destination) serial=60 path=/org/gtk/Private/RemoteVolumeMonitor; interface=org.gtk.Private.RemoteVolumeMonitor; member=VolumeAdded string "org.gtk.vfs.UDisks2VolumeMonitor" string "0xe01330" struct { string "0xe01330" string "2_GB_P" string ". GThemedIcon drive-removable-media-usb drive-removable-media drive-removable drive" string ". GThemedIcon drive-removable-media-usb-symbolic … drive-removable drive" string "" string "" boolean true boolean true string "0xe23480" string "" array [ dict entry( string "class" string "device" ) dict entry( string "unix-device" string "/dev/sdd1" ) dict entry( string "label" string "2_GB_P" ) dict entry( string "uuid" string "38ea6e0b-a161-401d-a673-11c06cf1229e" ) ] string "gvfs.time_detected_usec.1523464912399238" array [ ] }
Basic information on the subject of D-Bus signatures can be found in the following chapter.
If you need the results of a D-Bus inspection in a Gambas program, you need the D-Bus name of the application to be inspected and the D-Bus object path. With this source code (FIntrospection.class) the Intospection on the Session-D-Bus succeeds:
' Gambas class file Public Sub Form_Open() FIntrospection.X = 150 ' possibly adapt FIntrospection.Y = 200 FIntrospection.Caption = "Introspection D-Bus-Server - Object '/MSService'" txaIntrospection.ReadOnly = True End Public Sub Form_Show() Dim sDBusApplicationName, sDBusObjectPath, sXMLText As String sDBusApplicationName = "session://" & "org.gambas.dbusserver2" sDBusObjectPath = "/MSService" Try sXMLText = DBus[sDBusApplicationName]._Introspect(sDBusObjectPath) txaIntrospection.Insert(RTrim(sXMLText)) txaIntrospection.Pos = txaIntrospection.Length End Public Sub Form_KeyPress() If Key.Code = Key.ESC And FIntrospection.Closed = False Then FIntrospection.Delete() Endif End
In the main program you could display the window with the result of the D-Bus inspection:
Public Sub btnIntrospection_Click() FIntrospection.Show() End
Figure 24.9.0.2.4: Introspection result