Message and message bus
Application a is connected to the message bus, which obtains a well-known common name (recorded as connection a). In application a, object A1 provides interface I1, and interface I1 has method M1. When application B is connected to the message bus, it is required to call method M1 of interface I1 of object A1 on connection a.
In the addition example mentioned above, the above paragraph can be instantiated as: application example service and session bus connection. This connection gets a well-known public name "org.fmddlmyy.Test". The object "/ TestObj" in the application example service provides the interface "org.fmddlmyy.Test.Basic", and the interface "org.fmddlmyy.Test.Basic" has the method "Add". The application d-feet are connected to the session bus. It is required to call the method "Add" of the interface "org.fmddlmyy.Test.Basic" connecting the object "/ TestObj" on "org.fmddlmyy.Test".
Application B invokes the method of application A. in fact, application B sends a message of "method_call" to application a. Application a sends the return value to application B through a message of type "method_retn". Let's briefly introduce the messages on the D-Bus.
1. D-Bus message
As mentioned above, the most basic D-Bus protocol is one-to-one communication protocol. Different from using socket directly, D-Bus is a message oriented protocol. All functions of D-Bus are accomplished through messages flowing on the connection.
1.1 message type
D-Bus has four types of messages:
- method_call method call
- method_return method returns
- Error error
- Signal signal
The remote method call described earlier uses method_call and method_return message. As the name suggests, an error message is generated when an error occurs. If you put method_call is regarded as a call, and the signal message is an incoming call. It will be discussed in detail later.
1.2. DBUS send and DBUS monitor
dbus provides two Gadgets: dbus send and dbus monitor. We can send messages using dbus send. Use dbus monitor to monitor the messages flowing on the bus. Let's call the previous Add method by sending a message through dbus send, where dbus send acts as application B. Observe the messages in the calling process with dbus monitor.
For the detailed usage of DBUS send, please refer to the manual. The general form of calling remote methods is:
$ dbus-send [--system | --session] --type=method_call --print-reply --dest=Connection name object path interface name.Method name parameter type:Parameter value parameter type:Parameter value
The parameter types supported by DBUS send include: string, int32, uint32, double, byte and Boolean.
2. Method and signal of message bus
2.1 overview
Message bus is a special application, which can transfer messages between applications connected to it. Think of the message bus as a router. It is through the message bus that D-Bus realizes many to one and one to many communication on the basis of one-to-one communication protocol.
Although message bus has special forwarding function, it is also an application. The communication between other applications and the message bus is also completed through the basic message types in Section 1.1. As an application, the message bus also provides its own interface, including methods and signals.
We can call the methods provided by the message bus by sending a message to the object "/" on the connection "org.freedesktop.DBus". In fact, applications connect to other applications on the message bus through these methods to complete the work of requesting common names.
2.2 list
To use DBUS send on FCP and AC boards, you need to execute export $(DBUS launch) first
root@xxxx-obmc:~# dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames Failed to open connection to "session" message bus: Using X11 for dbus-daemon autolaunch was disabled at compile time, set your DBUS_SESSION_BUS_ADDRESS instead root@xxxx-obmc:~# export $(dbus-launch) root@xxxx-obmc:~# root@xxxx-obmc:~# dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames method return time=61305.454012 sender=org.freedesktop.DBus -> destination=:1.0 serial=3 reply_serial=2 array [ string "org.freedesktop.DBus" string ":1.0" ] root@xxxx-obmc:~#
The message bus object supports the standard interface "org.freedesktop.DBus.Introspectable" mentioned in the first lecture. We can call org. Com freedesktop. DBus. Introspectable. The introspect method looks at the interfaces supported by the message bus object. For example:
$ dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect
root@xxxx-obmc:~# dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.Introspectable.Introspect method return time=109.212525 sender=org.freedesktop.DBus -> destination=:1.1 serial=3 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"> <method name="Hello"> <arg direction="out" type="s"/> </method> <method name="RequestName"> <arg direction="in" type="s"/> <arg direction="in" type="u"/> <arg direction="out" type="u"/> </method> <method name="ReleaseName"> <arg direction="in" type="s"/> <arg direction="out" type="u"/> </method> <method name="StartServiceByName"> <arg direction="in" type="s"/> <arg direction="in" type="u"/> <arg direction="out" type="u"/> </method> <method name="UpdateActivationEnvironment"> <arg direction="in" type="a{ss}"/> </method> <method name="NameHasOwner"> <arg direction="in" type="s"/> <arg direction="out" type="b"/> </method> <method name="ListNames"> <arg direction="out" type="as"/> </method> <method name="ListActivatableNames"> <arg direction="out" type="as"/> </method> <method name="AddMatch"> <arg direction="in" type="s"/> </method> <method name="RemoveMatch"> <arg direction="in" type="s"/> </method> <method name="GetNameOwner"> <arg direction="in" type="s"/> <arg direction="out" type="s"/> </method> <method name="ListQueuedOwners"> <arg direction="in" type="s"/> <arg direction="out" type="as"/> </method> <method name="GetConnectionUnixUser"> <arg direction="in" type="s"/> <arg direction="out" type="u"/> </method> <method name="GetConnectionUnixProcessID"> <arg direction="in" type="s"/> <arg direction="out" type="u"/> </method> <method name="GetAdtAuditSessionData"> <arg direction="in" type="s"/> <arg direction="out" type="ay"/> </method> <method name="GetConnectionSELinuxSecurityContext"> <arg direction="in" type="s"/> <arg direction="out" type="ay"/> </method> <method name="ReloadConfig"> </method> <method name="GetId"> <arg direction="out" type="s"/> </method> <method name="GetConnectionCredentials"> <arg direction="in" type="s"/> <arg direction="out" type="a{sv}"/> </method> <property name="Features" type="as" access="read"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> <property name="Interfaces" type="as" access="read"> <annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="const"/> </property> <signal name="NameOwnerChanged"> <arg type="s"/> <arg type="s"/> <arg type="s"/> </signal> <signal name="NameLost"> <arg type="s"/> </signal> <signal name="NameAcquired"> <arg type="s"/> </signal> </interface> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg direction="out" type="s"/> </method> </interface> <interface name="org.freedesktop.DBus.Peer"> <method name="GetMachineId"> <arg direction="out" type="s"/> </method> <method name="Ping"> </method> </interface> <node name="org/freedesktop/DBus"/> </node> "
From the output, we can see that the session bus object supports the standard interface "org.freedesktop.DBus.Introspectable" and the interface "org.freedesktop.DBus". The interface "org.freedesktop.DBus" has 16 methods and 3 signals. The following table lists a brief description of the 12 methods of "org.freedesktop.DBus"
mathod | explain |
---|---|
org.freedesktop.DBus.RequestName (in STRING name, in UINT32 flags, out UINT32 reply) | Request public name. The definition of flag is as follows: DBUS_ NAME_ FLAG_ ALLOW_ REPLACEMENT 1 DBUS_ NAME_ FLAG_ REPLACE_ EXISTING 2 DBUS_ NAME_ FLAG_ DO_ NOT_ The return value reply of queue 4 is defined as follows: DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 DBUS_REQUEST_NAME_REPLY_EXISTS 3 DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 |
org.freedesktop.DBus.ReleaseName (in STRING name, out UINT32 reply) | Release the public name. The return value reply is defined as follows: DBUS_RELEASE_NAME_REPLY_RELEASED 1 DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 |
org.freedesktop.DBus.Hello (out STRING unique_name) | An application must call hello to get the unique name of its connection before sending messages to other applications through the message bus. The return value is the unique name of the connection. dbus does not define a special command to cut off the connection. Closing the socket is to cut off the connection. In the dbus monitor output in section 1.2, you can see that dbus send calls the Hello method of the message bus. |
org.freedesktop.DBus.ListNames (out ARRAY of STRING bus_names) | Returns all connection names connected on the message bus, including all public and unique names. For example, the connection "org.fmddlmyy.Test" has both the public name "org.fmddlmyy.Test" and the unique name ": 1.21", both of which will be returned. |
org.freedesktop.DBus.ListActivatableNames (out ARRAY of STRING bus_names) | Returns the names of all services that can be started. dbus supports on-demand service startup, that is, start the service according to the request of the application. |
org.freedesktop.DBus.NameHasOwner (in STRING name, out BOOLEAN has_owner) | Checks whether any connection has the specified name. |
org.freedesktop.DBus.StartServiceByName (in STRING name, in UINT32 flags, out UINT32 ret_val) | Start the service by name. The parameter flags is not used yet. Return value ret_val is defined as follows: 1. The service has been started successfully. 2. There is already a connection with the service name to be started |
org.freedesktop.DBus.GetNameOwner (in STRING name, out STRING unique_connection_name) | Returns the unique name of the connection with the specified public name. |
org.freedesktop.DBus.GetConnectionUnixUser (in STRING connection_name, out UINT32 unix_user_id) | Returns the Unix user id of the server process corresponding to the specified connection. |
org.freedesktop.DBus.AddMatch (in STRING rule) | Add a matching rule for the current connection. |
org.freedesktop.DBus.RemoveMatch (in STRING rule) | Removes the specified matching rule for the current connection. |
org.freedesktop.DBus.GetId (out STRING id) | Returns the ID of the message bus. This ID is unique for the lifetime of the message bus. |
The three signals of the interface "org.freedesktop.DBus" are:
signal | explain |
---|---|
org.freedesktop.DBus.NameOwnerChanged (STRING name, STRING old_owner, STRING new_owner) | The owner of the specified name has changed. |
org.freedesktop.DBus.NameLost (STRING name) | The notification app lost ownership of the specified name. |
org.freedesktop.DBus.NameAcquired (STRING name) | The notification application has obtained ownership of the specified name. |
Differences between session and system parameters:
dbus-send --session --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames method return time=875.939015 sender=org.freedesktop.DBus -> destination=:1.2 serial=3 reply_serial=2 array [ string "org.freedesktop.DBus" string ":1.2" ] root@obmc:~# root@obmc:~# root@obmc:~# root@obmc:~# dbus-send --system --type=method_call --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListNames method return time=908.657105 sender=org.freedesktop.DBus -> destination=:1.143 serial=4294967295 reply_serial=2 array [ string "org.freedesktop.DBus" ...... ]
In XYZ openbmc_ project. Control. Host. Take NMI as an example to view its root object.
root@obmc:~# dbus-send --system --type=method_call --print-reply --dest=xyz.openbmc_project.Control.Host.NMI / org.freedesktop.DBus.Introspectable.Introspect method return time=1482.867385 sender=:1.50 -> destination=:1.144 serial=150 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.Peer"> <method name="Ping"/> <method name="GetMachineId"> <arg type="s" name="machine_uuid" direction="out"/> </method> </interface> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg name="data" type="s" direction="out"/> </method> </interface> <interface name="org.freedesktop.DBus.Properties"> <method name="Get"> <arg name="interface" direction="in" type="s"/> <arg name="property" direction="in" type="s"/> <arg name="value" direction="out" type="v"/> </method> <method name="GetAll"> <arg name="interface" direction="in" type="s"/> <arg name="properties" direction="out" type="a{sv}"/> </method> <method name="Set"> <arg name="interface" direction="in" type="s"/> <arg name="property" direction="in" type="s"/> <arg name="value" direction="in" type="v"/> </method> <signal name="PropertiesChanged"> <arg type="s" name="interface"/> <arg type="a{sv}" name="changed_properties"/> <arg type="as" name="invalidated_properties"/> </signal> </interface> <interface name="org.freedesktop.DBus.ObjectManager"> <method name="GetManagedObjects"> <arg type="a{oa{sa{sv}}}" name="object_paths_interfaces_and_properties" direction="out"/> </method> <signal name="InterfacesAdded"> <arg type="o" name="object_path"/> <arg type="a{sa{sv}}" name="interfaces_and_properties"/> </signal> <signal name="InterfacesRemoved"> <arg type="o" name="object_path"/> <arg type="as" name="interfaces"/> </signal> </interface> <node name="xyz"/> </node> "
As above, there is a child node under the root directory. The search information is as follows. The interface information obtained is consistent with the information obtained under the root directory.
root@obmc:~# dbus-send --system --type=method_call --print-reply --dest=xyz.openbmc_project.Control.Host.NMI /xyz org.freedesktop.DBus.Introspectable.Introspect method return time=1762.447872 sender=:1.50 -> destination=:1.145 serial=151 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.Peer"> <method name="Ping"/> <method name="GetMachineId"> <arg type="s" name="machine_uuid" direction="out"/> </method> </interface> <interface name="org.freedesktop.DBus.Introspectable"> <method name="Introspect"> <arg name="data" type="s" direction="out"/> </method> </interface> <interface name="org.freedesktop.DBus.Properties"> <method name="Get"> <arg name="interface" direction="in" type="s"/> <arg name="property" direction="in" type="s"/> <arg name="value" direction="out" type="v"/> </method> <method name="GetAll"> <arg name="interface" direction="in" type="s"/> <arg name="properties" direction="out" type="a{sv}"/> </method> <method name="Set"> <arg name="interface" direction="in" type="s"/> <arg name="property" direction="in" type="s"/> <arg name="value" direction="in" type="v"/> </method> <signal name="PropertiesChanged"> <arg type="s" name="interface"/> <arg type="a{sv}" name="changed_properties"/> <arg type="as" name="invalidated_properties"/> </signal> </interface> <node name="openbmc_project"/> </node> "
2.3.2 automatic startup of ListActivatableNames and server
The results obtained by using session and system here are inconsistent.
root@obmc:~# dbus-send --system --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListActivatableNames method return time=1939.107887 sender=org.freedesktop.DBus -> destination=:1.146 serial=4294967295 reply_serial=2 array [ string "org.freedesktop.DBus" string "org.freedesktop.Avahi" string "org.freedesktop.hostname1" string "org.freedesktop.login1" string "org.freedesktop.network1" string "org.freedesktop.resolve1" string "org.freedesktop.systemd1" string "org.freedesktop.timedate1" string "org.freedesktop.timesync1" string "xyz.openbmc_project.EntityManager" ] root@obmc:~# dbus-send --session --print-reply --dest=org.freedesktop.DBus / org.freedesktop.DBus.ListActivatableNames method return time=1960.060127 sender=org.freedesktop.DBus -> destination=:1.3 serial=3 reply_serial=2 array [ string "org.freedesktop.DBus" string "org.freedesktop.systemd1" ]
Execution:
root@obmc:~# cat /usr/share/dbus-1/services/*|grep Name|awk -F= '{print $2}'|sort org.freedesktop.systemd1
It sends all files under "/ usr/share/dbus-1/services /" to grep to filter out the rows containing "Name". The rows containing "Name" are sent to awk for processing. Awk uses "=" as the column separator, takes out the second column, and then sends it to sort for output. The "/ usr/share/dbus-1/services /" directory is where DBUS puts the service file. The server that needs to be started automatically will put a service file in this directory, for example:
root@obmc:~# cat /usr/share/dbus-1/services/org.freedesktop.systemd1.service # SPDX-License-Identifier: LGPL-2.1+ # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [D-BUS Service] Name=org.freedesktop.systemd1 Exec=/bin/false User=root
Name is the public name of the server, and Exec is the execution path of the server. When a customer requests a service, but the service has not been started. dbus will automatically start the service according to the service file.
Literature
Some contents in doc / subdirectory are pre built and can be browsed here. If you are new to D-Bus, this tutorial is probably the best Getting Started Guide (even if it is very incomplete, it covers the Basics).
General D-Bus protocol information:
- D-Bus specification
- In txdbus document D bus overview
- Jeroen VermeulenIntroduction to basic knowledge of
- In Qt document Introduction to D-Bus
- Often ask questions
- Overview picture PNG SVG
- D-Bus tutorial (incomplete, including some binding and re Implementation)
- Profile DTD
- If you are interested in some Confused by the concept, please see Some analogies
- Some for D-Bus tool . Note that the D-Bus specification is incomplete, especially in its description of the message bus daemon. The specification of the agreement itself is quite complete, although it is not always clear or precise. Welcome to your patch! At the same time, you may need to read the reference implementation source code to supplement your reading of the specification.
Documentation specific to the reference implementation dbus:
- API reference manual for reference implementation (libdbus)
- Refer to the implementation manual And advanced In TODO@todo project
- Browse reference implementation source
- dbus-daemon(1) (including configuration files docs)
- dbus send (1) dbus monitoring (1) dbus startup (1) dbus-uuidgen(1)
- HACKING author
- Journalism ChangeLog readme file
- test plan
- Tarball Contains most of the above documents. Keep in mind that libdbus is a low-level library designed to serve as a back-end to language bindings and has the additional complexity required to implement DBUS daemon. If you use a higher-level wrapper or re implement it, you will save a lot of trouble. These documents are usually from Binding page Link.
Articles on the Internet, including some tutorials:
- Ross Burton's "Connecting desktop applications using D-BUS" (IBM developerWorks) (July 2004)
- John Palmieri's "Get on D-BUS" (January 2005)
- Robert Love ) of "Get on the D-BUS" (Linux Journal) (January 2005)
- "DBus" by Rapha à L slinkx Missing tutorial-DBus"Activate" (2005)
- Matthew Johnson's D-Bus low level API tutorial (November 2005)
- Aaron Seigo and KDE communities Introduction to D-BUS(2007)
- Rony G. Flatscher"Introduction to D-Bus language binding of ooRexx" (December 2011, D-Bus concept introduction and ooRexx binding introduction)