]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: More complete processing of connection quality monitor events
authorJouni Malinen <j@w1.fi>
Sun, 8 Jan 2017 10:08:04 +0000 (12:08 +0200)
committerJouni Malinen <j@w1.fi>
Sun, 8 Jan 2017 10:11:14 +0000 (12:11 +0200)
This adds processing of beacon loss events and generation of an internal
EVENT_BEACON_LOSS event based on them for wpa_supplicant processing. In
addition, number of consecutively lost (not acknowledged) packets is now
reported and TXE events are noted in the debug log.

Signed-off-by: Jouni Malinen <j@w1.fi>
src/drivers/driver.h
src/drivers/driver_common.c
src/drivers/driver_nl80211_event.c

index 291d4d6efb950936da8ecd08a71927bae5ea2cd5..92688a35d57a777a42ef4bf0f9880e7d213ccfc9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Driver interface definition
- * Copyright (c) 2003-2015, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -4228,6 +4228,15 @@ enum wpa_event_type {
         * EVENT_P2P_LO_STOP - Notify that P2P listen offload is stopped
         */
        EVENT_P2P_LO_STOP,
+
+       /**
+        * EVENT_BEACON_LOSS - Beacon loss detected
+        *
+        * This event indicates that no Beacon frames has been received from
+        * the current AP. This may indicate that the AP is not anymore in
+        * range.
+        */
+       EVENT_BEACON_LOSS,
 };
 
 
@@ -4817,9 +4826,12 @@ union wpa_event_data {
        /**
         * struct low_ack - Data for EVENT_STATION_LOW_ACK events
         * @addr: station address
+        * @num_packets: Number of packets lost (consecutive packets not
+        * acknowledged)
         */
        struct low_ack {
                u8 addr[ETH_ALEN];
+               u32 num_packets;
        } low_ack;
 
        /**
index c7107ba899b0bb500f239e7dff6cc385ccd5c5cf..b6bcbcad27f89fba87cc370c0da9b4653b672fbc 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Common driver-related functions
- * Copyright (c) 2003-2011, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi>
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -81,6 +81,7 @@ const char * event_to_string(enum wpa_event_type event)
        E2S(ACS_CHANNEL_SELECTED);
        E2S(DFS_CAC_STARTED);
        E2S(P2P_LO_STOP);
+       E2S(BEACON_LOSS);
        }
 
        return "UNKNOWN";
index de539b1c5d27fa36d19a3c2389bf015f251a0d79..c18fc223fa950ba9e736273299d693c9ebc7e0b3 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Driver interaction with Linux nl80211/cfg80211 - Event processing
- * Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2002-2017, Jouni Malinen <j@w1.fi>
  * Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
  * Copyright (c) 2009-2010, Atheros Communications
  *
@@ -1132,6 +1132,10 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
                [NL80211_ATTR_CQM_RSSI_HYST] = { .type = NLA_U8 },
                [NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] = { .type = NLA_U32 },
                [NL80211_ATTR_CQM_PKT_LOSS_EVENT] = { .type = NLA_U32 },
+               [NL80211_ATTR_CQM_TXE_RATE] = { .type = NLA_U32 },
+               [NL80211_ATTR_CQM_TXE_PKTS] = { .type = NLA_U32 },
+               [NL80211_ATTR_CQM_TXE_INTVL] = { .type = NLA_U32 },
+               [NL80211_ATTR_CQM_BEACON_LOSS_EVENT] = { .type = NLA_FLAG },
        };
        struct nlattr *cqm[NL80211_ATTR_CQM_MAX + 1];
        enum nl80211_cqm_rssi_threshold_event event;
@@ -1153,12 +1157,39 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
                        return;
                os_memcpy(ed.low_ack.addr, nla_data(tb[NL80211_ATTR_MAC]),
                          ETH_ALEN);
+               ed.low_ack.num_packets =
+                       nla_get_u32(cqm[NL80211_ATTR_CQM_PKT_LOSS_EVENT]);
+               wpa_printf(MSG_DEBUG, "nl80211: Packet loss event for " MACSTR
+                          " (num_packets %u)",
+                          MAC2STR(ed.low_ack.addr), ed.low_ack.num_packets);
                wpa_supplicant_event(drv->ctx, EVENT_STATION_LOW_ACK, &ed);
                return;
        }
 
-       if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL)
+       if (cqm[NL80211_ATTR_CQM_BEACON_LOSS_EVENT]) {
+               wpa_printf(MSG_DEBUG, "nl80211: Beacon loss event");
+               wpa_supplicant_event(drv->ctx, EVENT_BEACON_LOSS, NULL);
                return;
+       }
+
+       if (cqm[NL80211_ATTR_CQM_TXE_RATE] &&
+           cqm[NL80211_ATTR_CQM_TXE_PKTS] &&
+           cqm[NL80211_ATTR_CQM_TXE_INTVL] &&
+           cqm[NL80211_ATTR_MAC]) {
+               wpa_printf(MSG_DEBUG, "nl80211: CQM TXE event for " MACSTR
+                          " (rate: %u pkts: %u interval: %u)",
+                          MAC2STR((u8 *) nla_data(cqm[NL80211_ATTR_MAC])),
+                          nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_RATE]),
+                          nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_PKTS]),
+                          nla_get_u32(cqm[NL80211_ATTR_CQM_TXE_INTVL]));
+               return;
+       }
+
+       if (cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT] == NULL) {
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: Not a CQM RSSI threshold event");
+               return;
+       }
        event = nla_get_u32(cqm[NL80211_ATTR_CQM_RSSI_THRESHOLD_EVENT]);
 
        if (event == NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH) {
@@ -1169,8 +1200,12 @@ static void nl80211_cqm_event(struct wpa_driver_nl80211_data *drv,
                wpa_printf(MSG_DEBUG, "nl80211: Connection quality monitor "
                           "event: RSSI low");
                ed.signal_change.above_threshold = 0;
-       } else
+       } else {
+               wpa_printf(MSG_DEBUG,
+                          "nl80211: Unknown CQM RSSI threshold event: %d",
+                          event);
                return;
+       }
 
        res = nl80211_get_link_signal(drv, &sig);
        if (res == 0) {