1526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/* 2526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * WPA Supplicant / dbus-based control interface 3526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Copyright (c) 2006, Dan Williams <dcbw@redhat.com> and Red Hat, Inc. 4526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 5526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This program is free software; you can redistribute it and/or modify 6526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * it under the terms of the GNU General Public License version 2 as 7526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * published by the Free Software Foundation. 8526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 9526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Alternatively, this software may be distributed under the terms of BSD 10526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * license. 11526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 12526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * See README and COPYING for more details. 13526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 14526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 15526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "includes.h" 16526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 17526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "common.h" 18526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "eloop.h" 19526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "config.h" 20526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wpa_supplicant_i.h" 21526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "wps/wps.h" 22526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "ctrl_iface_dbus.h" 23526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#include "ctrl_iface_dbus_handlers.h" 24526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 25526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define _DBUS_VERSION (DBUS_VERSION_MAJOR << 8 | DBUS_VERSION_MINOR) 26526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define DBUS_VER(major, minor) ((major) << 8 | (minor)) 27526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 28526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#if _DBUS_VERSION < DBUS_VER(1,1) 29526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#define dbus_watch_get_unix_fd dbus_watch_get_fd 30526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif 31526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 32526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 33526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_dbus_priv { 34526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusConnection *con; 35526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int should_dispatch; 36526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global *global; 37526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 38526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 next_objid; 39526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt}; 40526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 41526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 42526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_watch(struct ctrl_iface_dbus_priv *iface, 43526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusWatch *watch, eloop_event_type type) 44526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 45526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_ref(iface->con); 46526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 47526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->should_dispatch = 0; 48526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 49526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (type == EVENT_TYPE_READ) 50526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_READABLE); 51526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (type == EVENT_TYPE_WRITE) 52526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_WRITABLE); 53526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (type == EVENT_TYPE_EXCEPTION) 54526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_watch_handle(watch, DBUS_WATCH_ERROR); 55526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 56526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface->should_dispatch) { 57526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (dbus_connection_get_dispatch_status(iface->con) == 58526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_DISPATCH_DATA_REMAINS) 59526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_dispatch(iface->con); 60526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->should_dispatch = 0; 61526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 62526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 63526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_unref(iface->con); 64526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 65526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 66526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 67526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_watch_exception(int sock, void *eloop_ctx, void *sock_ctx) 68526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 69526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_EXCEPTION); 70526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 71526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 72526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 73526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_watch_read(int sock, void *eloop_ctx, void *sock_ctx) 74526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 75526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_READ); 76526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 77526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 78526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 79526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_watch_write(int sock, void *eloop_ctx, void *sock_ctx) 80526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 81526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt process_watch(eloop_ctx, sock_ctx, EVENT_TYPE_WRITE); 82526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 83526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 84526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 85526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void connection_setup_add_watch(struct ctrl_iface_dbus_priv *iface, 86526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusWatch *watch) 87526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 88526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int flags; 89526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int fd; 90526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 91526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_watch_get_enabled(watch)) 92526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 93526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 94526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt flags = dbus_watch_get_flags(watch); 95526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fd = dbus_watch_get_unix_fd(watch); 96526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 97526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_EXCEPTION, process_watch_exception, 98526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface, watch); 99526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (flags & DBUS_WATCH_READABLE) { 101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_READ, process_watch_read, 102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface, watch); 103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (flags & DBUS_WATCH_WRITABLE) { 105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_sock(fd, EVENT_TYPE_WRITE, process_watch_write, 106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface, watch); 107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_watch_set_data(watch, iface, NULL); 110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void connection_setup_remove_watch(struct ctrl_iface_dbus_priv *iface, 114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusWatch *watch) 115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt unsigned int flags; 117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int fd; 118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt flags = dbus_watch_get_flags(watch); 120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt fd = dbus_watch_get_unix_fd(watch); 121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_EXCEPTION); 123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (flags & DBUS_WATCH_READABLE) 125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_READ); 126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (flags & DBUS_WATCH_WRITABLE) 127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_unregister_sock(fd, EVENT_TYPE_WRITE); 128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_watch_set_data(watch, NULL, NULL); 130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic dbus_bool_t add_watch(DBusWatch *watch, void *data) 134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt connection_setup_add_watch(data, watch); 136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return TRUE; 137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void remove_watch(DBusWatch *watch, void *data) 141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt connection_setup_remove_watch(data, watch); 143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void watch_toggled(DBusWatch *watch, void *data) 147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dbus_watch_get_enabled(watch)) 149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt add_watch(watch, data); 150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt remove_watch(watch, data); 152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_timeout(void *eloop_ctx, void *sock_ctx) 156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusTimeout *timeout = sock_ctx; 158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_timeout_handle(timeout); 160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void connection_setup_add_timeout(struct ctrl_iface_dbus_priv *iface, 164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusTimeout *timeout) 165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_timeout_get_enabled(timeout)) 167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_timeout(0, dbus_timeout_get_interval(timeout) * 1000, 170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt process_timeout, iface, timeout); 171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_timeout_set_data(timeout, iface, NULL); 173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void connection_setup_remove_timeout(struct ctrl_iface_dbus_priv *iface, 177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusTimeout *timeout) 178526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 179526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_cancel_timeout(process_timeout, iface, timeout); 180526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_timeout_set_data(timeout, NULL, NULL); 181526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 182526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 183526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 184526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic dbus_bool_t add_timeout(DBusTimeout *timeout, void *data) 185526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 186526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_timeout_get_enabled(timeout)) 187526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return TRUE; 188526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 189526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt connection_setup_add_timeout(data, timeout); 190526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 191526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return TRUE; 192526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 193526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 194526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 195526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void remove_timeout(DBusTimeout *timeout, void *data) 196526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 197526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt connection_setup_remove_timeout(data, timeout); 198526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 199526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 200526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 201526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void timeout_toggled(DBusTimeout *timeout, void *data) 202526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 203526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dbus_timeout_get_enabled(timeout)) 204526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt add_timeout(timeout, data); 205526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 206526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt remove_timeout(timeout, data); 207526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 208526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 209526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 210526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void process_wakeup_main(int sig, void *eloop_ctx, void *signal_ctx) 211526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 212526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface = signal_ctx; 213526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 214526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (sig != SIGPOLL || !iface->con) 215526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 216526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 217526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (dbus_connection_get_dispatch_status(iface->con) != 218526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_DISPATCH_DATA_REMAINS) 219526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 220526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 221526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Only dispatch once - we do not want to starve other events */ 222526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_ref(iface->con); 223526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_dispatch(iface->con); 224526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_unref(iface->con); 225526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 226526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 227526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 228526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 229526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wakeup_main - Attempt to wake our mainloop up 230526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @data: dbus control interface private data 231526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 232526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Try to wake up the main eloop so it will process 233526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * dbus events that may have happened. 234526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 235526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void wakeup_main(void *data) 236526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 237526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface = data; 238526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 239526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Use SIGPOLL to break out of the eloop select() */ 240526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt raise(SIGPOLL); 241526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->should_dispatch = 1; 242526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 243526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 244526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 245526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 246526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * connection_setup_wakeup_main - Tell dbus about our wakeup_main function 247526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iface: dbus control interface private data 248526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure 249526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 250526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Register our wakeup_main handler with dbus 251526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 252526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int connection_setup_wakeup_main(struct ctrl_iface_dbus_priv *iface) 253526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 254526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (eloop_register_signal(SIGPOLL, process_wakeup_main, iface)) 255526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 256526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 257526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_set_wakeup_main_function(iface->con, wakeup_main, 258526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface, NULL); 259526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 260526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 261526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 262526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 263526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 264526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 265526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_next_objid - Return next available object id 266526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iface: dbus control interface private data 267526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Object id 268526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 269526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtu32 wpa_supplicant_dbus_next_objid (struct ctrl_iface_dbus_priv *iface) 270526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 271526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return iface->next_objid++; 272526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 273526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 274526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 275526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 276526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_decompose_object_path - Decompose an interface object path into parts 277526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @path: The dbus object path 278526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @network: (out) the configured network this object path refers to, if any 279526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @bssid: (out) the scanned bssid this object path refers to, if any 280526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: The object path of the network interface this path refers to 281526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 282526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * For a given object path, decomposes the object path into object id, network, 283526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * and BSSID parts, if those parts exist. 284526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 285526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtchar * wpas_dbus_decompose_object_path(const char *path, char **network, 286526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char **bssid) 287526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 288526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const unsigned int dev_path_prefix_len = 289526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt strlen(WPAS_DBUS_PATH_INTERFACES "/"); 290526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *obj_path_only; 291526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *next_sep; 292526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 293526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Be a bit paranoid about path */ 294526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!path || strncmp(path, WPAS_DBUS_PATH_INTERFACES "/", 295526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dev_path_prefix_len)) 296526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 297526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 298526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Ensure there's something at the end of the path */ 299526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if ((path + dev_path_prefix_len)[0] == '\0') 300526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 301526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 302526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt obj_path_only = strdup(path); 303526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (obj_path_only == NULL) 304526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 305526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 306526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next_sep = strchr(obj_path_only + dev_path_prefix_len, '/'); 307526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (next_sep != NULL) { 308526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *net_part = strstr(next_sep, 309526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WPAS_DBUS_NETWORKS_PART "/"); 310526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *bssid_part = strstr(next_sep, 311526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WPAS_DBUS_BSSIDS_PART "/"); 312526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 313526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (network && net_part) { 314526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Deal with a request for a configured network */ 315526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *net_name = net_part + 316526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt strlen(WPAS_DBUS_NETWORKS_PART "/"); 317526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *network = NULL; 318526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(net_name)) 319526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *network = strdup(net_name); 320526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (bssid && bssid_part) { 321526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Deal with a request for a scanned BSSID */ 322526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *bssid_name = bssid_part + 323526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt strlen(WPAS_DBUS_BSSIDS_PART "/"); 324526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strlen(bssid_name)) 325526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *bssid = strdup(bssid_name); 326526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 327526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *bssid = NULL; 328526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 329526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 330526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Cut off interface object path before "/" */ 331526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt *next_sep = '\0'; 332526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 333526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 334526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return obj_path_only; 335526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 336526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 337526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 338526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 339526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_new_invalid_iface_error - Return a new invalid interface error message 340526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: Pointer to incoming dbus message this error refers to 341526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: A dbus error message 342526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 343526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Convenience function to create and return an invalid interface error 344526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 345526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtDBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message) 346526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 347526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return dbus_message_new_error(message, WPAS_ERROR_INVALID_IFACE, 348526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant knows nothing about " 349526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "this interface."); 350526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 351526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 352526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 353526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 354526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_new_invalid_network_error - Return a new invalid network error message 355526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: Pointer to incoming dbus message this error refers to 356526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: a dbus error message 357526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 358526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Convenience function to create and return an invalid network error 359526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 360526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry ShmidtDBusMessage * wpas_dbus_new_invalid_network_error(DBusMessage *message) 361526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 362526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return dbus_message_new_error(message, WPAS_ERROR_INVALID_NETWORK, 363526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "The requested network does not exist."); 364526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 365526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 366526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 367526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 368526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_new_invalid_bssid_error - Return a new invalid bssid error message 369526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: Pointer to incoming dbus message this error refers to 370526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: a dbus error message 371526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 372526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Convenience function to create and return an invalid bssid error 373526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 374526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DBusMessage * wpas_dbus_new_invalid_bssid_error(DBusMessage *message) 375526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 376526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return dbus_message_new_error(message, WPAS_ERROR_INVALID_BSSID, 377526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "The BSSID requested was invalid."); 378526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 379526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 380526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 381526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 382526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dispatch_network_method - dispatch messages for configured networks 383526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: the incoming dbus message 384526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: a network interface's data 385526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @network_id: id of the configured network we're interested in 386526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: a reply dbus message, or a dbus error message 387526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 388526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function dispatches all incoming dbus messages for configured networks. 389526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 390526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DBusMessage * wpas_dispatch_network_method(DBusMessage *message, 391526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s, 392526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int network_id) 393526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 394526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *reply = NULL; 395526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *method = dbus_message_get_member(message); 396526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_ssid *ssid; 397526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 398526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ssid = wpa_config_get_network(wpa_s->conf, network_id); 399526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ssid == NULL) 400526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpas_dbus_new_invalid_network_error(message); 401526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 402526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(method, "set")) 403526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_set_network(message, wpa_s, ssid); 404526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "enable")) 405526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_enable_network(message, wpa_s, ssid); 406526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "disable")) 407526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_disable_network(message, wpa_s, ssid); 408526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 409526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return reply; 410526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 411526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 412526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 413526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 414526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dispatch_bssid_method - dispatch messages for scanned networks 415526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: the incoming dbus message 416526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: a network interface's data 417526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @bssid: bssid of the scanned network we're interested in 418526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: a reply dbus message, or a dbus error message 419526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 420526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function dispatches all incoming dbus messages for scanned networks. 421526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 422526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DBusMessage * wpas_dispatch_bssid_method(DBusMessage *message, 423526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s, 424526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *bssid) 425526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 426526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *reply = NULL; 427526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *method = dbus_message_get_member(message); 428526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_scan_res *res = NULL; 429526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt size_t i; 430526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 431526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Ensure we actually have scan data */ 432526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s->scan_res == NULL && 433526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_get_scan_results(wpa_s) < 0) { 434526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_new_invalid_bssid_error(message); 435526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 436526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 437526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 438526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Find the bssid's scan data */ 439526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (i = 0; i < wpa_s->scan_res->num; i++) { 440526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_scan_res *search_res = wpa_s->scan_res->res[i]; 441526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char mac_str[18]; 442526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 443526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(mac_str, 0, sizeof(mac_str)); 444526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt snprintf(mac_str, sizeof(mac_str) - 1, WPAS_DBUS_BSSID_FORMAT, 445526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt MAC2STR(search_res->bssid)); 446526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(bssid, mac_str)) { 447526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt res = search_res; 448526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 449526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 450526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 451526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 452526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!res) { 453526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_new_invalid_bssid_error(message); 454526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 455526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 456526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 457526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Dispatch the method call against the scanned bssid */ 458526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(method, "properties")) 459526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_bssid_properties(message, wpa_s, res); 460526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 461526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtout: 462526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return reply; 463526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 464526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 465526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 466526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 467526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_iface_message_handler - Dispatch messages for interfaces or networks 468526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @connection: Connection to the system message bus 469526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: An incoming dbus message 470526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @user_data: A pointer to a dbus control interface data structure 471526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Whether or not the message was handled 472526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 473526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function dispatches all incoming dbus messages for network interfaces, 474526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * or objects owned by them, such as scanned BSSIDs and configured networks. 475526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 476526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection, 477526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *message, 478526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt void *user_data) 479526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 480526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s = user_data; 481526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *method = dbus_message_get_member(message); 482526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path = dbus_message_get_path(message); 483526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *msg_interface = dbus_message_get_interface(message); 484526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *iface_obj_path = NULL; 485526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *network = NULL; 486526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *bssid = NULL; 487526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *reply = NULL; 488526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 489526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Caller must specify a message interface */ 490526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!msg_interface) 491526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 492526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 493526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface_obj_path = wpas_dbus_decompose_object_path(path, &network, 494526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &bssid); 495526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface_obj_path == NULL) { 496526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_new_invalid_iface_error(message); 497526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 498526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 499526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 500526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Make sure the message's object path actually refers to the 501526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant structure it's supposed to (which is wpa_s) 502526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 503526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_supplicant_get_iface_by_dbus_path(wpa_s->global, 504526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface_obj_path) != wpa_s) { 505526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_new_invalid_iface_error(message); 506526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 507526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 508526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 509526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (network && !strcmp(msg_interface, WPAS_DBUS_IFACE_NETWORK)) { 510526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* A method for one of this interface's configured networks */ 511526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int nid = strtoul(network, NULL, 10); 512526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (errno != EINVAL) 513526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dispatch_network_method(message, wpa_s, 514526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt nid); 515526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else 516526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_new_invalid_network_error(message); 517526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (bssid && !strcmp(msg_interface, WPAS_DBUS_IFACE_BSSID)) { 518526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* A method for one of this interface's scanned BSSIDs */ 519526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dispatch_bssid_method(message, wpa_s, bssid); 520526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcmp(msg_interface, WPAS_DBUS_IFACE_INTERFACE)) { 521526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* A method for an interface only. */ 522526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(method, "scan")) 523526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_scan(message, wpa_s); 524526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "scanResults")) 525526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_scan_results(message, wpa_s); 526526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "addNetwork")) 527526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_add_network(message, wpa_s); 528526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "removeNetwork")) 529526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_remove_network(message, wpa_s); 530526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "selectNetwork")) 531526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_select_network(message, wpa_s); 532526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "capabilities")) 533526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_capabilities(message, wpa_s); 534526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "disconnect")) 535526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_disconnect(message, wpa_s); 536526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "setAPScan")) 537526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_set_ap_scan(message, wpa_s); 538526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "setSmartcardModules")) 539526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_set_smartcard_modules(message, 540526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_s); 541526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "state")) 542526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_get_state(message, wpa_s); 543dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt else if (!strcmp(method, "scanning")) 544dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt reply = wpas_dbus_iface_get_scanning(message, wpa_s); 545526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "setBlobs")) 546526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_set_blobs(message, wpa_s); 547526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt else if (!strcmp(method, "removeBlobs")) 548526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_iface_remove_blobs(message, wpa_s); 549526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 550526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 551526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* If the message was handled, send back the reply */ 552526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (reply) { 553526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_message_get_no_reply(message)) 554526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_send(connection, reply, NULL); 555526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_message_unref(reply); 556526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 557526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 558526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtout: 559526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(iface_obj_path); 560526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(network); 561526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(bssid); 562526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return reply ? DBUS_HANDLER_RESULT_HANDLED : 563526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 564526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 565526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 566526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 567526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 568526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_message_handler - dispatch incoming dbus messages 569526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @connection: connection to the system message bus 570526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @message: an incoming dbus message 571526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @user_data: a pointer to a dbus control interface data structure 572526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: whether or not the message was handled 573526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 574526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * This function dispatches all incoming dbus messages to the correct 575526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * handlers, depending on what the message's target object path is, 576526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * and what the method call is. 577526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 578526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic DBusHandlerResult wpas_message_handler(DBusConnection *connection, 579526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *message, void *user_data) 580526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 581526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *ctrl_iface = user_data; 582526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *method; 583526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path; 584526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *msg_interface; 585526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *reply = NULL; 586526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 587526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt method = dbus_message_get_member(message); 588526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = dbus_message_get_path(message); 589526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt msg_interface = dbus_message_get_interface(message); 590526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!method || !path || !ctrl_iface || !msg_interface) 591526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 592526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 593526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Validate the method interface */ 594526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(msg_interface, WPAS_DBUS_INTERFACE) != 0) 595526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 596526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 597526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(path, WPAS_DBUS_PATH)) { 598526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* dispatch methods against our global dbus interface here */ 599526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!strcmp(method, "addInterface")) { 600526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_global_add_interface( 601526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt message, ctrl_iface->global); 602526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcmp(method, "removeInterface")) { 603526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_global_remove_interface( 604526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt message, ctrl_iface->global); 605526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } else if (!strcmp(method, "getInterface")) { 606526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt reply = wpas_dbus_global_get_interface( 607526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt message, ctrl_iface->global); 608dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt } else if (!strcmp(method, "setDebugParams")) { 609dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt reply = wpas_dbus_global_set_debugparams( 610dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt message, ctrl_iface->global); 611526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 612526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 613526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 614526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* If the message was handled, send back the reply */ 615526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (reply) { 616526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_message_get_no_reply(message)) 617526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_send(connection, reply, NULL); 618526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_message_unref(reply); 619526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 620526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 621526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return reply ? DBUS_HANDLER_RESULT_HANDLED : 622526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 623526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 624526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 625526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 626526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 627526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_notify_scan_results - Send a scan results signal 628526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: %wpa_supplicant network interface data 629526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure 630526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 631526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Notify listeners that this interface has updated scan results. 632526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 633526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s) 634526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 635526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface = wpa_s->global->dbus_ctrl_iface; 636526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *_signal; 637526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path; 638526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 639526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Do nothing if the control interface is not turned on */ 640526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface == NULL) 641526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 642526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 643526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = wpa_supplicant_get_dbus_path(wpa_s); 644526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) { 645526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_scan_results[dbus]: " 646526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path"); 647526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 648526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_scan_results[dbus]: " 649526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path; can't send " 650526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "scan result signal."); 651526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 652526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 653526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, 654526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "ScanResultsAvailable"); 655526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (_signal == NULL) { 656526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_scan_results[dbus]: " 657526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't create dbus signal; likely out of memory"); 658526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "dbus control interface: not enough " 659526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "memory to send scan results signal."); 660526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 661526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 662526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_send(iface->con, _signal, NULL); 663526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_message_unref(_signal); 664526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 665526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 666526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 667526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 668526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_notify_state_change - Send a state change signal 669526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: %wpa_supplicant network interface data 670526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @new_state: new state wpa_supplicant is entering 671526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @old_state: old state wpa_supplicant is leaving 672526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure 673526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 674526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Notify listeners that wpa_supplicant has changed state 675526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 676526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s, 677526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_states new_state, 678526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_states old_state) 679526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 680526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface; 681526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *_signal = NULL; 682526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path; 683526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *new_state_str, *old_state_str; 684526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 685526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Do nothing if the control interface is not turned on */ 686526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s->global == NULL) 687526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 688526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface = wpa_s->global->dbus_ctrl_iface; 689526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface == NULL) 690526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 691526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 692526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Only send signal if state really changed */ 693526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (new_state == old_state) 694526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 695526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 696526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = wpa_supplicant_get_dbus_path(wpa_s); 697526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) { 698526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_state_change[dbus]: " 699526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path"); 700526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 701526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_state_change[dbus]: " 702526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path; can't send " 703526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "signal."); 704526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 705526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 706526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, 707526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "StateChange"); 708526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (_signal == NULL) { 709526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_state_change[dbus]: " 710526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't create dbus signal; likely out of memory"); 711526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 712526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_state_change[dbus]: " 713526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't create dbus signal; likely out of " 714526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "memory."); 715526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 716526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 717526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 718526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt new_state_str = wpa_supplicant_state_txt(new_state); 719526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt old_state_str = wpa_supplicant_state_txt(old_state); 720526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (new_state_str == NULL || old_state_str == NULL) { 721526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_state_change[dbus]: " 722526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't convert state strings"); 723526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 724526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_state_change[dbus]: " 725526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't convert state strings."); 726526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 727526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 728526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 729526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_message_append_args(_signal, 730526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_TYPE_STRING, &new_state_str, 731526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_TYPE_STRING, &old_state_str, 732526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_TYPE_INVALID)) { 733526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_state_change[dbus]: " 734526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "not enough memory to construct state change signal."); 735526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 736526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_state_change[dbus]: " 737526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "not enough memory to construct state change " 738526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "signal."); 739526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 740526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 741526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 742526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_send(iface->con, _signal, NULL); 743526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 744526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtout: 745526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_message_unref(_signal); 746526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 747526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 748526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 749dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt/** 750dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt * wpa_supplicant_dbus_notify_scanning - send scanning status 751dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt * @wpa_s: %wpa_supplicant network interface data 752dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt * Returns: 0 on success, -1 on failure 753dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt * 754dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt * Notify listeners of interface scanning state changes 755dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt */ 756dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidtvoid wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s) 757dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt{ 758dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt struct ctrl_iface_dbus_priv *iface = wpa_s->global->dbus_ctrl_iface; 759dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt DBusMessage *_signal; 760dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt const char *path; 761dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE; 762dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt 763dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt /* Do nothing if the control interface is not turned on */ 764dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt if (iface == NULL) 765dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt return; 766dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt 767dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt path = wpa_supplicant_get_dbus_path(wpa_s); 768dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt if (path == NULL) { 769dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface " 770dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "didn't have a dbus path"); 771dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt wpa_printf(MSG_ERROR, 772dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "%s[dbus]: interface didn't have a dbus path; " 773dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "can't send scanning signal.", __FUNCTION__); 774dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt return; 775dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt } 776dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, 777dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "Scanning"); 778dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt if (_signal == NULL) { 779dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't " 780dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "create dbus signal; likely out of memory"); 781dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt wpa_printf(MSG_ERROR, "%s[dbus]: dbus control interface: not " 782dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "enough memory to send scan results signal.", 783dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt __FUNCTION__); 784dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt return; 785dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt } 786dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt 787dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt if (dbus_message_append_args(_signal, 788dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt DBUS_TYPE_BOOLEAN, &scanning, 789dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt DBUS_TYPE_INVALID)) { 790dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt dbus_connection_send(iface->con, _signal, NULL); 791dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt } else { 792dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough " 793dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "memory to construct signal."); 794dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt wpa_printf(MSG_ERROR, "%s[dbus]: not enough memory to " 795dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt "construct signal.", __FUNCTION__); 796dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt } 797dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt dbus_message_unref(_signal); 798dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt} 799dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt 800dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt 801526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#ifdef CONFIG_WPS 802526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, 803526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const struct wps_credential *cred) 804526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 805526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface; 806526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusMessage *_signal = NULL; 807526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path; 808526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 809526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Do nothing if the control interface is not turned on */ 810526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s->global == NULL) 811526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 812526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface = wpa_s->global->dbus_ctrl_iface; 813526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface == NULL) 814526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 815526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 816526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = wpa_supplicant_get_dbus_path(wpa_s); 817526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) { 818526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " 819526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path"); 820526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 821526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_wps_cred[dbus]: " 822526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "interface didn't have a dbus path; can't send " 823526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "signal."); 824526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 825526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 826526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE, 827526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "WpsCred"); 828526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (_signal == NULL) { 829526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " 830526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't create dbus signal; likely out of memory"); 831526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 832526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_wps_cred[dbus]: " 833526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "couldn't create dbus signal; likely out of " 834526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "memory."); 835526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 836526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 837526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 838526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_message_append_args(_signal, 839526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 840526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt &cred->cred_attr, cred->cred_attr_len, 841526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_TYPE_INVALID)) { 842526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpa_supplicant_dbus_notify_wps_cred[dbus]: " 843526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "not enough memory to construct signal."); 844526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, 845526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "wpa_supplicant_dbus_notify_wps_cred[dbus]: " 846526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "not enough memory to construct signal."); 847526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 848526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 849526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 850526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_send(iface->con, _signal, NULL); 851526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 852526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtout: 853526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_message_unref(_signal); 854526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 855dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt#else /* CONFIG_WPS */ 856dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidtvoid wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s, 857dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt const struct wps_credential *cred) 858dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt{ 859dde787cc314cd04caa4ea5f031cc8a02495ca513Dmitry Shmidt} 860526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt#endif /* CONFIG_WPS */ 861526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 862526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 863526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 864526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * integrate_with_eloop - Register our mainloop integration with dbus 865526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @connection: connection to the system message bus 866526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iface: a dbus control interface data structure 867526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure 868526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 869526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * We register our mainloop integration functions with dbus here. 870526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 871526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic int integrate_with_eloop(DBusConnection *connection, 872526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface) 873526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 874526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_connection_set_watch_functions(connection, add_watch, 875526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt remove_watch, watch_toggled, 876526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface, NULL)) { 877526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_connection_set_watch_functions[dbus]"); 878526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Not enough memory to set up dbus."); 879526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 880526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 881526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 882526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_connection_set_timeout_functions(connection, add_timeout, 883526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt remove_timeout, 884526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt timeout_toggled, iface, 885526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL)) { 886526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_connection_set_timeout_functions[dbus]"); 887526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Not enough memory to set up dbus."); 888526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 889526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 890526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 891526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (connection_setup_wakeup_main(iface) < 0) { 892526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("connection_setup_wakeup_main[dbus]"); 893526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not setup main wakeup function."); 894526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 895526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 896526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 897526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 898526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 899526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 900526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 901526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 902526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * dispatch_initial_dbus_messages - Dispatch initial dbus messages after 903526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * claiming bus name 904526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @eloop_ctx: the DBusConnection to dispatch on 905526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @timeout_ctx: unused 906526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 907526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * If clients are quick to notice that wpa_supplicant claimed its bus name, 908526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * there may have been messages that came in before initialization was 909526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * all finished. Dispatch those here. 910526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 911526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstatic void dispatch_initial_dbus_messages(void *eloop_ctx, void *timeout_ctx) 912526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 913526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusConnection *con = eloop_ctx; 914526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 915526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt while (dbus_connection_get_dispatch_status(con) == 916526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBUS_DISPATCH_DATA_REMAINS) 917526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_dispatch(con); 918526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 919526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 920526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 921526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 922526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_ctrl_iface_init - Initialize dbus control interface 923526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 924526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Pointer to dbus_ctrl_iface date or %NULL on failure 925526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 926526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Initialize the dbus control interface and start receiving commands from 927526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * external programs over the bus. 928526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 929526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct ctrl_iface_dbus_priv * 930526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtwpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global) 931526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 932526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *iface; 933526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusError error; 934526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = -1; 935526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusObjectPathVTable wpas_vtable = { 936526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, &wpas_message_handler, NULL, NULL, NULL, NULL 937526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 938526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 939526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface = os_zalloc(sizeof(struct ctrl_iface_dbus_priv)); 940526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface == NULL) 941526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 942526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 943526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->global = global; 944526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 945526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Get a reference to the system bus */ 946526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_error_init(&error); 947526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->con = dbus_bus_get(DBUS_BUS_SYSTEM, &error); 948526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_error_free(&error); 949526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!iface->con) { 950526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_bus_get[ctrl_iface_dbus]"); 951526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not acquire the system bus."); 952526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 953526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 954526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 955526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Tell dbus about our mainloop integration functions */ 956526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (integrate_with_eloop(iface->con, iface)) 957526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 958526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 959526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Register the message handler for the global dbus interface */ 960526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_connection_register_object_path(iface->con, 961526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WPAS_DBUS_PATH, &wpas_vtable, 962526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface)) { 963526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_connection_register_object_path[dbus]"); 964526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not set up DBus message " 965526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "handler."); 966526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 967526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 968526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 969526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Register our service with the message bus */ 970526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_error_init(&error); 971526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt switch (dbus_bus_request_name(iface->con, WPAS_DBUS_SERVICE, 972526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 0, &error)) { 973526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: 974526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = 0; 975526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 976526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case DBUS_REQUEST_NAME_REPLY_EXISTS: 977526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case DBUS_REQUEST_NAME_REPLY_IN_QUEUE: 978526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER: 979526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_bus_request_name[dbus]"); 980526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not request DBus service name: " 981526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "already registered."); 982526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 983526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt default: 984526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("dbus_bus_request_name[dbus]"); 985526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not request DBus service name: " 986526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "%s %s.", error.name, error.message); 987526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt break; 988526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 989526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_error_free(&error); 990526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 991526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ret != 0) 992526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto fail; 993526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 994526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, "Providing DBus service '" WPAS_DBUS_SERVICE 995526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "'."); 996526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 997526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* 998526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Dispatch initial DBus messages that may have come in since the bus 999526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * name was claimed above. Happens when clients are quick to notice the 1000526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant service. 1001526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1002526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * FIXME: is there a better solution to this problem? 1003526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1004526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_register_timeout(0, 50, dispatch_initial_dbus_messages, 1005526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->con, NULL); 1006526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1007526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return iface; 1008526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1009526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtfail: 1010526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_supplicant_dbus_ctrl_iface_deinit(iface); 1011526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1012526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1013526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1014526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1015526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1016526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_ctrl_iface_deinit - Deinitialize dbus ctrl interface 1017526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @iface: Pointer to dbus private data from 1018526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_ctrl_iface_init() 1019526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1020526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Deinitialize the dbus control interface that was initialized with 1021526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_dbus_ctrl_iface_init(). 1022526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1023526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtvoid wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface) 1024526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1025526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface == NULL) 1026526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return; 1027526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1028526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (iface->con) { 1029526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt eloop_cancel_timeout(dispatch_initial_dbus_messages, 1030526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt iface->con, NULL); 1031526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_set_watch_functions(iface->con, NULL, NULL, 1032526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, NULL, NULL); 1033526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_set_timeout_functions(iface->con, NULL, NULL, 1034526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, NULL, NULL); 1035526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt dbus_connection_unref(iface->con); 1036526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1037526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1038526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt memset(iface, 0, sizeof(struct ctrl_iface_dbus_priv)); 1039526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(iface); 1040526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1041526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1042526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1043526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1044526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_register_new_iface - Register a new interface with dbus 1045526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: %wpa_supplicant interface description structure to register 1046526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on error 1047526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1048526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Registers a new interface with dbus and assigns it a dbus object path. 1049526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1050526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wpas_dbus_register_iface(struct wpa_supplicant *wpa_s) 1051526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1052526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *ctrl_iface = 1053526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_s->global->dbus_ctrl_iface; 1054526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusConnection * con; 1055526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 next; 1056526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusObjectPathVTable vtable = { 1057526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt NULL, &wpas_iface_message_handler, NULL, NULL, NULL, NULL 1058526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt }; 1059526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt char *path; 1060526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt int ret = -1; 1061526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1062526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Do nothing if the control interface is not turned on */ 1063526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_iface == NULL) 1064526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1065526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1066526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt con = ctrl_iface->con; 1067526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next = wpa_supplicant_dbus_next_objid(ctrl_iface); 1068526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1069526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Create and set the interface's object path */ 1070526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = os_zalloc(WPAS_DBUS_OBJECT_PATH_MAX); 1071526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (path == NULL) 1072526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1073526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt snprintf(path, WPAS_DBUS_OBJECT_PATH_MAX, 1074526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt WPAS_DBUS_PATH_INTERFACES "/%u", 1075526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt next); 1076526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_supplicant_set_dbus_path(wpa_s, path)) { 1077526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_DEBUG, 1078526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "Failed to set dbus path for interface %s", 1079526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_s->ifname); 1080526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 1081526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1082526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1083526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Register the message handler for the interface functions */ 1084526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_connection_register_fallback(con, path, &vtable, wpa_s)) { 1085526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt perror("wpas_dbus_register_iface [dbus]"); 1086526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_printf(MSG_ERROR, "Could not set up DBus message " 1087526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt "handler for interface %s.", wpa_s->ifname); 1088526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt goto out; 1089526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1090526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ret = 0; 1091526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1092526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtout: 1093526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(path); 1094526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return ret; 1095526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1096526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1097526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1098526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1099526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpas_dbus_unregister_iface - Unregister an interface from dbus 1100526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: wpa_supplicant interface structure 1101526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on success, -1 on failure 1102526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * 1103526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Unregisters the interface with dbus 1104526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1105526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wpas_dbus_unregister_iface(struct wpa_supplicant *wpa_s) 1106526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1107526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct ctrl_iface_dbus_priv *ctrl_iface; 1108526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt DBusConnection *con; 1109526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path; 1110526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1111526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt /* Do nothing if the control interface is not turned on */ 1112526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s == NULL || wpa_s->global == NULL) 1113526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1114526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt ctrl_iface = wpa_s->global->dbus_ctrl_iface; 1115526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (ctrl_iface == NULL) 1116526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1117526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1118526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt con = ctrl_iface->con; 1119526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt path = wpa_supplicant_get_dbus_path(wpa_s); 1120526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1121526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (!dbus_connection_unregister_object_path(con, path)) 1122526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1123526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1124526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt free(wpa_s->dbus_path); 1125526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_s->dbus_path = NULL; 1126526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1127526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1128526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1129526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1130526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1131526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1132526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_get_iface_by_dbus_path - Get a new network interface 1133526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @global: Pointer to global data from wpa_supplicant_init() 1134526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @path: Pointer to a dbus object path representing an interface 1135526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Pointer to the interface or %NULL if not found 1136526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1137526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtstruct wpa_supplicant * wpa_supplicant_get_iface_by_dbus_path( 1138526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_global *global, const char *path) 1139526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1140526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt struct wpa_supplicant *wpa_s; 1141526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1142526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { 1143526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (strcmp(wpa_s->dbus_path, path) == 0) 1144526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_s; 1145526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt } 1146526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return NULL; 1147526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1148526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1149526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1150526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1151526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_set_dbus_path - Assign a dbus path to an interface 1152526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: wpa_supplicant interface structure 1153526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @path: dbus path to set on the interface 1154526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: 0 on succes, -1 on error 1155526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1156526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtint wpa_supplicant_set_dbus_path(struct wpa_supplicant *wpa_s, 1157526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt const char *path) 1158526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1159526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt u32 len = strlen (path); 1160526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (len >= WPAS_DBUS_OBJECT_PATH_MAX) 1161526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1162526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt if (wpa_s->dbus_path) 1163526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return -1; 1164526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt wpa_s->dbus_path = strdup(path); 1165526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return 0; 1166526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1167526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1168526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt 1169526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt/** 1170526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * wpa_supplicant_get_dbus_path - Get an interface's dbus path 1171526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * @wpa_s: %wpa_supplicant interface structure 1172526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt * Returns: Interface's dbus object path, or %NULL on error 1173526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt */ 1174526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidtconst char * wpa_supplicant_get_dbus_path(struct wpa_supplicant *wpa_s) 1175526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt{ 1176526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt return wpa_s->dbus_path; 1177526fc2a7dc09b4450086cdec313a5c44d36b10fdDmitry Shmidt} 1178