dbus: add 'scanning' property
authorDan Williams <dcbw@redhat.com>
Wed, 27 May 2009 18:06:40 +0000 (21:06 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 27 May 2009 18:06:40 +0000 (21:06 +0300)
When the supplicant is connected and performs a scan, it doesn't enter
WPA_SCANNING state for various reasons.  However, external programs
still need to know that the supplicant is scanning since they may not
wish to perform certain operations during a scan (as those operations
will likely fail or yield incorrect results).  Add a 'scanning' property
and signal to the supplicant dbus interface to allow clients to
synchronize better with the supplicant when it scans.

Signed-off-by: Dan Williams <dcbw@redhat.com>

wpa_supplicant/ctrl_iface_dbus.c
wpa_supplicant/ctrl_iface_dbus.h
wpa_supplicant/ctrl_iface_dbus_handlers.c
wpa_supplicant/ctrl_iface_dbus_handlers.h
wpa_supplicant/events.c
wpa_supplicant/scan.c
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index 26a3e9d..572f262 100644 (file)
@@ -541,6 +541,8 @@ static DBusHandlerResult wpas_iface_message_handler(DBusConnection *connection,
                                                                      wpa_s);
                else if (!strcmp(method, "state"))
                        reply = wpas_dbus_iface_get_state(message, wpa_s);
+               else if (!strcmp(method, "scanning"))
+                       reply = wpas_dbus_iface_get_scanning(message, wpa_s);
                else if (!strcmp(method, "setBlobs"))
                        reply = wpas_dbus_iface_set_blobs(message, wpa_s);
                else if (!strcmp(method, "removeBlobs"))
@@ -753,6 +755,58 @@ out:
 }
 
 
+/**
+ * wpa_supplicant_dbus_notify_scanning - send scanning status
+ * @wpa_s: %wpa_supplicant network interface data
+ * Returns: 0 on success, -1 on failure
+ *
+ * Notify listeners of interface scanning state changes
+ */
+void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
+{
+       struct ctrl_iface_dbus_priv *iface = wpa_s->global->dbus_ctrl_iface;
+       DBusMessage *_signal;
+       const char *path;
+       dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
+
+       /* Do nothing if the control interface is not turned on */
+       if (iface == NULL)
+               return;
+
+       path = wpa_supplicant_get_dbus_path(wpa_s);
+       if (path == NULL) {
+               perror("wpa_supplicant_dbus_notify_scanning[dbus]: interface "
+                      "didn't have a dbus path");
+               wpa_printf(MSG_ERROR,
+                          "%s[dbus]: interface didn't have a dbus path; "
+                          "can't send scanning signal.", __FUNCTION__);
+               return;
+       }
+       _signal = dbus_message_new_signal(path, WPAS_DBUS_IFACE_INTERFACE,
+                                         "Scanning");
+       if (_signal == NULL) {
+               perror("wpa_supplicant_dbus_notify_scanning[dbus]: couldn't "
+                      "create dbus signal; likely out of memory");
+               wpa_printf(MSG_ERROR, "%s[dbus]: dbus control interface: not "
+                          "enough memory to send scan results signal.",
+                          __FUNCTION__);
+               return;
+       }
+
+       if (dbus_message_append_args(_signal,
+                                    DBUS_TYPE_BOOLEAN, &scanning,
+                                    DBUS_TYPE_INVALID)) {
+               dbus_connection_send(iface->con, _signal, NULL);
+       } else {
+               perror("wpa_supplicant_dbus_notify_scanning[dbus]: not enough "
+                      "memory to construct signal.");
+               wpa_printf(MSG_ERROR, "%s[dbus]: not enough memory to "
+                          "construct signal.", __FUNCTION__);
+       }
+       dbus_message_unref(_signal);
+}
+
+
 #ifdef CONFIG_WPS
 void wpa_supplicant_dbus_notify_wps_cred(struct wpa_supplicant *wpa_s,
                                         const struct wps_credential *cred)
index 8e9036d..0e3ec79 100644 (file)
@@ -92,6 +92,7 @@ struct ctrl_iface_dbus_priv *
 wpa_supplicant_dbus_ctrl_iface_init(struct wpa_global *global);
 void wpa_supplicant_dbus_ctrl_iface_deinit(struct ctrl_iface_dbus_priv *iface);
 void wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s);
+void wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
                                             wpa_states new_state,
                                             wpa_states old_state);
@@ -136,6 +137,11 @@ wpa_supplicant_dbus_notify_scan_results(struct wpa_supplicant *wpa_s)
 }
 
 static inline void
+wpa_supplicant_dbus_notify_scanning(struct wpa_supplicant *wpa_s)
+{
+}
+
+static inline void
 wpa_supplicant_dbus_notify_state_change(struct wpa_supplicant *wpa_s,
                                        wpa_states new_state,
                                        wpa_states old_state)
