dbus-send
一个shell指令,用来向dbus总线上的service发送消息,详细的用法可以使用man dbus-send
查询.
Usage
dbus-send [--system | --session | --address=ADDRESS ]
[--address=ADDRESS]
[--dest=NAME]
[--print-reply [=literal]]
[--reply-timeout=MSEC]
[--type=TYPE]
OBJECT_PATH INTERFACE.MEMBER [CONTENTS...]
--system | system类型 |
--session | session类型 |
--address | 发送到指定地址 |
--print-reply | 打印回应的消息.也可以写--print-reply=literal,,literal会把所有的标点和转义符号去掉 |
--reply-timeout | 响应超时,ms计算 |
--type | 消息类型 signal、method_call |
--dest | object 的 well-known Name |
OBJECT_PATH | #obj路径 |
INTERFACE.MEMBER | #要调用的接口.方法 |
[CONTENTS...] | 有些方法会有输入参数 |
下面尝试使用下dbus-send,但是好像一个method都不知道。问题来了,obj path、dest参数啥的怎么查询呢?小伙子不要慌,dbus是提供了一些标准接口的,标准接口可以在DBus-Spec中找到。我们可以使用dbus提供的标准接口进行迭代查询,查询到每个方法的输入输出参数、每个的服务名、obj路径等等。
标准接口是有这么个方法的
org.freedesktop.DBus.Introspectable.Introspect(out string xml_data)
Spec中提到,它可以返回一个对象的xml描述,描述了obj path、property、接口的方法、信号等等。
问题又出现了,这个方法咋调用呢?DBus-Spec有这么一段:
The bus itself owns a special name, org.freedesktop.DBus
, with an object located at /org/freedesktop/DBus
that implements the org.freedesktop.DBus
interface. This service allows applications to make administrative requests of the bus itself. For example, applications can ask the bus to assign a name to a connection.
大概意思就是他给自己起了这么个名,好让别人称呼它。那么调用方法可以如下:
dbus-send --system --print-reply --type=method_call --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.Introspectable.Introspect
/org/freedesktop/DBus
其实写成根路径/
也是可以的,有啥区别我没找到。PC端可以使用d-feet工具查看。下面是响应的xml字符串
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.Properties">
<method name="Get">
<arg direction="in" type="s"/>
<arg direction="in" type="s"/>
<arg direction="out" type="v"/>
</method>
<method name="GetAll">
<arg direction="in" type="s"/>
<arg direction="out" type="a{sv}"/>
</method>
<method name="Set">
<arg direction="in" type="s"/>
<arg direction="in" type="s"/>
<arg direction="in" type="v"/>
</method>
<signal name="PropertiesChanged">
<arg type="s" name="interface_name"/>
<arg type="a{sv}" name="changed_properties"/>
<arg type="as" name="invalidated_properties"/>
</signal>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg direction="out" type="s"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Monitoring">
<method name="BecomeMonitor">
<arg direction="in" type="as"/>
<arg direction="in" type="u"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Debug.Stats">
<method name="GetStats">
<arg direction="out" type="a{sv}"/>
</method>
<method name="GetConnectionStats">
<arg direction="in" type="s"/>
<arg direction="out" type="a{sv}"/>
</method>
<method name="GetAllMatchRules">
<arg direction="out" type="a{sas}"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Peer">
<method name="GetMachineId">
<arg direction="out" type="s"/>
</method>
<method name="Ping">
</method>
</interface>
</node>
"
其他的方法咋用,可以参考这篇文章。比如ListNames
可以打印所有挂在消息总线上的链接名,
dbus-send --system --print-reply --type=method_call --dest=org.freedesktop.DBus /org/freedesktop/DBus org.freedesktop.DBus.ListNames
method return time=1596561197.569149 sender=org.freedesktop.DBus -> destination=:1.1428 serial=3 reply_serial=2
array [
string "org.freedesktop.DBus"
string ":1.1428"
string ":1.700"
string ":1.106"
string "org.freedesktop.timesync1"
string ":1.701"
string ":1.8"
string "com.deepin.daemon.Fprintd"
string "org.freedesktop.systemd1"
string "org.freedesktop.ModemManager1"
string "org.freedesktop.NetworkManager"
string ":1.829"
string "com.deepin.daemon.Authority"
string "org.freedesktop.Accounts"
string "com.deepin.daemon.Gesture"
string "com.deepin.daemon.Timedated"
string "com.deepin.daemon.AirplaneMode"
string ":1.1291"
string ":1.61"
string "com.deepin.daemon.ImageEffect"
string "com.deepin.anything"
string ":1.1371"
string ":1.63"
string ":1.1296"
string "org.freedesktop.PolicyKit1"
string ":1.1297"
string ":1.65"
string ":1.21"
string "org.bluez"
string ":1.66"
string ":1.67"
string ":1.1355"
string ":1.1113"
string ":1.68"
string ":1.1356"
string ":1.298"
string ":1.69"
string ":1.49"
string ":1.1139"
string ":1.873"
string ":1.28"
string "fi.epitest.hostap.WPASupplicant"
string ":1.29"
string ":1.853"
string ":1.677"
string "com.deepin.system.Network"
string "com.deepin.daemon.Accounts"
string ":1.736"
string ":1.858"
string ":1.916"
string "org.freedesktop.UDisks2"
string "com.deepin.daemon.Apps"
string "fi.w1.wpa_supplicant1"
string "org.freedesktop.GeoClue2"
string ":1.70"
string "org.freedesktop.login1"
string "com.deepin.filemanager.daemon"
string "com.deepin.sync.Helper"
string ":1.1282"
string ":1.50"
string ":1.73"
string "org.freedesktop.DisplayManager"
string ":1.75"
string ":1.76"
string ":1.10"
string "com.deepin.system.Power"
string ":1.33"
string ":1.1420"
string "org.freedesktop.UPower"
string ":1.78"
string ":1.34"
string ":1.12"
string "com.deepin.daemon.SwapSchedHelper"
string ":1.1124"
string ":1.242"
string ":1.79"
string ":1.35"
string ":1.13"
string ":1.243"
string ":1.1"
string ":1.2"
string ":1.15"
string ":1.245"
string "com.deepin.lastore"
string ":1.4"
string ":1.104"
string ":1.5"
string "com.deepin.daemon.Daemon"
string ":1.18"
string ":1.6"
]
那么其他的object都有什么方法,路径在哪?咋查呢?
可以借用标准接口org.freedesktop.DBus.ObjectManager.GetManagedObjects
,查询根路径/
下org.bluez
服务里面的obj、intf、method等。
dbus-send --system --print-reply --type=method_call --dest=org.bluez / org.freedesktop.DBus.ObjectManager.GetManagedObjects
路径为啥写/
呢?你品,你细品
An API can optionally make use of this interface for one or more sub-trees of objects. The root of each sub-tree implements this interface so other applications can get all objects, interfaces and properties in a single method call. It is appropriate to use this interface if users of the tree of objects are expected to be interested in all interfaces of all objects in the tree; a more granular API should be used if users of the objects are expected to be interested in a small subset of the objects, a small subset of their interfaces, or both.
The method that applications can use to get all objects and properties is GetManagedObjects:
org.freedesktop.DBus.ObjectManager.GetManagedObjects (out DICT<OBJPATH,
DICT<STRING,
DICT<STRING,VARIANT>>>
objpath_interfaces_and_properties);
The return value of this method is a dict whose keys are object paths. All returned object paths are children of the object path implementing this interface, i.e. their object paths start with the ObjectManager's object path plus '/'.
method return time=1596561309.403861 sender=:1.21 -> destination=:1.1432 serial=9197 reply_serial=2
array [
dict entry(
object path "/org/bluez"
array [
dict entry(
string "org.freedesktop.DBus.Introspectable"
array [
]
)
dict entry(
string "org.bluez.AgentManager1"
array [
]
)
dict entry(
string "org.bluez.ProfileManager1"
array [
]
)
dict entry(
string "org.bluez.HealthManager1"
array [
]
)
]
)
dict entry(
object path "/org/bluez/hci0"
array [
dict entry(
string "org.freedesktop.DBus.Introspectable"
array [
]
)
dict entry(
string "org.bluez.Adapter1"
array [
dict entry(
string "Address"
variant string "C8:3D:D4:A3:A7:4E"
)
dict entry(
string "AddressType"
variant string "public"
)
dict entry(
string "Name"
variant string "kafka-PC"
)
dict entry(
string "Alias"
variant string "Alioth"
)
dict entry(
string "Class"
variant uint32 786700
)
dict entry(
string "Powered"
variant boolean true
)
dict entry(
string "Discoverable"
variant boolean true
)
dict entry(
string "DiscoverableTimeout"
variant uint32 0
)
dict entry(
string "Pairable"
variant boolean true
)
dict entry(
string "PairableTimeout"
variant uint32 0
)
dict entry(
string "Discovering"
variant boolean false
)
dict entry(
string "UUIDs"
variant array [
string "00001112-0000-1000-8000-00805f9b34fb"
string "00001801-0000-1000-8000-00805f9b34fb"
string "0000110e-0000-1000-8000-00805f9b34fb"
string "00001800-0000-1000-8000-00805f9b34fb"
string "00001200-0000-1000-8000-00805f9b34fb"
string "0000110c-0000-1000-8000-00805f9b34fb"
string "0000110a-0000-1000-8000-00805f9b34fb"
string "0000110b-0000-1000-8000-00805f9b34fb"
string "00001108-0000-1000-8000-00805f9b34fb"
]
)
dict entry(
string "Modalias"
variant string "usb:v1D6Bp0246d0532"
)
]
)
dict entry(
string "org.freedesktop.DBus.Properties"
array [
]
)
dict entry(
string "org.bluez.GattManager1"
array [
]
)
dict entry(
string "org.bluez.LEAdvertisingManager1"
array [
dict entry(
string "ActiveInstances"
variant byte 0
)
dict entry(
string "SupportedInstances"
variant byte 5
)
dict entry(
string "SupportedIncludes"
variant array [
string "tx-power"
string "appearance"
string "local-name"
]
)
]
)
dict entry(
string "org.bluez.Media1"
array [
]
)
dict entry(
string "org.bluez.NetworkServer1"
array [
]
)
]
)
]
不啰嗦了,接着调用这个方法org.freedesktop.DBus.Introspectable.Introspect
,看看org.bluez对象下的方法咋用
method return time=1596563047.620415 sender=:1.21 -> destination=:1.1453 serial=9222 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="xml" type="s" direction="out"/>
</method>
</interface>
<interface name="org.bluez.AgentManager1">
<method name="RegisterAgent">
<arg name="agent" type="o" direction="in"/>
<arg name="capability" type="s" direction="in"/>
</method>
<method name="UnregisterAgent">
<arg name="agent" type="o" direction="in"/>
</method>
<method name="RequestDefaultAgent">
<arg name="agent" type="o" direction="in"/>
</method>
</interface>
<interface name="org.bluez.ProfileManager1">
<method name="RegisterProfile">
<arg name="profile" type="o" direction="in"/>
<arg name="UUID" type="s" direction="in"/>
<arg name="options" type="a{sv}" direction="in"/>
</method>
<method name="UnregisterProfile">
<arg name="profile" type="o" direction="in"/>
</method>
</interface>
<interface name="org.bluez.HealthManager1">
<method name="CreateApplication">
<arg name="config" type="a{sv}" direction="in"/>
<arg name="application" type="o" direction="out"/>
</method>
<method name="DestroyApplication">
<arg name="application" type="o" direction="in"/>
</method>
</interface>
<node name="hci0"/></node>"
注意下node
节点,说明下面还有个obj,从GetManagedObjects
调用也能看得出来。剩下的,就是循环调用就可以了。
dbus-monitor
dbus-monitor
[--system | --session | --address ADDRESS]
[--profile | --monitor | --pcap | --binary]
[watch expressions]
选项 | 简介 |
---|---|
--system | 监视system总线 |
--session | 监视session总线(默认) |
--address ADDRESS | 监视指定地址总线 |
--profile | 输出格式 |
--monitor | 输出格式(默认) |
--pcap | 输出格式 |
--binary | 输出格式 |
[watch expressions] | 其他筛选参数,可选 |
示例
$ sudo dbus-monitor --profile --system "type='method_call',interface='org.bluez.Adapter1'"
返回
#type timestamp serial sender destination path interface member
# in_reply_to
mc 1596816138.631705 1364909 :1.63 org.bluez /org/bluez/hci0 org.bluez.Adapter1 StartDiscovery
mc 1596816143.954247 1364921 :1.63 org.bluez /org/bluez/hci0 org.bluez.Adapter1 RemoveDevice
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。