Skip to content

Instantly share code, notes, and snippets.

@AtieP
Created July 2, 2022 14:39
Show Gist options
  • Save AtieP/cbf3d1637e38067560470895b7b44670 to your computer and use it in GitHub Desktop.
Save AtieP/cbf3d1637e38067560470895b7b44670 to your computer and use it in GitHub Desktop.
#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