wpa_supplicant: Add SIGNAL_MONITOR command
authorDmitry Shmidt <dimitrysh@google.com>
Wed, 16 Dec 2015 22:18:18 +0000 (14:18 -0800)
committerJouni Malinen <j@w1.fi>
Fri, 18 Dec 2015 19:02:37 +0000 (21:02 +0200)
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 <dimitrysh@google.com>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/wpa_cli.c

index a3b587f..a75bc04 100644 (file)
@@ -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);
index cef18ba..aedd61a 100644 (file)
@@ -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" },