[PATCH] dbus: add SignalPoll() method to report current signal properties

Dan Williams dcbw at redhat.com
Mon Aug 18 16:00:36 EDT 2014


Analagous to the control interface's SIGNAL_POLL request.

Signed-hostap: Dan Williams <dcbw at redhat.com>
---
Example:

$ sudo dbus-send --system --print-reply --dest=fi.w1.wpa_supplicant1 /fi/w1/wpa_supplicant1/Interfaces/1 fi.w1.wpa_supplicant1.Interface.SignalPoll
method return sender=:1.268 -> dest=:1.273 reply_serial=2
   variant       array [
         dict entry(
            string "rssi"
            variant                int32 -47
         )
         dict entry(
            string "linkspeed"
            variant                int32 54
         )
         dict entry(
            string "noise"
            variant                int32 9999
         )
         dict entry(
            string "frequency"
            variant                uint32 2462
         )
         dict entry(
            string "width"
            variant                string "20 MHz (no HT)"
         )
         dict entry(
            string "avg-rssi"
            variant                int32 -42
         )
      ]

 wpa_supplicant/ctrl_iface.c             | 24 +---------
 wpa_supplicant/dbus/dbus_new.c          |  7 +++
 wpa_supplicant/dbus/dbus_new_handlers.c | 81 +++++++++++++++++++++++++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.h |  3 ++
 wpa_supplicant/wpas_glue.c              | 21 +++++++++
 wpa_supplicant/wpas_glue.h              |  3 ++
 6 files changed, 116 insertions(+), 23 deletions(-)

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 9970597..fe31805 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -37,14 +37,15 @@
 #include "scan.h"
 #include "ctrl_iface.h"
 #include "interworking.h"
 #include "blacklist.h"
 #include "autoscan.h"
 #include "wnm_sta.h"
 #include "offchannel.h"
+#include "wpas_glue.h"
 
 static int wpa_supplicant_global_iface_list(struct wpa_global *global,
 					    char *buf, int len);
 static int wpa_supplicant_global_iface_interfaces(struct wpa_global *global,
 						  char *buf, int len);
 static int * freq_range_to_channel_list(struct wpa_supplicant *wpa_s,
 					char *val);
@@ -5448,37 +5449,14 @@ static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd
 		   query_reason);
 
 	return wnm_send_bss_transition_mgmt_query(wpa_s, query_reason);
 }
 
 #endif /* CONFIG_WNM */
 
-
-/* Get string representation of channel width */
-static const char * channel_width_name(enum chan_width width)
-{
-	switch (width) {
-	case CHAN_WIDTH_20_NOHT:
-		return "20 MHz (no HT)";
-	case CHAN_WIDTH_20:
-		return "20 MHz";
-	case CHAN_WIDTH_40:
-		return "40 MHz";
-	case CHAN_WIDTH_80:
-		return "80 MHz";
-	case CHAN_WIDTH_80P80:
-		return "80+80 MHz";
-	case CHAN_WIDTH_160:
-		return "160 MHz";
-	default:
-		return "unknown";
-	}
-}
-
-
 static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf,
 				      size_t buflen)
 {
 	struct wpa_signal_info si;
 	int ret;
 	char *pos, *end;
 
diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c
index aab2225..7cee614 100644
--- a/wpa_supplicant/dbus/dbus_new.c
+++ b/wpa_supplicant/dbus/dbus_new.c
@@ -2433,14 +2433,21 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
 	{ "Scan", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) &wpas_dbus_handler_scan,
 	  {
 		  { "args", "a{sv}", ARG_IN },
 		  END_ARGS
 	  }
 	},
