diff --git a/src/agent.c b/src/agent.c index 8466fa6b942396d9eb359e6e6d8526087a21ee1a..a1408d9b0dc9aec4b0f02530142c928d050f1da9 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1689,9 +1689,12 @@ static int report_assoc_sta_metrics(struct agent *a, struct sta *s, bool notify_ snprintf(ev_data, sizeof(ev_data), "{\"macaddr\":\""MACFMT"\"" ",\"report_rcpi_threshold\":%d" + ",\"rcpi_hysteresis_margin\":%d" ",\"rcpi\":%d}", MAC2STR(s->macaddr), - rcfg->report_rcpi_threshold, curr_rcpi); + rcfg->report_rcpi_threshold, + rcfg->rcpi_hysteresis_margin, + curr_rcpi); if (curr_rcpi < rcfg->report_rcpi_threshold) agent_notify_iface_event(a, ap->ifname, @@ -1796,18 +1799,6 @@ static void wifi_sta_periodic_run(atimer_t *t) return; } - if (s->rssi_avg[0] && s->rssi_avg[1]) { - struct agent_config_radio *rcfg = - get_agent_config_radio(&a->cfg, ap->cfg->device); - uint8_t curr_rcpi = rssi_to_rcpi(s->rssi_avg[0]); - uint8_t prev_rcpi = rssi_to_rcpi(s->rssi_avg[1]); - uint8_t trigger = rcfg->report_rcpi_threshold; - - if ((prev_rcpi <= trigger && curr_rcpi > trigger) || - (prev_rcpi >= trigger && curr_rcpi < trigger)) - report_assoc_sta_metrics(a, s, true); - } - if (sta_steer_allowed(s->steer_policy) && !list_empty(&s->pref_nbrlist) && maybe_steer_sta(s, &reason, &pref_nbr)) { @@ -1818,6 +1809,42 @@ static void wifi_sta_periodic_run(atimer_t *t) if (!list_empty(&ap->nbrlist) && list_empty(&s->pref_nbrlist)) recalc_desired_neighbors(s); + if (s->rssi_avg[0] && s->rssi_avg[1]) { + struct agent_config_radio *rcfg; + uint8_t low, high; + uint8_t curr, prev; + + rcfg = get_agent_config_radio(&a->cfg, ap->cfg->device); + if (!rcfg) + goto rearm_periodic; + + if (!rcfg->report_rcpi_threshold) + goto rearm_periodic; + + low = rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; + high = rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; + curr = rssi_to_rcpi(s->rssi_avg[0]); + prev = rssi_to_rcpi(s->rssi_avg[1]); + + if (s->num_rssi_rep) { + if ((prev <= low && curr > low) || (prev >= high && curr < high)) { + /* back in range */ + s->num_rssi_rep = 0; + } else if ((prev <= low && curr <= low) || (prev >= high && curr >= high)) { + /* out of range for consecutive sample */ + s->num_rssi_rep++; + } + } else { + if ((prev < high && curr >= high) || (prev > low && curr <= low)) { + /* out of range for first time */ + s->num_rssi_rep = 1; + } + } + + if (s->num_rssi_rep == NUM_RSSI_REP_TRIG) + report_assoc_sta_metrics(a, s, true); + } + rearm_periodic: timer_set(&s->sta_timer, STA_PERIODIC_RUN_INTERVAL); } @@ -1846,6 +1873,7 @@ static void agent_sta_clean_rssi(struct sta *s) for (i = 0; i < MAX_RSSI_MEAS; i++) s->rssi_avg[i] = 0; s->num_rssi = 0; + s->num_rssi_rep = 0; } static int agent_modify_assoc_status(struct netif_ap *ap, bool allowed) diff --git a/src/agent.h b/src/agent.h index 3c70685d4cb00c28edf477c6fe7fa14549e01af2..55b953fef4af6de2f3feab33b084e460a59c15c3 100644 --- a/src/agent.h +++ b/src/agent.h @@ -456,9 +456,11 @@ struct sta { #endif uint32_t caps; /** capability bitmap */ int rssi[WIFI_NUM_ANTENNA]; /** rssi of last received pkt */ -#define MAX_RSSI_MEAS 2 - int8_t rssi_avg[MAX_RSSI_MEAS]; /** average rssi history FIFO buffer */ - uint8_t num_rssi; /** number of RSSI samples */ +#define MAX_RSSI_MEAS 2 /** must be >= 2: current and previous measurement alway required */ + int8_t rssi_avg[MAX_RSSI_MEAS]; /** average RSSI history FIFO buffer */ + uint8_t num_rssi; /** number of avg RSSI samples stored in FIFO buffer */ +#define NUM_RSSI_REP_TRIG 3 /** number of consecutive avg RSSI measurements below/above trigger needed for report */ + uint8_t num_rssi_rep; /** number of consecutive avg RSSI measurements below/above trigger observed */ uint64_t connected_ms; /** number of msecs connected */ struct timespec last_update; uint32_t tx_rate; /** tx-rate in kbps */ diff --git a/src/config.c b/src/config.c index 77e8466a7c760bf98c6997c151431aa27d271a99..3696b35d67e5a27308ad2135f0dc6dc658fc7daa 100644 --- a/src/config.c +++ b/src/config.c @@ -2556,7 +2556,8 @@ static int agent_config_get_wifi_radio(struct agent_config *a, } if (ifname && band) { - uint8_t rcpi_threshold = 0, report_rcpi_threshold = 0; + uint8_t rcpi_threshold = 0; + uint8_t report_rcpi_threshold = 0; n = get_agent_config_radio(a, ifname); if (!n) { @@ -2645,6 +2646,8 @@ static int agent_config_get_wifi_radio(struct agent_config *a, if (tb[WIFI_RADIO_RCPI_HYSTERESIS_MARGIN]) n->rcpi_hysteresis_margin = atoi(tb[WIFI_RADIO_RCPI_HYSTERESIS_MARGIN]->v.string); + else + n->rcpi_hysteresis_margin = 0; if (tb[WIFI_RADIO_REPORT_UTIL_THRESHOLD]) n->report_util_threshold =