Hi Lennart,

On Tue, Sep 08, 2020 at 03:58:34PM +0200, Lennart Poettering wrote:
> > 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.

interestingly enough the same error does not happen today, it just returns
the tree, thanks for the log level hint though - that is indeed
very helpful!
 
> > 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

Oh, so you mean that when I use "busctl call" it would detect and fake a 
GetManagedObjects() method invocation and internally use XML introspection?

That's good to know since I was using busctl to debug/test and I was assuming 
that it does the calls as instructed.

> Unlike GetManagedObjects() the XML introspection stuff is implemented
> by most services.

Understood.

Is it somehow possible to figure this out via command line tools if the
problem is in the missing GetManagedObjects() implementation or not?

> > 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...

Uhm, how do I correctly "enter" a container like this one: "a{oa{sa{sv}}}" ?

I guess this is correct, what GetManagedObjects() returns is an array of
dictionaries "a{oa{sa{sv}}}" or am I misinterpreting it?
 
> 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.

I already had error checks everywhere except loops, so I added that now.

sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "oa{sa{sv}}")
returns 1 on the first call, thats where I get the first path that
equals to "/org/freedesktop/ModemManager1/Modem/0" and it returns 0 on the
next invocation.

This leads me to the next question below...

> 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.

Could you please clarify how iteration works in sd_bus sense? Is my 
understanding correct that I need to use sd_bus_message_skip() before
exiting the container in order to iterate to the next item, if I am not
interested in parsing all of the nested items? Or can I just "exit" at any
time and expect the next "enter" invocation to fast forward to the
next entry?

Based on what you are saying the inner while loop that I had right after
entering the array should have returned all items. So I start by entering
the array:

// starting with a{oa{sa{sv}}}
sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "{oa{sa{sv}}}")

And loop over dictionary key-value pairs:

// brings me down into oa{sa{sv}}}, I am only interested in the object paths:
while (sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "oa{sa{sv}}") 
> 0) {
    sd_bus_message_read_basic(m, SD_BUS_TYPE_OBJECT_PATH, &path);
    sd_bus_message_skip(m, "a{sa{sv}}");
    sd_bus_message_exit_container(m);
}

Does the above look correct? As mentioned, I am not getting errors, return
codes are fine, so it all looks normal, but I am only reading out
the first path, on the second iteration
sd_bus_message_enter_container(m, SD_BUS_TYPE_DICT_ENTRY, "oa{sa{sv}}") returns 
0 which aborts the loop.

At this point I am not sure if sd_bus actually behaves correctly and
GetManagedObjects() returns only one path or if I messed up the parsing of
the reply somehow? And I am not sure how to check that...

I would like to avoid parsing XML if I can, but of course that option is
still there; nevertheless, I would first like to understand what is going on 
with the GetManagedObjects() call and if the problem is really there or 
somewhere else.

Kind regars,
Jin

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to