index e9dd9a5..53a1846 100644 (file)
@@ -1338,6 +1338,35 @@ DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
 
 
 /**
+ * wpas_dbus_iface_get_scanning - Get interface scanning state
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: A dbus message containing whether the interface is scanning
+ *
+ * Handler function for "scanning" method call.
+ */
+DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
+                                          struct wpa_supplicant *wpa_s)
+{
+       DBusMessage *reply = NULL;
+       dbus_bool_t scanning = wpa_s->scanning ? TRUE : FALSE;
+
+       reply = dbus_message_new_method_return(message);
+       if (reply != NULL) {
+               dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &scanning,
+                                        DBUS_TYPE_INVALID);
+       } else {
+               perror("wpas_dbus_iface_get_scanning[dbus]: out of "
+                      "memory.");
+               wpa_printf(MSG_ERROR, "dbus control interface: not enough "
+                          "memory to return scanning state.");
+       }
+
+       return reply;
+}
+
+
+/**
  * wpas_dbus_iface_set_blobs - Store named binary blobs (ie, for certificates)
  * @message: Pointer to incoming dbus message
  * @wpa_s: %wpa_supplicant data structure
index 0df5f3e..6564b54 100644 (file)
@@ -77,6 +77,9 @@ DBusMessage * wpas_dbus_iface_set_smartcard_modules(
 DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message,
                                        struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message,
+                                          struct wpa_supplicant *wpa_s);
+
 DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message,
                                        struct wpa_supplicant *wpa_s);
 
index 56c57fb..159b024 100644 (file)
@@ -615,6 +615,8 @@ static void wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s)
        struct wpa_scan_res *selected = NULL;
        struct wpa_ssid *ssid = NULL;
 
+       wpa_supplicant_notify_scanning(wpa_s, 0);
+
        if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
                if (wpa_s->conf->ap_scan == 2)
                        return;
index 1f53e23..50e81e3 100644 (file)
@@ -21,6 +21,7 @@
 #include "driver_i.h"
 #include "mlme.h"
 #include "wps_supplicant.h"
+#include "ctrl_iface_dbus.h"
 
 
 static void wpa_supplicant_gen_assoc_event(struct wpa_supplicant *wpa_s)
@@ -328,6 +329,8 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
        }
 #endif /* CONFIG_WPS */
 
+       wpa_supplicant_notify_scanning(wpa_s, 1);
+
        if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_USER_SPACE_MLME) {
                ieee80211_sta_set_probe_req_ie(wpa_s, params.extra_ies,
                                               params.extra_ies_len);
@@ -344,6 +347,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
 
        if (ret) {
                wpa_printf(MSG_WARNING, "Failed to initiate AP scan.");
+               wpa_supplicant_notify_scanning(wpa_s, 0);
                wpa_supplicant_req_scan(wpa_s, 10, 0);
        } else
                wpa_s->scan_runs++;
@@ -402,3 +406,14 @@ void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s)
        wpa_msg(wpa_s, MSG_DEBUG, "Cancelling scan request");
        eloop_cancel_timeout(wpa_supplicant_scan, wpa_s, NULL);
 }
+
+
+void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
+                                   int scanning)
+{
+       if (wpa_s->scanning != scanning) {
+               wpa_s->scanning = scanning;
+               wpa_supplicant_dbus_notify_scanning(wpa_s);
+       }
+}
+
index 723e2ed..d03e9da 100644 (file)
@@ -511,6 +511,9 @@ void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state)
                   wpa_supplicant_state_txt(wpa_s->wpa_state),
                   wpa_supplicant_state_txt(state));
 
+       if (state != WPA_SCANNING)
+               wpa_supplicant_notify_scanning(wpa_s, 0);
+
        wpa_supplicant_dbus_notify_state_change(wpa_s, state,
                                                wpa_s->wpa_state);
 
index 8d131fc..63984d8 100644 (file)
@@ -329,6 +329,7 @@ struct wpa_supplicant {
        struct ctrl_iface_priv *ctrl_iface;
 
        wpa_states wpa_state;
+       int scanning;
        int new_connection;
        int reassociated_connection;
 
@@ -431,6 +432,8 @@ int wpa_supplicant_scard_init(struct wpa_supplicant *wpa_s,
 /* scan.c */
 void wpa_supplicant_req_scan(struct wpa_supplicant *wpa_s, int sec, int usec);
 void wpa_supplicant_cancel_scan(struct wpa_supplicant *wpa_s);
+void wpa_supplicant_notify_scanning(struct wpa_supplicant *wpa_s,
+                                   int scanning);
 
 /* events.c */
 void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s);