From 96e8d831a5f61e94cdccbebc50a7aa964765875f Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Wed, 16 Dec 2015 14:18:18 -0800 Subject: [PATCH] wpa_supplicant: Add SIGNAL_MONITOR command SIGNAL_MONITOR THRESHOLD=DD HYSTERESIS=DD command will request signal strength monitoring events based on there having been requested amount of drop in the signal strength. The threshold value is the RSSI threshold in dBm for the event to be sent. 0 threshold can be used to disable monitoring. The hysteresis value is RSSI hysteresis in dB to specify the minimum amount of change before a consecutive event is reported. With nl80211 driver interface, these values map to the NL80211_CMD_SET_CQM command with NL80211_ATTR_CQM_RSSI_THOLD and NL80211_ATTR_CQM_RSSI_HYST attributes to the driver. This command cannot be used when bgscan module is in use since that depends on being able to control the connection monitoring parameters. Signed-off-by: Dmitry Shmidt --- wpa_supplicant/ctrl_iface.c | 25 +++++++++++++++++++++++++ wpa_supplicant/wpa_cli.c | 10 ++++++++++ 2 files changed, 35 insertions(+) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index a3b587fe8..a75bc0437 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -6704,6 +6704,28 @@ static int wpa_supplicant_signal_poll(struct wpa_supplicant *wpa_s, char *buf, } +static int wpas_ctrl_iface_signal_monitor(struct wpa_supplicant *wpa_s, + const char *cmd) +{ + const char *pos; + int threshold = 0; + int hysteresis = 0; + + if (wpa_s->bgscan && wpa_s->bgscan_priv) { + wpa_printf(MSG_DEBUG, + "Reject SIGNAL_MONITOR command - bgscan is active"); + return -1; + } + pos = os_strstr(cmd, "THRESHOLD="); + if (pos) + threshold = atoi(pos + 10); + pos = os_strstr(cmd, "HYSTERESIS="); + if (pos) + hysteresis = atoi(pos + 11); + return wpa_drv_signal_monitor(wpa_s, threshold, hysteresis); +} + + static int wpas_ctrl_iface_get_pref_freq_list( struct wpa_supplicant *wpa_s, char *cmd, char *buf, size_t buflen) { @@ -8769,6 +8791,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, } else if (os_strncmp(buf, "SIGNAL_POLL", 11) == 0) { reply_len = wpa_supplicant_signal_poll(wpa_s, reply, reply_size); + } else if (os_strncmp(buf, "SIGNAL_MONITOR", 14) == 0) { + if (wpas_ctrl_iface_signal_monitor(wpa_s, buf + 14)) + reply_len = -1; } else if (os_strncmp(buf, "PKTCNT_POLL", 11) == 0) { reply_len = wpa_supplicant_pktcnt_poll(wpa_s, reply, reply_size); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index cef18ba8e..aedd61aa3 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -2760,6 +2760,13 @@ static int wpa_cli_cmd_signal_poll(struct wpa_ctrl *ctrl, int argc, } +static int wpa_cli_cmd_signal_monitor(struct wpa_ctrl *ctrl, int argc, + char *argv[]) +{ + return wpa_cli_cmd(ctrl, "SIGNAL_MONITOR", 0, argc, argv); +} + + static int wpa_cli_cmd_pktcnt_poll(struct wpa_ctrl *ctrl, int argc, char *argv[]) { @@ -3394,6 +3401,9 @@ static const struct wpa_cli_cmd wpa_cli_commands[] = { { "signal_poll", wpa_cli_cmd_signal_poll, NULL, cli_cmd_flag_none, "= get signal parameters" }, + { "signal_monitor", wpa_cli_cmd_signal_monitor, NULL, + cli_cmd_flag_none, + "= set signal monitor parameters" }, { "pktcnt_poll", wpa_cli_cmd_pktcnt_poll, NULL, cli_cmd_flag_none, "= get TX/RX packet counters" },