static int parse_bitrate(struct nlattr *bitrate_attr, char *buf, int buflen)
{
int rate = 0;
- char *pos = buf;
- struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
+ int pos = 0;
+ char str_rate[32] = { 0, };
+ char str_buf[128] = { 0, };
+ struct nlattr *rate_info[NL80211_RATE_INFO_MAX + 1];
static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
[NL80211_RATE_INFO_BITRATE] = { .type = NLA_U16 },
- [NL80211_RATE_INFO_BITRATE32] = { .type = NLA_U32 },
[NL80211_RATE_INFO_MCS] = { .type = NLA_U8 },
[NL80211_RATE_INFO_40_MHZ_WIDTH] = { .type = NLA_FLAG },
[NL80211_RATE_INFO_SHORT_GI] = { .type = NLA_FLAG },
+ [NL80211_RATE_INFO_BITRATE32] = { .type = NLA_U32 },
};
- if (nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, bitrate_attr, rate_policy)) {
- snprintf(buf, buflen, "failed to parse nested rate attributes!");
+ if (nla_parse_nested(rate_info, NL80211_RATE_INFO_MAX, bitrate_attr, rate_policy)) {
+ if (buf)
+ snprintf(buf, buflen, "failed to parse nested rate attributes!");
return 0;
}
- if (rinfo[NL80211_RATE_INFO_BITRATE32])
- rate = nla_get_u32(rinfo[NL80211_RATE_INFO_BITRATE32]);
- else if (rinfo[NL80211_RATE_INFO_BITRATE])
- rate = nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
+ if (rate_info[NL80211_RATE_INFO_MCS])
+ pos += snprintf(str_buf + pos, 128 - pos,
+ " MCS %d", nla_get_u8(rate_info[NL80211_RATE_INFO_MCS]));
+ if (rate_info[NL80211_RATE_INFO_40_MHZ_WIDTH])
+ pos += snprintf(str_buf + pos, 128 - pos, " 40MHz");
+ if (rate_info[NL80211_RATE_INFO_SHORT_GI])
+ pos += snprintf(str_buf + pos, 128 - pos, " short GI");
+ if (rate_info[NL80211_RATE_INFO_VHT_MCS])
+ pos += snprintf(str_buf + pos, 128 - pos,
+ " VHT-MCS %d", nla_get_u8(rate_info[NL80211_RATE_INFO_VHT_MCS]));
+ if (rate_info[NL80211_RATE_INFO_VHT_NSS])
+ pos += snprintf(str_buf + pos, 128 - pos,
+ " VHT-NSS %d", nla_get_u8(rate_info[NL80211_RATE_INFO_VHT_NSS]));
+ if (rate_info[NL80211_RATE_INFO_80_MHZ_WIDTH])
+ pos += snprintf(str_buf + pos, 128 - pos, " 80MHz");
+ if (rate_info[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
+ pos += snprintf(str_buf + pos, 128 - pos, " 80P80MHz");
+ if (rate_info[NL80211_RATE_INFO_160_MHZ_WIDTH])
+ pos += snprintf(str_buf + pos, 128 - pos, " 160MHz");
+
+ if (rate_info[NL80211_RATE_INFO_BITRATE32])
+ rate = nla_get_u32(rate_info[NL80211_RATE_INFO_BITRATE32]);
+ else if (rate_info[NL80211_RATE_INFO_BITRATE])
+ rate = nla_get_u16(rate_info[NL80211_RATE_INFO_BITRATE]);
if (rate > 0)
- pos += snprintf(pos, buflen - (pos - buf),
- "%d.%d MBit/s", rate / 10, rate % 10);
-
- if (rinfo[NL80211_RATE_INFO_MCS])
- pos += snprintf(pos, buflen - (pos - buf),
- " MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]));
- if (rinfo[NL80211_RATE_INFO_VHT_MCS])
- pos += snprintf(pos, buflen - (pos - buf),
- " VHT-MCS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_MCS]));
- if (rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
- pos += snprintf(pos, buflen - (pos - buf), " 40MHz");
- if (rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
- pos += snprintf(pos, buflen - (pos - buf), " 80MHz");
- if (rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
- pos += snprintf(pos, buflen - (pos - buf), " 80P80MHz");
- if (rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
- pos += snprintf(pos, buflen - (pos - buf), " 160MHz");
- if (rinfo[NL80211_RATE_INFO_SHORT_GI])
- pos += snprintf(pos, buflen - (pos - buf), " short GI");
- if (rinfo[NL80211_RATE_INFO_VHT_NSS])
- pos += snprintf(pos, buflen - (pos - buf),
- " VHT-NSS %d", nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]));
+ snprintf(str_rate, 32, "%d.%d MBit/s", rate / 10, rate % 10);
+
+ if (buf)
+ snprintf(buf, buflen, "%s%s", str_rate, str_buf);
return rate;
}
static int _on_receive_station_info(struct nl_msg *msg, void *arg)
{
- struct nlattr *tb[NL80211_ATTR_MAX + 1];
struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
- struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
+ struct nlattr *sta_info[NL80211_STA_INFO_MAX + 1];
+ struct nlattr *attr_info[NL80211_ATTR_MAX + 1];
struct nl80211_sta_flag_update *sta_flags;
static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
[NL80211_STA_INFO_INACTIVE_TIME] = { .type = NLA_U32 },
[NL80211_STA_INFO_RX_BYTES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_BYTES] = { .type = NLA_U32 },
- [NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
- [NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
- [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
- [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
- [NL80211_STA_INFO_BEACON_RX] = { .type = NLA_U64},
- [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
- [NL80211_STA_INFO_T_OFFSET] = { .type = NLA_U64 },
- [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
- [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
[NL80211_STA_INFO_LLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLID] = { .type = NLA_U16 },
[NL80211_STA_INFO_PLINK_STATE] = { .type = NLA_U8 },
+ [NL80211_STA_INFO_SIGNAL] = { .type = NLA_U8 },
+ [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
+ [NL80211_STA_INFO_RX_PACKETS] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_TX_PACKETS] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_RETRIES] = { .type = NLA_U32 },
[NL80211_STA_INFO_TX_FAILED] = { .type = NLA_U32 },
- [NL80211_STA_INFO_BEACON_LOSS] = { .type = NLA_U32},
- [NL80211_STA_INFO_RX_DROP_MISC] = { .type = NLA_U64},
+ [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
+ [NL80211_STA_INFO_BSS_PARAM] = { .type = NLA_NESTED },
[NL80211_STA_INFO_STA_FLAGS] = { .minlen = sizeof(struct nl80211_sta_flag_update) },
- [NL80211_STA_INFO_LOCAL_PM] = { .type = NLA_U32},
- [NL80211_STA_INFO_PEER_PM] = { .type = NLA_U32},
- [NL80211_STA_INFO_NONPEER_PM] = { .type = NLA_U32},
+ [NL80211_STA_INFO_BEACON_LOSS] = { .type = NLA_U32},
+ [NL80211_STA_INFO_T_OFFSET] = { .type = NLA_U64 },
+ [NL80211_STA_INFO_LOCAL_PM] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_PEER_PM] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_NONPEER_PM] = { .type = NLA_U32 },
+ [NL80211_STA_INFO_RX_BYTES64] = { .type = NLA_U64 },
+ [NL80211_STA_INFO_TX_BYTES64] = { .type = NLA_U64 },
[NL80211_STA_INFO_CHAIN_SIGNAL] = { .type = NLA_NESTED },
[NL80211_STA_INFO_CHAIN_SIGNAL_AVG] = { .type = NLA_NESTED },
+ [NL80211_STA_INFO_RX_DROP_MISC] = { .type = NLA_U64 },
+ [NL80211_STA_INFO_BEACON_RX] = { .type = NLA_U64 },
[NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
- [NL80211_STA_INFO_BSS_PARAM] = { .type = NLA_NESTED },
[NL80211_STA_INFO_RX_DURATION] = { .type = NLA_U64 },
};
- char mac_addr[MAX_MAC_ADDR_LEN], state_name[10], dev[20];
+ char mac_addr[MAX_MAC_ADDR_LEN], dev[IF_NAMESIZE];
char *chain;
+ char *attr_mac = NULL;
mesh_nl_state *state = (mesh_nl_state *)arg;
mesh_station_info_s *station_info = NULL;
- nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
- genlmsg_attrlen(gnlh, 0), NULL);
-
- /*
- * TODO: validate the interface and mac address!
- * Otherwise, there's a race condition as soon as
- * the kernel starts sending station notifications.
- */
+ nla_parse(attr_info, NL80211_ATTR_MAX,
+ genlmsg_attrdata(gnlh, 0), genlmsg_attrlen(gnlh, 0), NULL);
- if (!tb[NL80211_ATTR_STA_INFO]) {
- MESH_LOGE("missing station stats !");
+ if (!attr_info[NL80211_ATTR_STA_INFO]) {
+ MESH_LOGE("[Station] missing station stats !");
return NL_SKIP;
}
- if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
- tb[NL80211_ATTR_STA_INFO],
- stats_policy)) {
- MESH_LOGE("failed to parse nested attributes!");
+
+ if (nla_parse_nested(sta_info, NL80211_STA_INFO_MAX,
+ attr_info[NL80211_ATTR_STA_INFO], stats_policy)) {
+ MESH_LOGE("[Station] Failed to parse nested attributes!");
return NL_SKIP;
}
+ /* Allocation */
station_info = g_try_new0(mesh_station_info_s, 1);
if (NULL == station_info) {
MESH_LOGE("Failed to allocate station info !");
return NL_SKIP;
}
- mac_addr_n2a(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
- if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
- MESH_LOGD("Station %s (on %s)", mac_addr, dev);
+ /* BSSID */
+ attr_mac = nla_data(attr_info[NL80211_ATTR_MAC]);
+ snprintf(mac_addr, MAX_MAC_ADDR_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
+ attr_mac[0], attr_mac[1], attr_mac[2],
+ attr_mac[3], attr_mac[4], attr_mac[5]);
+ if_indextoname(nla_get_u32(attr_info[NL80211_ATTR_IFINDEX]), dev);
station_info->bssid = g_strdup(mac_addr);
+ MESH_LOGD("Station %s [dev %s]", station_info->bssid, dev);
- if (sinfo[NL80211_STA_INFO_INACTIVE_TIME]) {
+ /* Inactive time */
+ if (0 != sta_info[NL80211_STA_INFO_INACTIVE_TIME]) {
station_info->inactive_time =
- nla_get_u32(sinfo[NL80211_STA_INFO_INACTIVE_TIME]);
+ nla_get_u32(sta_info[NL80211_STA_INFO_INACTIVE_TIME]);
MESH_LOGE(" inactive time:\t%u ms", station_info->inactive_time);
}
- if (sinfo[NL80211_STA_INFO_RX_BYTES64]) {
- station_info->rx_bytes =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
- MESH_LOGE(" rx bytes:\t%llu", station_info->rx_bytes);
- } else if (sinfo[NL80211_STA_INFO_RX_BYTES]) {
+ /* RX Bytes */
+ if (0 != sta_info[NL80211_STA_INFO_RX_BYTES]) {
station_info->rx_bytes =
- nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
+ nla_get_u32(sta_info[NL80211_STA_INFO_RX_BYTES]);
MESH_LOGD(" rx bytes:\t%u", station_info->rx_bytes);
+ } else if (0 != sta_info[NL80211_STA_INFO_RX_BYTES64]) {
+ station_info->rx_bytes =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_RX_BYTES64]);
+ MESH_LOGE(" rx bytes:\t%llu", station_info->rx_bytes);
}
- if (sinfo[NL80211_STA_INFO_RX_PACKETS]) {
+
+ /* RX Packets */
+ if (0 != sta_info[NL80211_STA_INFO_RX_PACKETS]) {
station_info->rx_packets =
- nla_get_u32(sinfo[NL80211_STA_INFO_RX_PACKETS]);
+ nla_get_u32(sta_info[NL80211_STA_INFO_RX_PACKETS]);
MESH_LOGD(" rx packets:\t%u", station_info->rx_packets);
}
- if (sinfo[NL80211_STA_INFO_TX_BYTES64]) {
- station_info->tx_bytes =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
- MESH_LOGD(" tx bytes:\t%llu", station_info->rx_packets);
- } else if (sinfo[NL80211_STA_INFO_TX_BYTES]) {
+ /* TX Bytes */
+ if (0 != sta_info[NL80211_STA_INFO_TX_BYTES]) {
station_info->tx_bytes =
- nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
+ nla_get_u32(sta_info[NL80211_STA_INFO_TX_BYTES]);
MESH_LOGD(" tx bytes:\t%u", station_info->tx_bytes);
- }
- if (sinfo[NL80211_STA_INFO_TX_PACKETS]) {
- station_info->tx_packets =
- nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS]);
- MESH_LOGD(" tx packets:\t%u", station_info->tx_packets);
- }
- if (sinfo[NL80211_STA_INFO_TX_RETRIES]) {
- station_info->tx_retries =
- nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
- MESH_LOGD(" tx retries:\t%u", station_info->tx_retries);
- }
- if (sinfo[NL80211_STA_INFO_TX_FAILED]) {
- station_info->tx_failed =
- nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED]);
- MESH_LOGD(" tx failed:\t%u", station_info->tx_failed);
- }
- if (sinfo[NL80211_STA_INFO_BEACON_LOSS]) {
- station_info->beacon_loss =
- nla_get_u32(sinfo[NL80211_STA_INFO_BEACON_LOSS]);
- MESH_LOGD(" beacon loss:\t%u", station_info->beacon_loss);
- }
- if (sinfo[NL80211_STA_INFO_BEACON_RX]) {
- station_info->beacon_rx =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_BEACON_RX]);
- MESH_LOGD(" beacon rx:\t%llu", station_info->beacon_rx);
- }
- if (sinfo[NL80211_STA_INFO_RX_DROP_MISC]) {
- station_info->rx_drop_misc =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_RX_DROP_MISC]);
- MESH_LOGD(" rx drop misc:\t%llu", station_info->rx_drop_misc);
- }
-
- chain = get_chain_signal(sinfo[NL80211_STA_INFO_CHAIN_SIGNAL]);
- if (sinfo[NL80211_STA_INFO_SIGNAL]) {
- station_info->rssi =
- (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
- MESH_LOGD(" signal: \t%d %sdBm", station_info->rssi, chain);
- }
-
- chain = get_chain_signal(sinfo[NL80211_STA_INFO_CHAIN_SIGNAL_AVG]);
- if (sinfo[NL80211_STA_INFO_SIGNAL_AVG]) {
- station_info->rssi_avg =
- (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
- MESH_LOGD(" signal avg:\t%d %sdBm", station_info->rssi_avg, chain);
- }
-
- if (sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]) {
- station_info->beacon_signal_avg =
- nla_get_u8(sinfo[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
- MESH_LOGD(" beacon signal avg:\t%d dBm", station_info->beacon_signal_avg);
- }
- if (sinfo[NL80211_STA_INFO_T_OFFSET]) {
- station_info->t_offset =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_T_OFFSET]);
- MESH_LOGD(" Toffset:\t%llu us", station_info->t_offset);
- }
-
- if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
- char buf[100];
- station_info->tx_bitrate =
- parse_bitrate(sinfo[NL80211_STA_INFO_TX_BITRATE], buf, sizeof(buf));
- MESH_LOGD(" tx bitrate:\t%s", buf);
- }
-
- if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
- char buf[100];
- station_info->rx_bitrate =
- parse_bitrate(sinfo[NL80211_STA_INFO_RX_BITRATE], buf, sizeof(buf));
- MESH_LOGD(" rx bitrate:\t%s", buf);
- }
-
- if (sinfo[NL80211_STA_INFO_RX_DURATION]) {
- station_info->rx_duration =
- (unsigned long long)nla_get_u64(sinfo[NL80211_STA_INFO_RX_DURATION]);
- MESH_LOGD(" rx duration:\t%lld us", station_info->rx_duration);
+ } else if (0 != sta_info[NL80211_STA_INFO_TX_BYTES64]) {
+ station_info->tx_bytes =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_TX_BYTES64]);
+ MESH_LOGD(" tx bytes:\t%llu", station_info->rx_packets);
}
- if (sinfo[NL80211_STA_INFO_LLID]) {
- station_info->llid = nla_get_u16(sinfo[NL80211_STA_INFO_LLID]);
+ /* LLID, PLID */
+ if (0 != sta_info[NL80211_STA_INFO_LLID]) {
+ station_info->llid = nla_get_u16(sta_info[NL80211_STA_INFO_LLID]);
MESH_LOGD(" mesh llid:\t%d", station_info->llid);
}
- if (sinfo[NL80211_STA_INFO_PLID]) {
- station_info->llid = nla_get_u16(sinfo[NL80211_STA_INFO_PLID]);
+ if (0 != sta_info[NL80211_STA_INFO_PLID]) {
+ station_info->llid = nla_get_u16(sta_info[NL80211_STA_INFO_PLID]);
MESH_LOGD(" mesh plid:\t%d", station_info->plid);
}
- if (sinfo[NL80211_STA_INFO_PLINK_STATE]) {
+
+ /* Plink state */
+ if (0 != sta_info[NL80211_STA_INFO_PLINK_STATE]) {
+ char state_name[10];
station_info->mesh_plink =
- nla_get_u8(sinfo[NL80211_STA_INFO_PLINK_STATE]);
+ nla_get_u8(sta_info[NL80211_STA_INFO_PLINK_STATE]);
switch (station_info->mesh_plink) {
case LISTEN:
snprintf(state_name, 10, "%s", "LISTEN");
}
MESH_LOGD(" mesh plink:\t%s", state_name);
}
- if (sinfo[NL80211_STA_INFO_LOCAL_PM]) {
- station_info->local_ps_mode =
- nla_get_u32(sinfo[NL80211_STA_INFO_LOCAL_PM]);
- MESH_LOGD(" mesh local PS mode:\t");
- print_power_mode(sinfo[NL80211_STA_INFO_LOCAL_PM]);
+
+ /* RSSI Signal */
+ chain = get_chain_signal(sta_info[NL80211_STA_INFO_CHAIN_SIGNAL]);
+ if (0 != sta_info[NL80211_STA_INFO_SIGNAL]) {
+ station_info->rssi =
+ (int8_t)nla_get_u8(sta_info[NL80211_STA_INFO_SIGNAL]);
+ MESH_LOGD(" signal: \t%d %sdBm", station_info->rssi, chain);
}
- if (sinfo[NL80211_STA_INFO_PEER_PM]) {
- station_info->peer_ps_mode =
- nla_get_u32(sinfo[NL80211_STA_INFO_PEER_PM]);
- MESH_LOGD(" mesh peer PS mode:\t");
- print_power_mode(sinfo[NL80211_STA_INFO_PEER_PM]);
+
+ /* TX Bitrate */
+ if (0 != sta_info[NL80211_STA_INFO_TX_BITRATE]) {
+ char buf[100];
+ station_info->tx_bitrate =
+ parse_bitrate(sta_info[NL80211_STA_INFO_TX_BITRATE], buf, sizeof(buf));
+ MESH_LOGD(" tx bitrate:\t%s", buf);
}
- if (sinfo[NL80211_STA_INFO_NONPEER_PM]) {
- station_info->non_peer_ps_mode =
- nla_get_u32(sinfo[NL80211_STA_INFO_NONPEER_PM]);
- MESH_LOGD(" mesh non-peer PS mode:\t");
- print_power_mode(sinfo[NL80211_STA_INFO_NONPEER_PM]);
+
+ if (0 != sta_info[NL80211_STA_INFO_TX_PACKETS]) {
+ station_info->tx_packets =
+ nla_get_u32(sta_info[NL80211_STA_INFO_TX_PACKETS]);
+ MESH_LOGD(" tx packets:\t%u", station_info->tx_packets);
+ }
+ if (0 != sta_info[NL80211_STA_INFO_TX_RETRIES]) {
+ station_info->tx_retries =
+ nla_get_u32(sta_info[NL80211_STA_INFO_TX_RETRIES]);
+ MESH_LOGD(" tx retries:\t%u", station_info->tx_retries);
+ }
+ if (0 != sta_info[NL80211_STA_INFO_TX_FAILED]) {
+ station_info->tx_failed =
+ nla_get_u32(sta_info[NL80211_STA_INFO_TX_FAILED]);
+ MESH_LOGD(" tx failed:\t%u", station_info->tx_failed);
+ }
+
+ /* Signal average */
+ chain = get_chain_signal(sta_info[NL80211_STA_INFO_CHAIN_SIGNAL_AVG]);
+ if (0 != sta_info[NL80211_STA_INFO_SIGNAL_AVG]) {
+ station_info->rssi_avg =
+ (int8_t)nla_get_u8(sta_info[NL80211_STA_INFO_SIGNAL_AVG]);
+ MESH_LOGD(" signal avg:\t%d %sdBm", station_info->rssi_avg, chain);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_RX_BITRATE]) {
+ char buf[100];
+ station_info->rx_bitrate =
+ parse_bitrate(sta_info[NL80211_STA_INFO_RX_BITRATE], buf, sizeof(buf));
+ MESH_LOGD(" rx bitrate:\t%s", buf);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_BSS_PARAM])
+ parse_bss_param(sta_info[NL80211_STA_INFO_BSS_PARAM], station_info);
+
+ if (0 != sta_info[NL80211_STA_INFO_CONNECTED_TIME]) {
+ station_info->connected_time =
+ nla_get_u32(sta_info[NL80211_STA_INFO_CONNECTED_TIME]);
+ MESH_LOGD(" connected time:\t%u seconds", station_info->connected_time);
}
- if (sinfo[NL80211_STA_INFO_STA_FLAGS]) {
+ if (0 != sta_info[NL80211_STA_INFO_STA_FLAGS]) {
sta_flags = (struct nl80211_sta_flag_update *)
- nla_data(sinfo[NL80211_STA_INFO_STA_FLAGS]);
+ nla_data(sta_info[NL80211_STA_INFO_STA_FLAGS]);
if (sta_flags->mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
MESH_LOGD(" authorized:");
}
}
- if (sinfo[NL80211_STA_INFO_BSS_PARAM])
- parse_bss_param(sinfo[NL80211_STA_INFO_BSS_PARAM], station_info);
- if (sinfo[NL80211_STA_INFO_CONNECTED_TIME]) {
- station_info->connected_time =
- nla_get_u32(sinfo[NL80211_STA_INFO_CONNECTED_TIME]);
- MESH_LOGD(" connected time:\t%u seconds", station_info->connected_time);
+ if (0 != sta_info[NL80211_STA_INFO_BEACON_LOSS]) {
+ station_info->beacon_loss =
+ nla_get_u32(sta_info[NL80211_STA_INFO_BEACON_LOSS]);
+ MESH_LOGD(" beacon loss:\t%u", station_info->beacon_loss);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_T_OFFSET]) {
+ station_info->t_offset =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_T_OFFSET]);
+ MESH_LOGD(" Toffset:\t%llu us", station_info->t_offset);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_LOCAL_PM]) {
+ station_info->local_ps_mode =
+ nla_get_u32(sta_info[NL80211_STA_INFO_LOCAL_PM]);
+ MESH_LOGD(" mesh local PS mode:\t");
+ print_power_mode(sta_info[NL80211_STA_INFO_LOCAL_PM]);
+ }
+ if (0 != sta_info[NL80211_STA_INFO_PEER_PM]) {
+ station_info->peer_ps_mode =
+ nla_get_u32(sta_info[NL80211_STA_INFO_PEER_PM]);
+ MESH_LOGD(" mesh peer PS mode:\t");
+ print_power_mode(sta_info[NL80211_STA_INFO_PEER_PM]);
+ }
+ if (0 != sta_info[NL80211_STA_INFO_NONPEER_PM]) {
+ station_info->non_peer_ps_mode =
+ nla_get_u32(sta_info[NL80211_STA_INFO_NONPEER_PM]);
+ MESH_LOGD(" mesh non-peer PS mode:\t");
+ print_power_mode(sta_info[NL80211_STA_INFO_NONPEER_PM]);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_RX_DROP_MISC]) {
+ station_info->rx_drop_misc =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_RX_DROP_MISC]);
+ MESH_LOGD(" rx drop misc:\t%llu", station_info->rx_drop_misc);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_BEACON_RX]) {
+ station_info->beacon_rx =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_BEACON_RX]);
+ MESH_LOGD(" beacon rx:\t%llu", station_info->beacon_rx);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_BEACON_SIGNAL_AVG]) {
+ station_info->beacon_signal_avg =
+ nla_get_u8(sta_info[NL80211_STA_INFO_BEACON_SIGNAL_AVG]);
+ MESH_LOGD(" beacon signal avg:\t%d dBm", station_info->beacon_signal_avg);
+ }
+
+ if (0 != sta_info[NL80211_STA_INFO_RX_DURATION]) {
+ station_info->rx_duration =
+ (unsigned long long)nla_get_u64(sta_info[NL80211_STA_INFO_RX_DURATION]);
+ MESH_LOGD(" rx duration:\t%lld us", station_info->rx_duration);
}
MESH_LOGD("");