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;