+	{ "SignalPoll", WPAS_DBUS_NEW_IFACE_INTERFACE,
+	  (WPADBusMethodHandler) &wpas_dbus_handler_signal_poll,
+	  {
+		  { "args", "a{sv}", ARG_OUT },
+		  END_ARGS
+	  }
+	},
 	{ "Disconnect", WPAS_DBUS_NEW_IFACE_INTERFACE,
 	  (WPADBusMethodHandler) &wpas_dbus_handler_disconnect,
 	  {
 		  END_ARGS
 	  }
 	},
 	{ "AddNetwork", WPAS_DBUS_NEW_IFACE_INTERFACE,
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index bd38d65..a9c65cc 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -23,14 +23,15 @@
 #include "../scan.h"
 #include "../autoscan.h"
 #include "dbus_new_helpers.h"
 #include "dbus_new.h"
 #include "dbus_new_handlers.h"
 #include "dbus_dict_helpers.h"
 #include "dbus_common_i.h"
+#include "../wpas_glue.h"
 
 static const char *debug_strings[] = {
 	"excessive", "msgdump", "debug", "info", "warning", "error", NULL
 };
 
 
 /**
@@ -1386,14 +1387,94 @@ out:
 	for (i = 0; i < WPAS_MAX_SCAN_SSIDS; i++)
 		os_free((u8 *) params.ssids[i].ssid);
 	os_free((u8 *) params.extra_ies);
 	os_free(params.freqs);
 	return reply;
 }
 
+/**
+ * wpas_dbus_handler_signal_poll - Request immediate signal properties
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "SignalPoll" method call of a network device. Requests
+ * that wpa_supplicant read signal properties like RSSI, noise, and link
+ * speed and return them.
+ */
+DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s)
+{
+	struct wpa_signal_info si;
+	DBusMessage *reply = NULL;
+	DBusMessageIter iter, iter_dict, variant_iter;
+	int ret;
+
+	ret = wpa_drv_signal_poll(wpa_s, &si);
+	if (ret) {
+		return dbus_message_new_error(message, DBUS_ERROR_FAILED,
+					      "Failed to read signal");
+	}
+
+	reply = dbus_message_new_method_return(message);
+	if (reply == NULL)
+		goto nomem;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT,
+					      "a{sv}", &variant_iter))
+		goto nomem;
+	if (!wpa_dbus_dict_open_write(&variant_iter, &iter_dict))
+		goto nomem;
+
+	if (!wpa_dbus_dict_append_int32(&iter_dict, "rssi", si.current_signal))
+		goto nomem;
+	if (!wpa_dbus_dict_append_int32(&iter_dict, "linkspeed",
+					si.current_txrate / 1000))
+		goto nomem;
+	if (!wpa_dbus_dict_append_int32(&iter_dict, "noise", si.current_noise))
+		goto nomem;
+	if (!wpa_dbus_dict_append_uint32(&iter_dict, "frequency", si.frequency))
+		goto nomem;
+
+	if (si.chanwidth != CHAN_WIDTH_UNKNOWN) {
+		if (!wpa_dbus_dict_append_string(&iter_dict, "width",
+					channel_width_name(si.chanwidth)))
+			goto nomem;
+	}
+
+	if (si.center_frq1 > 0 && si.center_frq2 > 0) {
+		if (!wpa_dbus_dict_append_int32(&iter_dict, "center-frq1",
+						si.center_frq1))
+			goto nomem;
+		if (!wpa_dbus_dict_append_int32(&iter_dict, "center-frq2",
+						si.center_frq2))
+			goto nomem;
+	}
+
+	if (si.avg_signal) {
+		if (!wpa_dbus_dict_append_int32(&iter_dict, "avg-rssi",
+						si.avg_signal))
+			goto nomem;
+	}
+
+	if (!wpa_dbus_dict_close_write(&variant_iter, &iter_dict))
+		goto nomem;
+	if (!dbus_message_iter_close_container(&iter, &variant_iter))
+		goto nomem;
+
+	return reply;
+
+nomem:
+	if (reply)
+		dbus_message_unref(reply);
+	reply = dbus_message_new_error(message, DBUS_ERROR_NO_MEMORY, NULL);
+	return reply;
+}
 
 /*
  * wpas_dbus_handler_disconnect - Terminate the current connection
  * @message: Pointer to incoming dbus message
  * @wpa_s: wpa_supplicant structure for a network interface
  * Returns: NotConnected DBus error message if already not connected
  * or NULL otherwise.
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h
index 461970d..f00eb88 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.h
+++ b/wpa_supplicant/dbus/dbus_new_handlers.h
@@ -83,14 +83,17 @@ dbus_bool_t wpas_dbus_getter_eap_methods(DBusMessageIter *iter,
 dbus_bool_t wpas_dbus_getter_global_capabilities(DBusMessageIter *iter,
 						 DBusError *error,
 						 void *user_data);
 
 DBusMessage * wpas_dbus_handler_scan(DBusMessage *message,
 				     struct wpa_supplicant *wpa_s);
 
+DBusMessage * wpas_dbus_handler_signal_poll(DBusMessage *message,
+					    struct wpa_supplicant *wpa_s);
+
 DBusMessage * wpas_dbus_handler_disconnect(DBusMessage *message,
 					   struct wpa_supplicant *wpa_s);
 
 dbus_bool_t set_network_properties(struct wpa_supplicant *wpa_s,
 				   struct wpa_ssid *ssid,
 				   DBusMessageIter *iter,
 				   DBusError *error);
diff --git a/wpa_supplicant/wpas_glue.c b/wpa_supplicant/wpas_glue.c
index 350b122..b77e5d3 100644
--- a/wpa_supplicant/wpas_glue.c
+++ b/wpa_supplicant/wpas_glue.c
@@ -966,7 +966,28 @@ void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
 				wpabuf_free(p2p);
 			}
 		}
 #endif /* CONFIG_P2P */
 	}
 	wpa_sm_set_config(wpa_s->wpa, ssid ? &conf : NULL);
 }
+
+/* Get string representation of channel width */
+const char * channel_width_name(enum chan_width width)
+{
+	switch (width) {
+	case CHAN_WIDTH_20_NOHT:
+		return "20 MHz (no HT)";
+	case CHAN_WIDTH_20:
+		return "20 MHz";
+	case CHAN_WIDTH_40:
+		return "40 MHz";
+	case CHAN_WIDTH_80:
+		return "80 MHz";
+	case CHAN_WIDTH_80P80:
+		return "80+80 MHz";
+	case CHAN_WIDTH_160:
+		return "160 MHz";
+	default:
+		return "unknown";
+	}
+}
diff --git a/wpa_supplicant/wpas_glue.h b/wpa_supplicant/wpas_glue.h
index 9808c22..8dd99ff 100644
--- a/wpa_supplicant/wpas_glue.h
+++ b/wpa_supplicant/wpas_glue.h
@@ -6,20 +6,23 @@
  * See README for more details.
  */
 
 #ifndef WPAS_GLUE_H
 #define WPAS_GLUE_H
 
 enum wpa_ctrl_req_type;
+enum chan_width;
 
 int wpa_supplicant_init_eapol(struct wpa_supplicant *wpa_s);
 int wpa_supplicant_init_wpa(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_rsn_supp_set_config(struct wpa_supplicant *wpa_s,
 					struct wpa_ssid *ssid);
 
 const char * wpa_supplicant_ctrl_req_to_string(enum wpa_ctrl_req_type field,
 					       const char *default_txt,
 					       const char **txt);
 
 enum wpa_ctrl_req_type wpa_supplicant_ctrl_req_from_string(const char *field);
 
+const char * channel_width_name(enum chan_width width);
+
 #endif /* WPAS_GLUE_H */
-- 
1.9.3




More information about the HostAP mailing list