Thursday, June 2, 2016

[RR Bluetooth] list dbus services (buses), path, interfaces, methods, and properties

Though I am working on bluetooth/bluez/python, it is still a lot stuff I have to catch up with dbus because dbus is a major path to communicate with bluez.

It's interesting to check what kind of dbus service (bus name actually) currently provided in the system.

from A list of available DBus services we know that command
dbus-send --system            \
  --dest=org.freedesktop.DBus \
  --type=method_call          \
  --print-reply               \
  /org/freedesktop/DBus       \
  org.freedesktop.DBus.ListNames

can do and the result at my env is (18 items)

method return time=1464797917.554108 sender=org.freedesktop.DBus -> destination=:1.104 serial=3 reply_serial=2
   array [
      string "org.freedesktop.DBus"
      string ":1.7"
      string "org.freedesktop.systemd1"
      string "org.freedesktop.ModemManager1"
      string "org.freedesktop.NetworkManager"
      string "org.freedesktop.Accounts"
      string "org.freedesktop.RealtimeKit1"
      string ":1.80"
      string ":1.81"
      string ":1.82"
      string ":1.60"
      string ":1.83"
      string ":1.61"
      string ":1.84"
      string ":1.62"
      string ":1.85"
      string ":1.86"
      string ":1.64"
      string "org.freedesktop.PolicyKit1"
      string ":1.20"
      string ":1.87"
      string ":1.65"
      string "org.bluez"
      string ":1.21"
      string ":1.88"
      string ":1.66"
      string ":1.22"
      string ":1.89"
      string ":1.67"
      string ":1.68"
      string ":1.46"
      string ":1.24"
      string ":1.69"
      string ":1.47"
      string "fi.epitest.hostap.WPASupplicant"
      string "org.freedesktop.Avahi"
      string "org.freedesktop.UDisks2"
      string ":1.90"
      string "fi.w1.wpa_supplicant1"
      string ":1.91"
      string ":1.70"
      string "org.freedesktop.login1"
      string ":1.71"
      string ":1.94"
      string "org.freedesktop.ColorManager"
      string ":1.50"
      string ":1.95"
      string "org.freedesktop.DisplayManager"
      string ":1.96"
      string ":1.74"
      string "org.freedesktop.NetworkManager.dnsmasq"
      string "org.freedesktop.thermald"
      string ":1.98"
      string ":1.10"
      string ":1.99"
      string ":1.55"
      string ":1.11"
      string ":1.78"
      string "org.freedesktop.UPower"
      string ":1.12"
      string ":1.0"
      string ":1.13"
      string ":1.100"
      string ":1.58"
      string ":1.1"
      string ":1.2"
      string ":1.59"
      string ":1.3"
      string ":1.4"
      string ":1.17"
      string ":1.39"
      string ":1.104"
      string ":1.18"
      string ":1.6"
      string ":1.19"
   ]
the equivalent python is (How to list all object paths under a dbus service? ) which has the same result.
import dbus
for service in dbus.SystemBus().list_names(): print(service)

Similar method is ListActivatableNames but returns more bus names (Maybe those are candidates to be actually got connected to systembus on demand)

the result on my pc are listed below (31 items):

org.freedesktop.DBus
org.freedesktop.login1
com.ubuntu.LanguageSelector
com.ubuntu.USBCreator
com.hp.hplip
org.freedesktop.ColorManager
com.ubuntu.SoftwareProperties
org.freedesktop.systemd1
org.freedesktop.thermald
org.freedesktop.PolicyKit1
org.freedesktop.Avahi
org.freedesktop.ModemManager1
org.debian.apt
org.bluez
org.freedesktop.hostname1
org.freedesktop.PackageKit
org.freedesktop.UPower
org.freedesktop.UDisks2
org.freedesktop.network1
com.ubuntu.SystemService
org.freedesktop.resolve1
org.debian.AptXapianIndex
fi.epitest.hostap.WPASupplicant
fi.w1.wpa_supplicant1
org.freedesktop.Accounts
com.ubuntu.WhoopsiePreferences
org.freedesktop.RealtimeKit1
org.freedesktop.timedate1
org.freedesktop.nm_dispatcher
org.opensuse.CupsPkHelper.Mechanism
org.freedesktop.locale1

PATH and interface

by slightly modifying the code from here, we can show path with corresponding interfaces:
import dbus
from xml.etree import ElementTree

def rec_intro(bus, service, object_path):
    print(object_path)
    obj = bus.get_object(service, object_path)
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    for child in ElementTree.fromstring(xml_string):
        if child.tag == 'interface':
            print 'interface: ' + child.attrib['name']
        if child.tag == 'node':
            if object_path == '/':
                object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            print '\n'
            rec_intro(bus, service, new_path)
bus = dbus.SystemBus()
rec_intro(bus, 'org.bluez', '/org/bluez')

and the result 
/org/bluez
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.AgentManager1
interface: org.bluez.ProfileManager1
interface: org.bluez.Alert1
interface: org.bluez.HealthManager1

/org/bluez/hci0
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Adapter1
interface: org.freedesktop.DBus.Properties
interface: org.bluez.Media1
interface: org.bluez.CyclingSpeedManager1
interface: org.bluez.HeartRateManager1
interface: org.bluez.ThermometerManager1
interface: org.bluez.NetworkServer1

/org/bluez/hci0/dev_00_02_72_C0_3F_D7
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Device1
interface: org.freedesktop.DBus.Properties

/org/bluez/hci0/dev_00_07_61_EB_E9_35
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Device1
interface: org.freedesktop.DBus.Properties
interface: org.bluez.Input1

/org/bluez/hci0/dev_34_B1_F7_D5_59_64
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Device1
interface: org.freedesktop.DBus.Properties
interface: org.bluez.ProximityReporter1

/org/bluez/hci0/dev_88_18_56_68_98_EB
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Device1
interface: org.freedesktop.DBus.Properties

/org/bluez/hci0/dev_90_59_AF_09_EB_93
interface: org.freedesktop.DBus.Introspectable
interface: org.bluez.Device1
interface: org.freedesktop.DBus.Properties

To list interface, method, and property, the simple code is 


import dbus
from xml.etree import ElementTree
def rec_intro(bus, service, object_path):
    print(object_path)
    obj = bus.get_object(service, object_path)
# get props
    iface = dbus.Interface(obj, 'org.freedesktop.DBus.Introspectable')
    xml_string = iface.Introspect()
    for child in ElementTree.fromstring(xml_string):
        if child.tag == 'interface':
            print 'interface: ' + child.attrib['name']
            for c in child.getchildren():
              if c.tag == 'property':
                print 'property: ' + c.attrib['name'] + ' ' + c.attrib['type'] + ' ' + c.attrib['access']
              if c.tag == 'method':
                print 'metohd: ' + c.attrib['name']
        print '\n'
        if child.tag == 'node':
            if object_path == '/':
                object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            print '\n'
            rec_intro(bus, service, new_path)
bus = dbus.SystemBus()
rec_intro(bus, 'org.bluez', '/org/bluez')