Skip to content

Commit

Permalink
Info/History Screen: use nl80211 signal levels
Browse files Browse the repository at this point in the history
This now uses the nl80211 signal-level information, if available.
If the hardware does not fill in STA_INFO_SIGNAL{,_AVG} (indicated
by a zero value), it falls back to BSS_SIGNAL; else gives up.
  • Loading branch information
Gerrit Renker committed Nov 7, 2015
1 parent bc785ca commit ce88d3b
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 24 deletions.
20 changes: 13 additions & 7 deletions info_scr.c
Expand Up @@ -45,16 +45,22 @@ void sampling_do_poll(void)
{
iw_getstat(&cur);
iw_nl80211_get_linkstat(&ls);
iw_cache_update(&cur, &ls);
iw_cache_update(&ls);
}

static void display_levels(void)
{
static float qual, signal, noise, ssnr;
char nscale[2] = { cur.dbm.signal - 20, cur.dbm.signal },
lvlscale[2] = { -40, -20};
char tmp[0x100];
static float qual, signal, noise, ssnr;
int line;
bool noise_data_valid = iw_nl80211_have_survey_data(&ls);
int sig_level = ls.signal_avg ?: ls.signal;

/* See comments in iw_cache_update */
if (sig_level == 0)
sig_level = ls.bss_signal;

for (line = 1; line <= WH_LEVEL; line++)
mvwclrtoborder(w_levels, line, 1);
Expand All @@ -68,7 +74,7 @@ static void display_levels(void)
line = 1;

/* Noise data is rare. Use the space for spreading out. */
if (!iw_nl80211_have_survey_data(&ls))
if (!noise_data_valid)
line++;

if (cur.stat.qual.updated & IW_QUAL_QUAL_INVALID) {
Expand All @@ -88,11 +94,11 @@ static void display_levels(void)

/* Spacer */
line++;
if (!iw_nl80211_have_survey_data(&ls))
if (!noise_data_valid)
line++;

if (!(cur.stat.qual.updated & IW_QUAL_LEVEL_INVALID)) {
signal = ewma(signal, cur.dbm.signal, conf.meter_decay / 100.0);
if (sig_level != 0) {
signal = ewma(signal, sig_level, conf.meter_decay / 100.0);

mvwaddstr(w_levels, line++, 1, "signal level: ");
sprintf(tmp, "%.0f dBm (%s) ", signal, dbm2units(signal));
Expand All @@ -110,7 +116,7 @@ static void display_levels(void)

line++;

if (iw_nl80211_have_survey_data(&ls)) {
if (noise_data_valid) {
noise = ewma(noise, ls.survey.noise, conf.meter_decay / 100.0);

mvwaddstr(w_levels, line++, 1, "noise level: ");
Expand Down
4 changes: 0 additions & 4 deletions iw_if.h
Expand Up @@ -207,11 +207,7 @@ struct iw_stat {
/*
* Periodic sampling of wireless statistics via timer alarm
*/
/* FIXME: remove forward declaration */
struct iw_nl80211_linkstat;

extern void iw_getstat(struct iw_stat *stat);
extern void iw_cache_update(struct iw_stat *iw, struct iw_nl80211_linkstat *ls);

extern void sampling_init(void (*sampling_handler)(int));
extern void sampling_do_poll(void);
Expand Down
8 changes: 8 additions & 0 deletions iw_nl80211.c
Expand Up @@ -351,6 +351,14 @@ static int link_handler(struct nl_msg *msg, void *arg)
if (!bss[NL80211_BSS_STATUS])
return NL_SKIP;

if (bss[NL80211_BSS_SIGNAL_UNSPEC])
ls->bss_signal_qual = nla_get_u8(bss[NL80211_BSS_SIGNAL_UNSPEC]);

if (bss[NL80211_BSS_SIGNAL_MBM]) {
int s = nla_get_u32(bss[NL80211_BSS_SIGNAL_MBM]);
ls->bss_signal = s / 100;
}

ls->status = nla_get_u32(bss[NL80211_BSS_STATUS]);
switch (ls->status) {
case NL80211_BSS_STATUS_ASSOCIATED: /* apparently no longer used */
Expand Down
19 changes: 13 additions & 6 deletions iw_nl80211.h
Expand Up @@ -16,7 +16,8 @@

#define BIT(x) (1ULL<<(x)) /* from iw:iw.h */

/** struct msg_attribute - attributes to nla_put into the message
/**
* struct msg_attribute - attributes to nla_put into the message
* @type: type of the attribute
* @len: attribute length
* @data: pointer to data area of length @len
Expand Down Expand Up @@ -119,12 +120,14 @@ extern void iw_nl80211_get_survey(struct iw_nl80211_survey *sd);
* @beacon_int: beacon interval in Time Units of 1024usec
* @dtim_period: DTIM period for beaconing
* @beacon_avg_sig: average beacon signal (in dBm)
* @beacons: number of beacons received
* @beacons: number of beacons received
* @beacon_loss: count of times beacon loss was detected
* @signal: signal strength in dBm
* @signal_avg: average signal strength in dBm
* @tx_bitrate: string describing current TX bitrate
* @rx_bitrate: string describing current RX bitrate
* @signal: signal strength in dBm (0 if not present)
* @signal_avg: average signal strength in dBm
* @bss_signal: signal strength of BSS probe in dBm (or 0)
* @bss_signal_qual: unitless signal strength of BSS probe, 0..100
* @tx_bitrate: string describing current TX bitrate
* @rx_bitrate: string describing current RX bitrate
* @authorized: FIXME
* @authenticated: FIXME
* @long_preamble: whether using long or short preamble
Expand Down Expand Up @@ -161,6 +164,9 @@ struct iw_nl80211_linkstat {
int8_t signal,
signal_avg;

int8_t bss_signal;
uint8_t bss_signal_qual;

char tx_bitrate[100],
rx_bitrate[100];

Expand All @@ -177,6 +183,7 @@ struct iw_nl80211_linkstat {
struct iw_nl80211_survey survey;
};
extern void iw_nl80211_get_linkstat(struct iw_nl80211_linkstat *ls);
extern void iw_cache_update(struct iw_nl80211_linkstat *ls);

/* Indicate whether @ls contains usable channel survey data */
static inline bool iw_nl80211_have_survey_data(struct iw_nl80211_linkstat *ls)
Expand Down
24 changes: 17 additions & 7 deletions lhist_scr.c
Expand Up @@ -118,24 +118,34 @@ static struct iw_levelstat iw_cache_get(const uint32_t index)
return iw_stats_cache[(count - index) % IW_STACKSIZE];
}

// XXX FIXME: rewrite in terms of struct iw_nl80211_linkstat
void iw_cache_update(struct iw_stat *iw,
struct iw_nl80211_linkstat *ls)
void iw_cache_update(struct iw_nl80211_linkstat *ls)
{
static struct iw_levelstat prev, avg = IW_LSTAT_INIT;
static int slot;
int sig_level = ls->signal_avg ?: ls->signal;

if (! (iw->stat.qual.updated & IW_QUAL_LEVEL_INVALID)) {
/*
* If hardware does not support dBm signal level, it will not
* be filled in, and show up as 0. Try to fall back to the BSS
* probe where again a 0 dBm value reflects 'not initialized'.
*/
if (sig_level == 0)
sig_level = ls->bss_signal;

if (sig_level == 0) {
avg.flags |= IW_QUAL_LEVEL_INVALID;
} else {
avg.flags &= ~IW_QUAL_LEVEL_INVALID;
avg.signal += iw->dbm.signal / conf.slotsize;
track_extrema(iw->dbm.signal, &e_signal);
avg.signal += (float)sig_level / conf.slotsize;
track_extrema(sig_level, &e_signal);
}

if (iw_nl80211_have_survey_data(ls)) {
avg.flags &= ~IW_QUAL_NOISE_INVALID;
avg.noise += (float)ls->survey.noise / conf.slotsize;
track_extrema(ls->survey.noise, &e_noise);
track_extrema(iw->dbm.signal - ls->survey.noise, &e_snr);
if (! (avg.flags & IW_QUAL_LEVEL_INVALID))
track_extrema(sig_level - ls->survey.noise, &e_snr);
}

if (++slot >= conf.slotsize) {
Expand Down

0 comments on commit ce88d3b

Please sign in to comment.