From: Gokul Sivakumar Date: Wed, 4 Aug 2021 18:42:10 +0000 (+0530) Subject: mesh: Show peer connected time in the wpa_cli STA cmd output for Mesh mode X-Git-Tag: hostap_2_10~201 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cdc6d381aa713703a1118e3cd935c2692668e03;p=thirdparty%2Fhostap.git mesh: Show peer connected time in the wpa_cli STA cmd output for Mesh mode When a Mesh interface is managed by wpa_supplicant, include the peer link connected time (secs) in the output of "sta ", "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 --- diff --git a/src/ap/ctrl_iface_ap.c b/src/ap/ctrl_iface_ap.c index 28e40ba9c..84b23f7bf 100644 --- a/src/ap/ctrl_iface_ap.c +++ b/src/ap/ctrl_iface_ap.c @@ -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) { diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 4148ab07b..2020184c5 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -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; diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 447897d96..2aefa336c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -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],