I wish to use sd-bus to query upowerd for my battery's remaining percentage. I have begun by adapting the example program from Lennart's blog post introducing the sd-bus API:
http://0pointer.net/blog/the-new-sd-bus-api-of-systemd.html However, I cannot succeed in adapting it to my needs. I can read the value of the Percentage property with $ busctl introspect org.freedesktop.UPower /org/freedesktop/UPower/devices/battery_BAT0 This shows me that the Percentage is a double value, and that the Get() method of the org.freedesktop.DBus.Properties interface returns a variant value. I can also retrieve the desired datum with busctl: $ busctl call org.freedesktop.UPower \ /org/freedesktop/UPower/devices/battery_BAT0 \ org.freedesktop.DBus.Properties Get \ ss org.freedesktop.UPower.Device Percentage I can make the equivalent method call using the sd-bus API from the C program, but the program errors out at the call to sd_bus_message_read(). When I tell sd_bus_message_read() that my message is of variant type "v", it fails with -EINVAL. When I instead give it "d", it fails with -ENXIO. What does sd_bus_message_read() expect in the 2nd argument? Or am I doing something else wrong? /* gcc bus-client.c -o bus-client -lsystemd */ #include <stdio.h> #include <stdlib.h> #include <systemd/sd-bus.h> int main() { sd_bus_error error = SD_BUS_ERROR_NULL; sd_bus_message *m = NULL; sd_bus *bus = NULL; int r; double p; /* Connect to the system bus */ r = sd_bus_open_system(&bus); if (r < 0) { fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r)); goto finish; } /* The following call to sd_bus_call_method() should be equivalent to this cmd: busctl call org.freedesktop.UPower \ /org/freedesktop/UPower/devices/battery_BAT0 \ org.freedesktop.DBus.Properties Get \ ss org.freedesktop.UPower.Device Percentage */ r = sd_bus_call_method(bus, "org.freedesktop.UPower", /* service to contact */ "/org/freedesktop/UPower/devices/battery_BAT0", /* object path */ "org.freedesktop.DBus.Properties", /* interface name */ "Get", /* method name */ &error, /* object to return error in */ &m, /* return message on success */ "ss" /* input signature */ ,"org.freedesktop.UPower.Device" /* first argument */ ,"Percentage" /* second argument */ ); if (r < 0) { fprintf(stderr, "Failed to issue method call: %s\n", error.message); goto finish; } /* XXX This is where the failure is occurring XXX */ r = sd_bus_message_read(m, "v", &p); if (r < 0) { fprintf(stderr, "Failed to parse response message: (%d) %s\n", r, strerror(-r)); goto finish; } printf("Battery %f%%", p); finish: sd_bus_error_free(&error); sd_bus_message_unref(m); sd_bus_unref(bus); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } /* * Running this program results in the following output: * * % ./bus-client * Failed to parse response message: (-22) Invalid argument * */ -- Erik Falor Registered Linux User #445632 http://unnovative.net
signature.asc
Description: PGP signature
_______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/systemd-devel