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 =