Created
July 2, 2022 14:39
-
-
Save AtieP/cbf3d1637e38067560470895b7b44670 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <dbus-1.0/dbus/dbus.h> | |
#include <stdio.h> | |
#include "pthread.h" | |
#include <stdint.h> | |
pthread_mutex_t handle_signal_lock = PTHREAD_MUTEX_INITIALIZER; | |
static DBusHandlerResult | |
handle_signal(DBusConnection *connection, DBusMessage *message, void *user_data) | |
{ | |
DBusMessageIter iter, array, dict, variant; | |
DBusBasicValue interface_name, property_name, value; | |
int type; | |
uint64_t v; | |
const char *interface = "org.freedesktop.DBus.Properties"; | |
const char *object = "/org/freedesktop/UPower/devices/battery_BAT0"; | |
const char *member = "PropertiesChanged"; | |
if (dbus_message_get_type(message) != DBUS_MESSAGE_TYPE_SIGNAL) | |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | |
printf("received signal from %s\n", dbus_message_get_sender(message)); | |
/* Make sure this comes where we want from. */ | |
if (!dbus_message_has_interface(message, interface)) | |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | |
if (!dbus_message_has_path(message, object)) | |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | |
if (!dbus_message_has_member(message, member)) | |
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; | |
printf("signal coming from %s.%s on %s\n", interface, member, object); | |
pthread_mutex_lock(&handle_signal_lock); | |
/* Parse the arguments. We expect a: | |
s - interface_name | |
a{sv} - changed_properties | |
as - invalidated_properties | |
we do not care about invalidated_properties | |
*/ | |
dbus_message_iter_init(message, &iter); | |
/* interface_name */ | |
dbus_message_iter_get_basic(&iter, &interface_name); | |
printf("- interface_name: %s\n", interface_name.str); | |
dbus_message_iter_next(&iter); | |
/* changed_properties */ | |
dbus_message_iter_recurse(&iter, &array); | |
while ((type = dbus_message_iter_get_arg_type(&array)) != DBUS_TYPE_INVALID) { | |
/* open the dict */ | |
dbus_message_iter_recurse(&array, &dict); | |
/* get the property_name */ | |
dbus_message_iter_get_basic(&dict, &property_name); | |
printf("- property_name: %s\n", property_name.str); | |
/* get the value, it's a variant, parsing needed */ | |
dbus_message_iter_next(&dict); | |
dbus_message_iter_recurse(&dict, &variant); | |
type = dbus_message_iter_get_arg_type(&variant); | |
dbus_message_iter_get_basic(&variant, &value); | |
if (type == DBUS_TYPE_STRING) { | |
printf("- value: %s\n", value.str); | |
} else if (type == DBUS_TYPE_UINT64) | |
v = value.u64; | |
else if (type == DBUS_TYPE_INT64) | |
v = value.i64; | |
else if (type == DBUS_TYPE_UINT32) | |
v = value.u32; | |
else if (type == DBUS_TYPE_INT32) | |
v = value.i32; | |
else if (type == DBUS_TYPE_UINT16) | |
v = value.u16; | |
else if (type == DBUS_TYPE_INT16) | |
v = value.i16; | |
else if (type == DBUS_TYPE_BYTE) | |
v = value.byt; | |
else if (type == DBUS_TYPE_BOOLEAN) | |
v = value.bool_val; | |
else if (type == DBUS_TYPE_DOUBLE) | |
v = (uint64_t) value.dbl; | |
else { | |
printf("> (unknown)\n"); | |
dbus_message_iter_next(&array); | |
continue; | |
} | |
printf("> %llu\n", v); | |
dbus_message_iter_next(&array); | |
} | |
pthread_mutex_unlock(&handle_signal_lock); | |
return DBUS_HANDLER_RESULT_HANDLED; | |
} | |
int | |
main(void) | |
{ | |
DBusConnection *conn; | |
DBusError err; | |
dbus_error_init(&err); | |
/* Get a connection to the system bus. */ | |
conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err); | |
if (!conn) { | |
fprintf(stderr, "dbus_bus_get failure: %s\n", err.message); | |
return 1; | |
} | |
dbus_connection_set_exit_on_disconnect(conn, FALSE); | |
/* Request the bus that we're interested on this type | |
of broadcast signals. */ | |
dbus_bus_add_match(conn, "type='signal',path='/org/freedesktop/UPower/devices/battery_BAT0',interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'", &err); | |
if (dbus_error_is_set(&err)) { | |
fprintf(stderr, "dbus_bus_add_match failure: %s\n", err.message); | |
return 1; | |
} | |
/* Add a filter to the incoming messages queue. */ | |
if (!dbus_connection_add_filter(conn, handle_signal, NULL, NULL)) { | |
fprintf(stderr, "dbus_connection_add_filter failure: %s\n", err.message); | |
return 1; | |
} | |
while (dbus_connection_read_write_dispatch(conn, -1)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment