Como listar todos os caminhos de objetos sob um serviço dbus?

15

Esta é uma pergunta de acompanhamento para Uma lista de serviços DBus disponíveis .

O seguinte código python listará todos os serviços DBus disponíveis.

import dbus
for service in dbus.SystemBus().list_names():
    print(service)

Como listamos os caminhos de objeto sob os serviços em python? Não há problema se a resposta não envolver python, embora seja preferível.

Estou usando o Ubuntu 14.04

    
por user768421 14.05.2015 / 17:04

4 respostas

12

De acordo com as docs oficiais (em interfaces padrão ):

There are some standard interfaces that may be useful across various D-Bus applications.

org.freedesktop.DBus.Introspectable

This interface has one method:

org.freedesktop.DBus.Introspectable.Introspect (out STRING xml_data)

Objects instances may implement Introspect which returns an XML description of the object, including its interfaces (with signals and methods), objects below it in the object path tree, and its properties.

Então aqui está um exemplo muito simplista que deve começar. Ele usa xml.etree.ElementTree e dbus :

#!/usr/bin/env python

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 == 'node':
            if object_path == '/':
                object_path = ''
            new_path = '/'.join((object_path, child.attrib['name']))
            rec_intro(bus, service, new_path)

bus = dbus.SystemBus()
rec_intro(bus, 'org.freedesktop.UPower', '/org/freedesktop/UPower')

Ele recursivamente faz a introspecção de org.freedesktop.UPower a partir de, e. /org/freedesktop/UPower e imprime todos os caminhos de objetos (nomes de nós):

/org/freedesktop/UPower
/org/freedesktop/UPower/Wakeups
/org/freedesktop/UPower/devices
/org/freedesktop/UPower/devices/DisplayDevice
/org/freedesktop/UPower/devices/battery_BAT0
/org/freedesktop/UPower/devices/line_power_ADP0

que é praticamente o que você teria se usasse d-feet (não que você precisasse):

Claro,vocêpodeobterfacilmenteoscaminhosdeobjetovialinhadecomando,comgdbus:

gdbusintrospect--system--destorg.freedesktop.UPower--object-path\/org/freedesktop/UPower--recurse|awk'/^*node/{print$2}'
/org/freedesktop/UPower/org/freedesktop/UPower/Wakeups/org/freedesktop/UPower/devices/org/freedesktop/UPower/devices/DisplayDevice/org/freedesktop/UPower/devices/battery_BAT0/org/freedesktop/UPower/devices/line_power_ADP0

Eunãotenhoqdbusinstalado,masdeacordocom esta página

qdbus --system org.freedesktop.UPower

deve produzir um resultado semelhante.

    
por 15.05.2015 / 21:42
3

Não sei se você pode fazer isso programaticamente no Python. Você pode, mas será uma enorme dor de cabeça para descobrir como. Eu tentei fazer isso antes e acabei odiando o Dbus. De qualquer forma, eu recomendo usar d-feet se você quiser investigar as coisas. Abaixo está uma imagem que eu roubei do meu blog .

Uma vez que você sabe o nome do programa, o caminho do objeto, etc., você pode usar o Python para acessar essas coisas.

Exemplo

progname = 'org.freedesktop.NetworkManager'
objpath  = '/org/freedesktop/NetworkManager'
intfname = 'org.freedesktop.NetworkManager'
methname = 'GetDevices'

bus = dbus.SystemBus()

obj  = bus.get_object(progname, objpath)  # Here we get object
intf = dbus.Interface(obj, intfname)      # Here we get interface
meth = inf.get_dbus_method(methname)      # Here we get method

meth()                                    # And finally calling the method

Como você vê, é uma dor na bunda para fazer uma coisa simples. Mas este é o fluxo de trabalho mais fácil que você pode obter com o Dbus!

Portanto, use uma ferramenta GUI para descobrir os caminhos, as interfaces, etc. de objetos. Em seguida, use o snippet de código acima como um modelo para acessar essas coisas. Também sugiro que você faça isso através do intérprete do IPython para ver quais métodos, propriedades, etc. cada objeto possui (clicando na aba).

    
por 15.05.2015 / 13:21
1

O que eu sei da minha experiência para obter os caminhos de objeto de um nome de barramento (serviço) é possível fazer uma introspecção com o caminho do objeto '/', ou seja, (usando o exemplo acima)

introspectfunc('org.freedesktop.UPower', '/') 

isso deve retornar:

<node name="/"> 
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/>
<node name="org"/></node>

faça uma introspecção com o caminho '/ org'

introspectfunc('org.freedesktop.UPower', '/org')

isso deve retornar:

<node name="/org"> 
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/>
<node name="freedesktop"/></node>

e assim por diante:

introspectfunc('org.freedesktop.UPower', '/org/freedesktop')
introspectfunc('org.freedesktop.UPower', '/org/freedesktop/UPower')
etc.

É como percorrer a estrutura de pastas do disco rígido, onde o caminho do objeto '/' é a raiz e cada nó é uma subpasta. Esta parece ser a melhor maneira de recuperar os caminhos de objetos de um determinado nome de barramento (serviço) e construir uma coleção contendo os caminhos de objetos

    
por 28.09.2015 / 16:38
1

Se o serviço tiver um objeto implementando org.freedesktop.DBus.ObjectManager , seu método GetManagedObjects retornará “Todos os objetos, interfaces e propriedades em uma única chamada de método.” Por exemplo, o UDisks2 tem esse objeto.

    
por 22.06.2016 / 15:14