1

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...]
--systemsystem类型
--sessionsession类型
--address发送到指定地址
--print-reply打印回应的消息.也可以写--print-reply=literal,,literal会把所有的标点和转义符号去掉
--reply-timeout响应超时,ms计算
--type消息类型 signal、method_call
--destobject 的 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

Alkaid
11 声望0 粉丝

驱动开发、Wi-Fi驱动、Bluetooth驱动、BSP开发


引用和评论

0 条评论