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@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/systemd-devel