diff --git a/src/plugins/steer/rcpi/rcpi.c b/src/plugins/steer/rcpi/rcpi.c index f5d2034e5bbdfccb3c86c80a76be57432cb89744..e29e29ecad592ab12213e631d9093caf9f5033da 100644 --- a/src/plugins/steer/rcpi/rcpi.c +++ b/src/plugins/steer/rcpi/rcpi.c @@ -73,6 +73,15 @@ enum rcpi_trigger_type { RCPI_TRIGGER_HIGH = 1, }; +enum rcpi_sta_state { + RCPI_STA_CONNECTED, + RCPI_STA_USTA_CHECK, + RCPI_STA_BCN_CHECK, + RCPI_STA_NOP, + RCPI_STA_NOSTEER, + RCPI_STA_DISCONNECTED, +}; + /* per-sta steer context data */ struct rcpi_steer_sta_data { uint8_t macaddr[6]; @@ -87,10 +96,14 @@ struct rcpi_steer_sta_data { uint8_t rcpi_high_trigger_cnt; uint8_t diffsnr; + enum rcpi_sta_state state; + time_t lowrcpi_tstart; time_t lowrcpi_tend; bool lowrcpi_epoch; + time_t nop_tstart; + time_t bcn_query_time; time_t usta_query_time; @@ -162,6 +175,28 @@ static void rcpi_reset_steer_sta_data(struct rcpi_steer_sta_data *st); static int rcpi_query_sta_metrics(struct rcpi_steer_control *sc, struct steer_sta *s); +static const char *rcpi_sta_state_string(enum rcpi_sta_state s) +{ + switch (s) { + case RCPI_STA_CONNECTED: + return "Connected"; + case RCPI_STA_DISCONNECTED: + return "Disconnected"; + case RCPI_STA_USTA_CHECK: + return "Unassoc-STA metrics check"; + case RCPI_STA_BCN_CHECK: + return "Beacon metrics check"; + case RCPI_STA_NOP: + return "Idle"; + case RCPI_STA_NOSTEER: + return "No Steer"; + default: + break; + } + + return "Unknown"; +} + static int timeradd_msecs(struct timeval *a, unsigned long msecs, struct timeval *res) { @@ -208,6 +243,7 @@ int rcpi_sta_table_entry_process(struct rcpi_steer_control *sc, { struct steer_sta *s = (struct steer_sta *)st->sta; int action = STA_TIMER_NOP; + time_t now = time(NULL); /* if action = STA_TIMER_ADD, set 'st->interval' as desired. @@ -222,35 +258,47 @@ int rcpi_sta_table_entry_process(struct rcpi_steer_control *sc, return STA_TIMER_NOP; } - if (st->usta_query_sent && !st->usta_metrics_processed) { - st->check_bcn_report = 1; - - /* send sta-metrics-query to know updated metrics */ - rcpi_query_sta_metrics(sc, s); - st->interval = 2 * 1000; - - cntlr_dbg(LOG_STEER, - "rcpi_sta_timer_cb: STA " MACFMT ": Unassoc-STA meas not available yet\n", - MAC2STR(st->macaddr)); - - return STA_TIMER_ADD; - } - - if (st->bcn_query_sent && !st->bcn_metrics_processed) { - cntlr_dbg(LOG_STEER, - "rcpi_sta_timer_cb: STA " MACFMT ": Beacon Report not available yet\n", - MAC2STR(st->macaddr)); + switch (st->state) { + case RCPI_STA_USTA_CHECK: + if (st->usta_query_sent && difftime(now, st->usta_query_time) >= USTA_RESPONSE_TIMEOUT) { + st->state = RCPI_STA_BCN_CHECK; + st->check_bcn_report = 1; - /* send sta-metrics-query to know updated metrics */ - rcpi_query_sta_metrics(sc, s); - st->interval = 2 * 1000; + cntlr_dbg(LOG_STEER, + "rcpi_sta_timer_cb: STA " MACFMT ": Unassoc-STA meas not available yet\n", + MAC2STR(st->macaddr)); - // reset following so can retry in the next rcpi_steer call - st->usta_query_sent = 0; - st->bcn_query_sent = 0; - st->check_bcn_report = 0; + /* send sta-metrics-query to know updated metrics */ + rcpi_query_sta_metrics(sc, s); + } + break; + case RCPI_STA_BCN_CHECK: + if (st->bcn_query_sent && difftime(now, st->bcn_query_time) >= BEACON_RESPONSE_TIMEOUT) { + st->state = RCPI_STA_NOP; + cntlr_dbg(LOG_STEER, + "rcpi_sta_timer_cb: STA " MACFMT ": Beacon Report not available yet\n", + MAC2STR(st->macaddr)); - return STA_TIMER_ADD; + /* enter 'steer_int' nop interval */ + time(&st->nop_tstart); + st->interval = sc->steer_int * 1000; + action = STA_TIMER_ADD; + } + break; + case RCPI_STA_NOP: + if (difftime(now, st->nop_tstart) >= sc->steer_int) { + /* exit nop state */ + st->state = RCPI_STA_CONNECTED; + st->nop_tstart = 0; + st->usta_query_sent = 0; + st->bcn_query_sent = 0; + st->check_bcn_report = 0; + + rcpi_query_sta_metrics(sc, s); + } + break; + default: + break; } return action; @@ -632,6 +680,7 @@ void rcpi_reset_steer_sta_data(struct rcpi_steer_sta_data *st) st->tprev = 0; st->connected = ((struct steer_sta *)st->sta)->bss.connected; + st->state = st->connected ? RCPI_STA_CONNECTED : RCPI_STA_DISCONNECTED; st->bcn_metrics_processed = false; st->bcn_query_sent = false; st->check_bcn_report = false; @@ -648,6 +697,8 @@ void rcpi_print_steer_sta_data(struct rcpi_steer_sta_data *st) #define NUM_USTA_METRICS 16 #define NUM_BCN_METRICS 16 cntlr_dbg(LOG_STEER, "STA = " MACFMT "\n", MAC2STR(st->macaddr)); + cntlr_dbg(LOG_STEER, "BSSID = " MACFMT "\n", MAC2STR(((struct steer_sta *)st->sta)->bss.bssid)); + cntlr_dbg(LOG_STEER, "state = %s\n", rcpi_sta_state_string(st->state)); cntlr_dbg(LOG_STEER, "lowrcpi = %d\n", st->lowrcpi_epoch); cntlr_dbg(LOG_STEER, "usta-query-sent = %d\n", st->usta_query_sent); cntlr_dbg(LOG_STEER, "bcn-query-sent = %d\n", st->bcn_query_sent); @@ -852,7 +903,8 @@ int rcpi_steer(void *priv, struct steer_sta *s, uint16_t rxcmdu_type) time_t now = time(NULL); - cntlr_trace(LOG_STEER, "%s: STA " MACFMT " --------->\n", __func__, MAC2STR(s->sta->macaddr)); + cntlr_trace(LOG_STEER, "%s: STA " MACFMT ", rcpi = %u --------->\n", + __func__, MAC2STR(s->sta->macaddr), s->sta->rcpi); s->verdict = STEER_VERDICT_UNDECIDED; s->reason = STEER_REASON_UNDEFINED; @@ -998,7 +1050,8 @@ int rcpi_steer(void *priv, struct steer_sta *s, uint16_t rxcmdu_type) MAC2STR(b->bssid), b->rcpi, b->channel, b->opclass); if (is_meas_old(now, b->rpt_time, BEACON_METRICS_AGEOUT)) { - cntlr_dbg(LOG_STEER, "%s: Ignore old bcn-report\n", __func__); + cntlr_dbg(LOG_STEER, "%s: Ignore %ds old bcn-report\n", + __func__, (int)difftime(now, b->rpt_time)); continue; } @@ -1026,7 +1079,8 @@ int rcpi_steer(void *priv, struct steer_sta *s, uint16_t rxcmdu_type) list_for_each_entry(b, s->meas_reportlist, list) { if (is_meas_old(now, b->rpt_time, BEACON_METRICS_AGEOUT)) { - cntlr_dbg(LOG_STEER, "%s: Ignore old bcn-report\n", __func__); + cntlr_dbg(LOG_STEER, "%s: Ignore %ds old bcn-report\n", + __func__, (int)difftime(now, b->rpt_time)); continue; } @@ -1066,12 +1120,14 @@ int rcpi_steer(void *priv, struct steer_sta *s, uint16_t rxcmdu_type) if (!st->usta_query_sent) { ret = rcpi_query_unassoc_sta_metrics(sc, st); if (!ret && st->usta_query_sent) { + st->state = RCPI_STA_USTA_CHECK; st->usta_metrics_processed = 0; rcpi_sta_timer_set(sc, st, USTA_RESPONSE_TIMEOUT * 1000); } } else if (st->check_bcn_report && !st->bcn_query_sent) { ret = rcpi_query_beacon_metrics(sc, st); if (!ret && st->bcn_query_sent) { + st->state = RCPI_STA_BCN_CHECK; st->bcn_metrics_processed = 0; rcpi_sta_timer_set(sc, st, BEACON_RESPONSE_TIMEOUT * 1000); } @@ -1082,7 +1138,6 @@ int rcpi_steer(void *priv, struct steer_sta *s, uint16_t rxcmdu_type) /* curr-rcpi >= report_rcpi_threshold */ if (rcpi_trigger == RCPI_TRIGGER_HIGH) { - st->cleanup = 1; rcpi_reset_steer_sta_data(st); }