uint32_t thr;
};
+struct iwinfo_survey_entry {
+ uint64_t active_time;
+ uint64_t busy_time;
+ uint64_t busy_time_ext;
+ uint64_t rxtime;
+ uint64_t txtime;
+ uint32_t mhz;
+ uint8_t noise;
+};
+
struct iwinfo_txpwrlist_entry {
uint8_t dbm;
uint16_t mw;
int (*scanlist)(const char *, char *, int *);
int (*freqlist)(const char *, char *, int *);
int (*countrylist)(const char *, char *, int *);
+ int (*survey)(const char *, char *, int *);
int (*lookup_phy)(const char *, char *);
void (*close)(void);
};
re->is_40mhz = (re->mhz == 40);
}
+static int nl80211_get_survey_cb(struct nl_msg *msg, void *arg)
+{
+ struct nl80211_array_buf *arr = arg;
+ struct iwinfo_survey_entry *e = arr->buf;
+ struct nlattr **attr = nl80211_parse(msg);
+ struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
+ int rc;
+
+ static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
+ [NL80211_SURVEY_INFO_FREQUENCY] = { .type = NLA_U32 },
+ [NL80211_SURVEY_INFO_NOISE] = { .type = NLA_U8 },
+ [NL80211_SURVEY_INFO_TIME] = { .type = NLA_U64 },
+ [NL80211_SURVEY_INFO_TIME_BUSY] = { .type = NLA_U64 },
+ [NL80211_SURVEY_INFO_TIME_EXT_BUSY] = { .type = NLA_U64 },
+ [NL80211_SURVEY_INFO_TIME_RX] = { .type = NLA_U64 },
+ [NL80211_SURVEY_INFO_TIME_TX] = { .type = NLA_U64 },
+ };
+
+ rc = nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,
+ attr[NL80211_ATTR_SURVEY_INFO],
+ survey_policy);
+ if (rc)
+ return NL_SKIP;
+
+ /* advance to end of array */
+ e += arr->count;
+ memset(e, 0, sizeof(*e));
+
+ if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
+ e->mhz = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
+
+ if (sinfo[NL80211_SURVEY_INFO_NOISE])
+ e->noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
+
+ if (sinfo[NL80211_SURVEY_INFO_TIME])
+ e->active_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
+
+ if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
+ e->busy_time = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
+
+ if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
+ e->busy_time_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
+
+ if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
+ e->rxtime = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
+
+ if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
+ e->txtime = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
+
+ arr->count++;
+ return NL_SKIP;
+}
+
static int nl80211_get_assoclist_cb(struct nl_msg *msg, void *arg)
{
struct nl80211_array_buf *arr = arg;
return NL_SKIP;
}
+static int nl80211_get_survey(const char *ifname, char *buf, int *len)
+{
+ struct nl80211_array_buf arr = { .buf = buf, .count = 0 };
+ int rc;
+
+ rc = nl80211_request(ifname, NL80211_CMD_GET_SURVEY,
+ NLM_F_DUMP, nl80211_get_survey_cb, &arr);
+ if (!rc)
+ *len = (arr.count * sizeof(struct iwinfo_survey_entry));
+ else
+ *len = 0;
+
+ return 0;
+}
+
static int nl80211_get_assoclist(const char *ifname, char *buf, int *len)
{
DIR *d;
.scanlist = nl80211_get_scanlist,
.freqlist = nl80211_get_freqlist,
.countrylist = nl80211_get_countrylist,
+ .survey = nl80211_get_survey,
.lookup_phy = nl80211_lookup_phyname,
.close = nl80211_close
};