]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
mesh: Show peer connected time in the wpa_cli STA cmd output for Mesh mode
authorGokul Sivakumar <gokulkumar792@gmail.com>
Wed, 4 Aug 2021 18:42:10 +0000 (00:12 +0530)
committerJouni Malinen <j@w1.fi>
Wed, 25 Aug 2021 09:26:25 +0000 (12:26 +0300)
When a Mesh interface is managed by wpa_supplicant, include the peer
link connected time (secs) in the output of "sta <addr>", "all_sta"
wpa_cli cmds for each peer. This will be helpful to find when the peer
link connection got established. The NL80211_STA_INFO_CONNECTED_TIME
netlink attribute data is used for this purpose if available.

$ wpa_cli -i mesh0 all_sta
02:00:00:00:02:00
flags=[ASSOC][WMM][HT]
aid=1
capability=0x0
listen_interval=0
supported_rates=82 84 8b 96 8c 12 98 24 b0 48 60 6c
timeout_next=NULLFUNC POLL
rx_packets=77
tx_packets=3
rx_bytes=8510
tx_bytes=284
inactive_msec=104
signal=-30
rx_rate_info=65 mcs 0
tx_rate_info=65 mcs 0
ht_mcs_bitmask=ffff0000000000000000
connected_time=24
ht_caps_info=0x103c

The connected_time field in the output of "hostapd_cli -i ap0 all_sta"
cmd is not affected and it will continue to show the connected time
maintained by hostapd for each STA.

Signed-off-by: Gokul Sivakumar <gokulkumar792@gmail.com>
src/ap/ctrl_iface_ap.c
src/drivers/driver.h
src/drivers/driver_nl80211.c

index 28e40ba9cedeae798e0c91a0ec6b097ce34ef7ac..84b23f7bf414fd881863f38b5b51562bbdac2910 100644 (file)
@@ -50,6 +50,32 @@ static size_t hostapd_write_ht_mcs_bitmask(char *buf, size_t buflen,
 }
 
 
+static int hostapd_get_sta_conn_time(struct sta_info *sta,
+                                    struct hostap_sta_driver_data *data,
+                                    char *buf, size_t buflen)
+{
+       struct os_reltime age;
+       unsigned long secs;
+       int ret;
+
+       if (sta->connected_time.sec) {
+               /* Locally maintained time in AP mode */
+               os_reltime_age(&sta->connected_time, &age);
+               secs = (unsigned long) age.sec;
+       } else if (data->flags & STA_DRV_DATA_CONN_TIME) {
+               /* Time from the driver in mesh mode */
+               secs = data->connected_sec;
+       } else {
+               return 0;
+       }
+
+       ret = os_snprintf(buf, buflen, "connected_time=%lu\n", secs);
+       if (os_snprintf_error(buflen, ret))
+               return 0;
+       return ret;
+}
+
+
 static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
                                 struct sta_info *sta,
                                 char *buf, size_t buflen)
@@ -160,26 +186,9 @@ static int hostapd_get_sta_tx_rx(struct hostapd_data *hapd,
                        len += ret;
        }
 
-       return len;
-}
-
-
-static int hostapd_get_sta_conn_time(struct sta_info *sta,
-                                    char *buf, size_t buflen)
-{
-       struct os_reltime age;
-       int ret;
-
-       if (!sta->connected_time.sec)
-               return 0;
-
-       os_reltime_age(&sta->connected_time, &age);
+       len += hostapd_get_sta_conn_time(sta, &data, buf + len, buflen - len);
 
-       ret = os_snprintf(buf, buflen, "connected_time=%u\n",
-                         (unsigned int) age.sec);
-       if (os_snprintf_error(buflen, ret))
-               return 0;
-       return ret;
+       return len;
 }
 
 
@@ -264,7 +273,6 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
                len += res;
 
        len += hostapd_get_sta_tx_rx(hapd, sta, buf + len, buflen - len);
-       len += hostapd_get_sta_conn_time(sta, buf + len, buflen - len);
 
 #ifdef CONFIG_SAE
        if (sta->sae && sta->sae->state == SAE_ACCEPTED) {
index 4148ab07bb608f5baafcb64d6787053f96b0f134..2020184c5f94712a4bb084b483c9952ef3dc83be 100644 (file)
@@ -2151,6 +2151,7 @@ struct hostapd_data;
 #define STA_DRV_DATA_TX_SHORT_GI BIT(6)
 #define STA_DRV_DATA_RX_SHORT_GI BIT(7)
 #define STA_DRV_DATA_LAST_ACK_RSSI BIT(8)
+#define STA_DRV_DATA_CONN_TIME BIT(9)
 
 struct hostap_sta_driver_data {
        unsigned long rx_packets, tx_packets;
@@ -2160,6 +2161,7 @@ struct hostap_sta_driver_data {
        unsigned long current_tx_rate;
        unsigned long current_rx_rate;
        unsigned long inactive_msec;
+       unsigned long connected_sec;
        unsigned long flags; /* bitfield of STA_DRV_DATA_* */
        unsigned long num_ps_buf_frames;
        unsigned long tx_retry_failed;
index 447897d96fae0019f6de2588a51986608fc2e2ca..2aefa336cc95a95575977acaf8689bc496a06b1a 100644 (file)
@@ -7035,6 +7035,7 @@ static int get_sta_handler(struct nl_msg *msg, void *arg)
                [NL80211_STA_INFO_ACK_SIGNAL] = { .type = NLA_U8 },
                [NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
                [NL80211_STA_INFO_TX_DURATION] = { .type = NLA_U64 },
+               [NL80211_STA_INFO_CONNECTED_TIME] = { .type = NLA_U32 },
        };
        struct nlattr *rate[NL80211_RATE_INFO_MAX + 1];
        static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
@@ -7109,6 +7110,12 @@ static int get_sta_handler(struct nl_msg *msg, void *arg)
                data->flags |= STA_DRV_DATA_LAST_ACK_RSSI;
        }
 
+       if (stats[NL80211_STA_INFO_CONNECTED_TIME]) {
+               data->connected_sec =
+                       nla_get_u32(stats[NL80211_STA_INFO_CONNECTED_TIME]);
+               data->flags |= STA_DRV_DATA_CONN_TIME;
+       }
+
        if (stats[NL80211_STA_INFO_TX_BITRATE] &&
            nla_parse_nested(rate, NL80211_RATE_INFO_MAX,
                             stats[NL80211_STA_INFO_TX_BITRATE],