diff --git a/src/agent.c b/src/agent.c index e620f171103868b1c1e891e73c28878c9d45e135..d4f227509a7c816ca106897188954e1200ad75a0 100644 --- a/src/agent.c +++ b/src/agent.c @@ -1473,29 +1473,45 @@ static void wifi_sta_periodic_run(atimer_t *t) return; } + if (sta_steer_allowed(s->steer_policy) + && !list_empty(&s->pref_nbrlist) + && maybe_steer_sta(s, &reason, &pref_nbr)) { + + steer_sta(s, pref_nbr); + } + + if (!list_empty(&vif->nbrlist) && list_empty(&s->pref_nbrlist)) + recalc_desired_neighbors(s); + if (s->rssi_avg[0] && s->rssi_avg[1]) { struct agent_config_radio *rcfg = get_agent_config_radio(&a->cfg, vif->cfg->device); + uint8_t trig_l = + rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; + uint8_t trig_h = + rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; uint8_t curr_rcpi = rssi_to_rcpi(s->rssi_avg[0]); uint8_t prev_rcpi = rssi_to_rcpi(s->rssi_avg[1]); - uint8_t trig_l = rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; - uint8_t trig_h = rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; + + if (!rcfg) + goto rearm_periodic; if ((prev_rcpi <= trig_h && curr_rcpi > trig_h) || - (prev_rcpi >= trig_l && curr_rcpi < trig_l)) - timer_set(&a->rcpi_threshold_timer, 0); - } + (prev_rcpi >= trig_l && curr_rcpi < trig_l)) { + /* passed report threshold (+/-hyst), (re)start sample collection */ + s->num_rssi_rep = 1; + goto rearm_periodic; + } - if (sta_steer_allowed(s->steer_policy) - && !list_empty(&s->pref_nbrlist) - && maybe_steer_sta(s, &reason, &pref_nbr)) { + if (s->num_rssi_rep > 0 && s->num_rssi_rep < MAX_RSSI_MEAS) + /* collect next sample */ + s->num_rssi_rep++; - steer_sta(s, pref_nbr); + if (s->num_rssi_rep == MAX_RSSI_MEAS) + /* interpret collected samples */ + timer_set(&a->rcpi_threshold_timer, 0); } - if (!list_empty(&vif->nbrlist) && list_empty(&s->pref_nbrlist)) - recalc_desired_neighbors(s); - rearm_periodic: timer_set(&s->sta_timer, STA_PERIODIC_RUN_INTERVAL); } @@ -3323,7 +3339,6 @@ static void agent_rcpi_thresold_timer_cb(atimer_t *t) struct sta *s = NULL; struct agent_config_radio *rcfg; - dbg("%s %d checking clients on %s\n", __func__, __LINE__, ap->name); rcfg = get_agent_config_radio(&a->cfg, ap->cfg->device); @@ -3331,62 +3346,64 @@ static void agent_rcpi_thresold_timer_cb(atimer_t *t) continue; list_for_each_entry(s, &ap->stalist, list) { - uint8_t trig_l = rcfg->report_rcpi_threshold - rcfg->rcpi_hysteresis_margin; - uint8_t trig_h = rcfg->report_rcpi_threshold + rcfg->rcpi_hysteresis_margin; - 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)); + 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; + /* 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 < trig_l) || - (curr_rcpi > trig_h && prev_rcpi <= trig_h)) { - struct cmdu_buff *cmdu; - char ev_data[512] = {0}; - - 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, - curr_rcpi); - - if (curr_rcpi < trig_l) - agent_notify_iface_event(a, ap->name, - "sta_low_rcpi", ev_data); - else - agent_notify_iface_event(a, ap->name, - "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); - } + 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 < s->num_rssi_rep) && + (num_rssi_high < s->num_rssi_rep)) { + dbg("%s: insufficient number of samples below/above RCPI trigger, continue\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 == s->num_rssi_rep) + agent_notify_iface_event(a, ap->name, "sta_low_rcpi", ev_data); + else + agent_notify_iface_event(a, ap->name, "sta_high_rcpi", ev_data); -/* curr_rcpi = calculate_radio_rcpi(a, p->name); - 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->name); + /* stop collecting samples for report */ + s->num_rssi_rep = 0; + + /* 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); + } + } + } -//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 92b42f236c882102869e601be937c5d80d4f6e47..91349e6597ad91eb0571b4602ab41312c2c19cfc 100644 --- a/src/agent.h +++ b/src/agent.h @@ -187,9 +187,10 @@ struct sta { unsigned char macaddr[6]; 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;