diff --git a/src/agent.c b/src/agent.c index bb29a3f4df426e78c69406b37f8d7ce8b87f20e1..0f66775ef54c63bd738381356eb7dc7464006c47 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1749,18 +1749,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)) - timer_set(&a->rcpi_threshold_timer, 0); - } - if (sta_steer_allowed(s->steer_policy) && !list_empty(&s->pref_nbrlist) && maybe_steer_sta(s, &reason, &pref_nbr)) { @@ -1771,6 +1759,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 trig_l, trig_h; + uint8_t curr_rcpi, prev_rcpi; + + rcfg = get_agent_config_radio(&a->cfg, ap->cfg->device); + if (!rcfg) + goto rearm_periodic; + + if (!rcfg->report_rcpi_threshold) + goto rearm_periodic; + + trig_l = rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; + trig_h = rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; + curr_rcpi = rssi_to_rcpi(s->rssi_avg[0]); + prev_rcpi = rssi_to_rcpi(s->rssi_avg[1]); + + if (curr_rcpi > trig_l && curr_rcpi < trig_h) { + /* rcpi in range, stop sample collection */ + s->num_rssi_rep = 0; + } else if ((prev_rcpi < trig_h && curr_rcpi >= trig_h) || + (prev_rcpi > trig_l && curr_rcpi <= trig_l)) { + /* passed report trigger, (re)start sample collection */ + s->num_rssi_rep = 1; + } else { + /* rcpi outside range for consecutive sample */ + if (s->num_rssi_rep == MAX_RSSI_MEAS) { + /* interpret collected samples */ + timer_set(&a->rcpi_threshold_timer, 0); + } else { + /* collect next sample */ + s->num_rssi_rep++; + } + } + } + rearm_periodic: timer_set(&s->sta_timer, STA_PERIODIC_RUN_INTERVAL); } @@ -3750,59 +3774,62 @@ static void agent_rcpi_thresold_timer_cb(atimer_t *t) continue; list_for_each_entry(s, &ap->stalist, list) { - uint8_t report_rcpi = rcfg->report_rcpi_threshold; - uint8_t curr_rcpi, prev_rcpi; + struct cmdu_buff *cmdu; + char ev_data[512] = {0}; + uint8_t rcpi_low, rcpi_high; /* RCPI triggers */ + int i, num_rssi_low = 0, num_rssi_high = 0; dbg("%s %d found client "MACFMT"\n", __func__, __LINE__, MAC2STR(s->macaddr)); - /* Note: Using average RSSI for all triggers */ - curr_rcpi = rssi_to_rcpi(s->rssi_avg[0]); - prev_rcpi = rssi_to_rcpi(s->rssi_avg[1]); - - if ((curr_rcpi < report_rcpi) || - (curr_rcpi > report_rcpi && prev_rcpi <= report_rcpi)) { - struct cmdu_buff *cmdu; - char ev_data[512] = {0}; - - snprintf(ev_data, sizeof(ev_data), - "{\"macaddr\":\""MACFMT"\"" - ",\"report_rcpi_threshold\":%d" - ",\"rcpi\":%d}", - MAC2STR(s->macaddr), - rcfg->report_rcpi_threshold, curr_rcpi); - - if (curr_rcpi < report_rcpi) - agent_notify_iface_event(a, ap->ifname, - "sta_low_rcpi", ev_data); - else - agent_notify_iface_event(a, ap->ifname, - "sta_high_rcpi", ev_data); - - cmdu = agent_gen_assoc_sta_metric_responsex(a, - a->cntlr_almac, s, ap); - if (cmdu) { - agent_send_cmdu(a, cmdu); - cmdu_free(cmdu); - } + if (s->num_rssi_rep < MAX_RSSI_MEAS) { + dbg("%s: incomplete number of samples (%d) for report, continue\n", + __func__, s->num_rssi_rep); + continue; } - } + rcpi_low = rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; + rcpi_high = rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; + + /* Using average RSSI for all triggers */ + for (i = 0; i < s->num_rssi_rep; i++) { + if (rssi_to_rcpi(s->rssi_avg[i]) <= rcpi_low) + num_rssi_low++; + else if (rssi_to_rcpi(s->rssi_avg[i]) >= rcpi_high) + num_rssi_high++; + } + + if (num_rssi_low && num_rssi_high) { + /* should not happen */ + err("%s: mixed samples below & above RCPI triggers!\n", __func__); + continue; + } + 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, + rcfg->rcpi_hysteresis_margin, + rssi_to_rcpi(s->rssi_avg[0])); + + if (num_rssi_low) + agent_notify_iface_event(a, ap->ifname, "sta_low_rcpi", ev_data); + else + agent_notify_iface_event(a, ap->ifname, "sta_high_rcpi", ev_data); + + /* send the report */ + cmdu = agent_gen_assoc_sta_metric_responsex(a, a->cntlr_almac, s, ap); + if (cmdu) { + agent_send_cmdu(a, cmdu); + cmdu_free(cmdu); + } + } } - } -/* curr_rcpi = calculate_radio_rcpi(a, p->ifname); - prev_rcpi = p->prev_rcpi; - if (((prev_rcpi > p->cfg->rcpi_threshold) && - (curr_rcpi > p->cfg->rcpi_threshold)) || - ((prev_rcpi < p->cfg->rcpi_threshold) && - (curr_rcpi < p->cfg->rcpi_threshold))) - goto refresh_interval; -*/ - //prepare_assoc_sta_metric_response(a, p->ifname); + } -//refresh_interval: -// p->prev_rcpi = curr_rcpi; timer_set(&a->rcpi_threshold_timer, RCPI_THRESHOLD_TIMER); } diff --git a/src/agent.h b/src/agent.h index 863f5ad3cd78ddadaca2e6a31a41c632c80d3435..a68cf6797378e0fb060cd6af49edbc524430da96 100644 --- a/src/agent.h +++ b/src/agent.h @@ -459,9 +459,10 @@ struct sta { #endif uint32_t caps; /** capability bitmap */ int rssi[WIFI_NUM_ANTENNA]; /** rssi of last received pkt */ -#define MAX_RSSI_MEAS 2 +#define MAX_RSSI_MEAS 3 int8_t rssi_avg[MAX_RSSI_MEAS]; /** average rssi history FIFO buffer */ - uint8_t num_rssi; /** number of RSSI samples */ + uint8_t num_rssi; /** total number of RSSI samples aggregated */ + uint8_t num_rssi_rep; /** number of RSSI samples collected for report */ uint64_t connected_ms; /** number of msecs connected */ struct timespec last_update; uint32_t tx_rate; diff --git a/src/config.c b/src/config.c index 1e531bdb287f5219afd970586588c3971ecd3844..b3c024261752ee2131f08d13d721069239dbace0 100644 --- a/src/config.c +++ b/src/config.c @@ -2572,7 +2572,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) { @@ -2661,6 +2662,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 =