[systemd-devel] libsystemd/sd_bus: trouble understanding how to parse complex responses
Lennart Poettering
lennart at poettering.net
Tue Sep 8 13:58:34 UTC 2020
On Mo, 07.09.20 19:40, Sergey 'Jin' Bostandzhyan (jin at mediatomb.cc) wrote:
> Hi,
>
> I have spent quite some time on this, but I don't seem to be getting
> anywhere, so I hope someone could point me in the right direction.
>
> I am learning sd_bus, my goal is to get a list of available modem services
> from ModemManager. To make sure that what I am looking for is actually there,
> I first checked with busctl:
>
> Service org.freedesktop.ModemManager1:
> └─/org
> └─/org/freedesktop
> └─/org/freedesktop/ModemManager1
> ├─/org/freedesktop/ModemManager1/Modem
> │ └─/org/freedesktop/ModemManager1/Modem/0
> └─/org/freedesktop/ModemManager1/SIM
> └─/org/freedesktop/ModemManager1/SIM/0
>
> Service /org/freedesktop/ModemManager1:
> Failed to introspect object / of service /org/freedesktop/ModemManager1: Invali argument
> No objects discovered.
>
> The tree looks fine, the error message is a bit weird?
Hmm, consider running this with the env var SYSTEMD_LOG_LEVEL=debug
set, maybe that explains where the error is generated.
> The only things I am interested in are the paths:
> /org/freedesktop/ModemManager1/Modem/0
> /org/freedesktop/ModemManager1/SIM/0
>
> The above paths may change when the modem is replugged, so I'd like to query
> them dynamically.
>
> I learned that the call to list what I need is "GetManagedObjects":
> busctl call org.freedesktop.ModemManager1
> /org/freedesktop/ModemManager1 org.freedesktop.DBus.ObjectManager
> GetManagedObjects
GetManagedObjects() is only available in some services, it's an
optional interface. "busctl" uses the XML introspection logic to
enumerate objects, i.e. this:
https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format
Unlike GetManagedObjects() the XML introspection stuff is implemented
by most services.
> while (sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{oa{sa{sv}}}") > 0)
> {
Hmm, this is what you'd write when you have an array of arrays...
sd_bus_message_enter_container() returns < 0 on error, == 0 if we
reached the end of the surrounding container, and > 0 if all was
good. I'd recommend checking for error cases which you ignore
here. The errors tell you where things go wrong.
Normally, you#d enter the array once and then iterate through the
dict entries contained therein. i.e. unless there's an "aa" object
somewhere (i.e. "array of array") you'd do the while loop around the
dict entries, not the array object.
Lennart
--
Lennart Poettering, Berlin
More information about the systemd-devel
mailing list