18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wpa_supplicant D-Bus control interface - common functionality 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Witold Sowa <witold.sowa@gmail.com> 58d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2009, Jouni Malinen <j@w1.fi> 68d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This program is free software; you can redistribute it and/or modify 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it under the terms of the GNU General Public License version 2 as 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * published by the Free Software Foundation. 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * license. 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * See README and COPYING for more details. 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/includes.h" 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include <dbus/dbus.h> 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/common.h" 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "utils/eloop.h" 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_common.h" 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_common_i.h" 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_new.h" 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "dbus_old.h" 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifndef SIGPOLL 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef SIGIO 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If we do not have SIGPOLL, try to use SIGIO instead. This is needed for 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FreeBSD. 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#define SIGPOLL SIGIO 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void dispatch_data(DBusConnection *con) 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (dbus_connection_get_dispatch_status(con) == 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBUS_DISPATCH_DATA_REMAINS) 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_dispatch(con); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * dispatch_initial_dbus_messages - Dispatch initial dbus messages after 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * claiming bus name 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eloop_ctx: the DBusConnection to dispatch on 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @timeout_ctx: unused 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * If clients are quick to notice that service claimed its bus name, 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * there may have been messages that came in before initialization was 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * all finished. Dispatch those here. 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx) 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBusConnection *con = eloop_ctx; 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dispatch_data(con); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_watch(struct wpas_dbus_priv *priv, 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBusWatch *watch, eloop_event_type type) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_ref(priv->con); 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->should_dispatch = 0; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (type == EVENT_TYPE_READ) 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_READABLE); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (type == EVENT_TYPE_WRITE) 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_WRITABLE); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else if (type == EVENT_TYPE_EXCEPTION) 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_ERROR); 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->should_dispatch) { 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dispatch_data(priv->con); 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->should_dispatch = 0; 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_unref(priv->con); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx) 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION); 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx) 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE); 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic dbus_bool_t add_watch(DBusWatch *watch, void *data) 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv = data; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int flags; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dbus_watch_get_enabled(watch)) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = dbus_watch_get_flags(watch); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd = dbus_watch_get_unix_fd(watch); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception, 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv, watch); 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & DBUS_WATCH_READABLE) { 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv, watch); 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & DBUS_WATCH_WRITABLE) { 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write, 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv, watch); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_watch_set_data(watch, priv, NULL); 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void remove_watch(DBusWatch *watch, void *data) 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int flags; 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int fd; 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = dbus_watch_get_flags(watch); 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt fd = dbus_watch_get_unix_fd(watch); 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION); 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & DBUS_WATCH_READABLE) 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_READ); 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & DBUS_WATCH_WRITABLE) 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_WRITE); 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_watch_set_data(watch, NULL, NULL); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void watch_toggled(DBusWatch *watch, void *data) 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dbus_watch_get_enabled(watch)) 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt add_watch(watch, data); 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt remove_watch(watch, data); 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_timeout(void *eloop_ctx, void *sock_ctx) 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBusTimeout *timeout = sock_ctx; 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_timeout_handle(timeout); 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv = data; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dbus_timeout_get_enabled(timeout)) 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000, 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt process_timeout, priv, timeout); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_timeout_set_data(timeout, priv, NULL); 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return TRUE; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void remove_timeout(DBusTimeout *timeout, void *data) 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv = data; 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(process_timeout, priv, timeout); 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_timeout_set_data(timeout, NULL, NULL); 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void timeout_toggled(DBusTimeout *timeout, void *data) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dbus_timeout_get_enabled(timeout)) 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt add_timeout(timeout, data); 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt else 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt remove_timeout(timeout, data); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void process_wakeup_main(int sig, void *signal_ctx) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv = signal_ctx; 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (sig != SIGPOLL || !priv->con) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (dbus_connection_get_dispatch_status(priv->con) != 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBUS_DISPATCH_DATA_REMAINS) 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Only dispatch once - we do not want to starve other events */ 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_ref(priv->con); 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_dispatch(priv->con); 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_unref(priv->con); 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * wakeup_main - Attempt to wake our mainloop up 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: dbus control interface private data 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Try to wake up the main eloop so it will process 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * dbus events that may have happened. 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wakeup_main(void *data) 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv = data; 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Use SIGPOLL to break out of the eloop select() */ 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt raise(SIGPOLL); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->should_dispatch = 1; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * integrate_with_eloop - Register our mainloop integration with dbus 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @connection: connection to the system message bus 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @priv: a dbus control interface data structure 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int integrate_with_eloop(struct wpas_dbus_priv *priv) 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!dbus_connection_set_watch_functions(priv->con, add_watch, 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt remove_watch, watch_toggled, 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv, NULL) || 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !dbus_connection_set_timeout_functions(priv->con, add_timeout, 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt remove_timeout, 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt timeout_toggled, priv, 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL)) { 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "dbus: Failed to set callback " 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "functions"); 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eloop_register_signal(SIGPOLL, process_wakeup_main, priv)) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_set_wakeup_main_function(priv->con, wakeup_main, 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv, NULL); 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_dbus_init_common(struct wpas_dbus_priv *priv) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt DBusError error; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Get a reference to the system bus */ 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_error_init(&error); 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!priv->con) { 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "dbus: Could not acquire the system " 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "bus: %s - %s", error.name, error.message); 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_error_free(&error); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int wpas_dbus_init_common_finish(struct wpas_dbus_priv *priv) 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Tell dbus about our mainloop integration functions */ 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt integrate_with_eloop(priv); 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Dispatch initial DBus messages that may have come in since the bus 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * name was claimed above. Happens when clients are quick to notice the 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * service. 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * FIXME: is there a better solution to this problem? 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_register_timeout(0, 50, dispatch_initial_dbus_messages, 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->con, NULL); 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void wpas_dbus_deinit_common(struct wpas_dbus_priv *priv) 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv->con) { 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eloop_cancel_timeout(dispatch_initial_dbus_messages, 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->con, NULL); 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_set_watch_functions(priv->con, NULL, NULL, 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL, NULL); 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_set_timeout_functions(priv->con, NULL, NULL, 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt NULL, NULL, NULL); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt dbus_connection_unref(priv->con); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(priv); 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpas_dbus_priv * wpas_dbus_init(struct wpa_global *global) 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpas_dbus_priv *priv; 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv = os_zalloc(sizeof(*priv)); 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt priv->global = global; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_dbus_init_common(priv) < 0) { 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_deinit(priv); 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE_DBUS_NEW 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_dbus_ctrl_iface_init(priv) < 0) { 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_deinit(priv); 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE_DBUS 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpa_supplicant_dbus_ctrl_iface_init(priv) < 0) { 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_deinit(priv); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE_DBUS */ 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpas_dbus_init_common_finish(priv) < 0) { 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_deinit(priv); 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return priv; 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid wpas_dbus_deinit(struct wpas_dbus_priv *priv) 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (priv == NULL) 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE_DBUS_NEW 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_ctrl_iface_deinit(priv); 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#ifdef CONFIG_CTRL_IFACE_DBUS 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: is any deinit needed? */ 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#endif /* CONFIG_CTRL_IFACE_DBUS */ 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpas_dbus_deinit_common(priv); 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 372