From 7a4a93b9593575ffd64ba72739429d98e4b90858 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 10 Sep 2014 12:34:56 -0500 Subject: [PATCH] dbus: Add SignalPoll() method to report current signal properties Analogous to the control interface's SIGNAL_POLL request. Signed-hostap: Dan Williams --- src/drivers/driver.h | 3 + src/drivers/driver_common.c | 21 +++++++ wpa_supplicant/ctrl_iface.c | 25 +------- wpa_supplicant/dbus/dbus_new.c | 7 +++ wpa_supplicant/dbus/dbus_new_handlers.c | 83 +++++++++++++++++++++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 3 + 6 files changed, 119 insertions(+), 23 deletions(-) diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 3a70bb0bc..ff052bacc 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4188,6 +4188,9 @@ void wpa_scan_results_free(struct wpa_scan_results *res); /* Convert wpa_event_type to a string for logging */ const char * event_to_string(enum wpa_event_type event); +/* Convert chan_width to a string for logging and control interfaces */ +const char * channel_width_to_string(enum chan_width width); + /* NULL terminated array of linked in driver wrappers */ extern struct wpa_driver_ops *wpa_drivers[]; diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c index 3058cd57d..77e6905d5 100644 --- a/src/drivers/driver_common.c +++ b/src/drivers/driver_common.c @@ -84,3 +84,24 @@ const char * event_to_string(enum wpa_event_type event) return "UNKNOWN"; #undef E2S } + + +const char * channel_width_to_string(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/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 23049446e..9d28837b1 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -41,6 +41,7 @@ #include "autoscan.h" #include "wnm_sta.h" #include "offchannel.h" +#include "drivers/driver.h" static int wpa_supplicant_global_iface_list(struct wpa_global *global, char *buf, int len); @@ -5553,28 +5554,6 @@ static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd #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) { @@ -5599,7 +5578,7 @@ static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, if (si.chanwidth != CHAN_WIDTH_UNKNOWN) { ret = os_snprintf(pos, end - pos, "WIDTH=%s\n", - channel_width_name(si.chanwidth)); + channel_width_to_string(si.chanwidth)); if (ret < 0 || ret > end - pos) return -1; pos += ret; diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index ab2096142..73b1aeabe 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -2525,6 +2525,13 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { 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, { diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index b7d88b46d..9f6c4a39b 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -27,6 +27,7 @@ #include "dbus_new_handlers.h" #include "dbus_dict_helpers.h" #include "dbus_common_i.h" +#include "drivers/driver.h" static const char *debug_strings[] = { "excessive", "msgdump", "debug", "info", "warning", "error", NULL @@ -1401,6 +1402,88 @@ out: } +/** + * 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_to_string(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 diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 8d157edd9..51cf5f380 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -87,6 +87,9 @@ dbus_bool_t wpas_dbus_getter_global_capabilities(DBusMessageIter *iter, 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);