From 1fd147f9f15074c2d64c5c8f6440cb8020846ad6 Mon Sep 17 00:00:00 2001
From: Anjan Chanda <anjan.chanda@iopsys.eu>
Date: Mon, 24 Mar 2025 15:07:39 +0100
Subject: [PATCH] steer: rcpi: introduce sta states
---
src/plugins/steer/rcpi/rcpi.c | 115 +++++++++++++++++++++++++---------
1 file changed, 85 insertions(+), 30 deletions(-)
diff --git a/src/plugins/steer/rcpi/rcpi.c b/src/plugins/steer/rcpi/rcpi.c
index f5d2034e..e29e29ec 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);
}
--
GitLab