From 8e894565e933d77aae491ec1bfd3204836f00fff Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Fri, 25 Dec 2009 03:44:07 -0800 Subject: [PATCH] Add signal handling to supplicant test program --- tools/supplicant-test.c | 23 +++++++++++-- tools/supplicant.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++-- tools/supplicant.h | 11 +++++-- 3 files changed, 115 insertions(+), 7 deletions(-) diff --git a/tools/supplicant-test.c b/tools/supplicant-test.c index d2bb3c2..b448a02 100644 --- a/tools/supplicant-test.c +++ b/tools/supplicant-test.c @@ -33,6 +33,25 @@ #include "supplicant.h" +#define DBG(fmt, arg...) do { \ + syslog(LOG_DEBUG, "%s() " fmt, __FUNCTION__ , ## arg); \ +} while (0) + +static void interface_added(const struct supplicant_interface *interface) +{ + DBG("interface %p", interface); +} + +static void interface_removed(const struct supplicant_interface *interface) +{ + DBG("interface %p", interface); +} + +static const struct supplicant_callbacks callbacks = { + .interface_added = interface_added, + .interface_removed = interface_removed, +}; + static GMainLoop *main_loop = NULL; static void sig_term(int sig) @@ -80,14 +99,14 @@ int main(int argc, char *argv[]) syslog(LOG_INFO, "Startup"); - if (supplicant_init() < 0) { + if (supplicant_register(&callbacks) < 0) { syslog(LOG_ERR, "Failed to init supplicant"); goto done; } g_main_loop_run(main_loop); - supplicant_exit(); + supplicant_unregister(&callbacks); done: syslog(LOG_INFO, "Exit"); diff --git a/tools/supplicant.c b/tools/supplicant.c index 0e4ffc2..4653a7f 100644 --- a/tools/supplicant.c +++ b/tools/supplicant.c @@ -24,8 +24,10 @@ #endif #include +#include #include +#include #include #include "supplicant.h" @@ -42,6 +44,8 @@ static DBusConnection *connection; +static const struct supplicant_callbacks *callbacks_pointer; + static void show_property(const char *key, DBusMessageIter *iter) { DBusMessageIter array; @@ -50,10 +54,12 @@ static void show_property(const char *key, DBusMessageIter *iter) switch (dbus_message_iter_get_arg_type(iter)) { case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: dbus_message_iter_get_basic(iter, &str); DBG("%s = %s", key, str); break; case DBUS_TYPE_BYTE: + case DBUS_TYPE_BOOLEAN: dbus_message_iter_get_basic(iter, &byte); DBG("%s = %u", key, byte); break; @@ -174,7 +180,51 @@ static int properties_get_all(const char *path, const char *interface) return 0; } -int supplicant_init(void) +static DBusHandlerResult supplicant_filter(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + int prefixlen = strlen(SUPPLICANT_INTERFACE); + const char *interface, *member, *path; + + interface = dbus_message_get_interface(msg); + if (interface == NULL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + if (g_str_has_prefix(interface, SUPPLICANT_INTERFACE) == FALSE) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + member = dbus_message_get_member(msg); + if (member == NULL) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + + path = dbus_message_get_path(msg); + + syslog(LOG_DEBUG, "[ %s ]%s.%s", path, interface + prefixlen, member); + + if (g_str_equal(member, "PropertiesChanged") == TRUE) { + DBusMessageIter iter; + + if (dbus_message_iter_init(msg, &iter) == TRUE) + properties_decode(&iter); + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static const char *supplicant_rule1 = "type=signal," + "interface=" SUPPLICANT_INTERFACE; +static const char *supplicant_rule2 = "type=signal," + "interface=" SUPPLICANT_INTERFACE ".Interface"; +static const char *supplicant_rule3 = "type=signal," + "interface=" SUPPLICANT_INTERFACE ".Interface.WPS"; +static const char *supplicant_rule4 = "type=signal," + "interface=" SUPPLICANT_INTERFACE ".Interface.BSS"; +static const char *supplicant_rule5 = "type=signal," + "interface=" SUPPLICANT_INTERFACE ".Interface.Network"; +static const char *supplicant_rule6 = "type=signal," + "interface=" SUPPLICANT_INTERFACE ".Interface.Blob"; + +int supplicant_register(const struct supplicant_callbacks *callbacks) { DBG(""); @@ -182,15 +232,47 @@ int supplicant_init(void) if (connection == NULL) return -EIO; + if (dbus_connection_add_filter(connection, + supplicant_filter, NULL, NULL) == FALSE) { + dbus_connection_unref(connection); + connection = NULL; + return -EIO; + } + + callbacks_pointer = callbacks; + + dbus_bus_add_match(connection, supplicant_rule1, NULL); + dbus_bus_add_match(connection, supplicant_rule2, NULL); + dbus_bus_add_match(connection, supplicant_rule3, NULL); + dbus_bus_add_match(connection, supplicant_rule4, NULL); + dbus_bus_add_match(connection, supplicant_rule5, NULL); + dbus_bus_add_match(connection, supplicant_rule6, NULL); + dbus_connection_flush(connection); + properties_get_all(SUPPLICANT_PATH, SUPPLICANT_INTERFACE); return 0; } -void supplicant_exit(void) +void supplicant_unregister(const struct supplicant_callbacks *callbacks) { DBG(""); - if (connection != NULL) + if (connection != NULL) { + dbus_bus_remove_match(connection, supplicant_rule6, NULL); + dbus_bus_remove_match(connection, supplicant_rule5, NULL); + dbus_bus_remove_match(connection, supplicant_rule4, NULL); + dbus_bus_remove_match(connection, supplicant_rule3, NULL); + dbus_bus_remove_match(connection, supplicant_rule2, NULL); + dbus_bus_remove_match(connection, supplicant_rule1, NULL); + dbus_connection_flush(connection); + + dbus_connection_remove_filter(connection, + supplicant_filter, NULL); + dbus_connection_unref(connection); + connection = NULL; + } + + callbacks_pointer = NULL; } diff --git a/tools/supplicant.h b/tools/supplicant.h index 1465108..e7ba876 100644 --- a/tools/supplicant.h +++ b/tools/supplicant.h @@ -19,5 +19,12 @@ * */ -int supplicant_init(void); -void supplicant_exit(void); +struct supplicant_interface; + +struct supplicant_callbacks { + void (*interface_added) (const struct supplicant_interface *interface); + void (*interface_removed) (const struct supplicant_interface *interface); +}; + +int supplicant_register(const struct supplicant_callbacks *callbacks); +void supplicant_unregister(const struct supplicant_callbacks *callbacks); -- 2.7.4