aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-10-10 14:55:34 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-10-10 16:09:17 +0200
commitf957469956a10a21abe788314fd99feab5dcf224 (patch)
tree60fe282455157acc76cd687979883aa97ea8abff
parent8be1e6d8cfbbe2d59e1102e75c788fdae997f091 (diff)
measurement report: avoid cycling old report numbers
When a measurement report number is received, make sure no old ones from the last report number cycle are left behind: clear out any reports that might have the same report number, as well as older ones where we might have nr skips. Change-Id: Ib7e657b698d33862bd61c25dc23f1a24e5bc575f
-rw-r--r--src/osmo-bsc/abis_rsl.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/src/osmo-bsc/abis_rsl.c b/src/osmo-bsc/abis_rsl.c
index 38357787b..6ed87bcf2 100644
--- a/src/osmo-bsc/abis_rsl.c
+++ b/src/osmo-bsc/abis_rsl.c
@@ -964,10 +964,40 @@ static void print_meas_rep(struct gsm_lchan *lchan, struct gsm_meas_rep *mr)
}
}
+/* A measurement report number has just come in, make sure no old ones linger. If there was a
+ * measurement report number gap, also clear out those numbers, to make sure we only keep recent
+ * measurement reports.
+ * [10, 11, 12, 14, 15 <-last, prev-cycle-> 99, 100, 101]
+ * If, however unlikely, the next incoming report nr were 101, we'd have two reports with the same
+ * number, and 99 and 100 would look like they were quite recent, though they were from the last cycle.
+ */
+static void lchan_clear_meas_rep_nr(struct gsm_lchan *lchan, uint8_t new_nr)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(lchan->meas_rep); i++) {
+ struct gsm_meas_rep *meas_rep = &lchan->meas_rep[i];
+ bool clear;
+ if (lchan->meas_rep_last_seen_nr < new_nr) {
+ /* no wrap around 255 involved. e.g. last = 10, new_nr = 15, drop 11..15 */
+ clear = new_nr > lchan->meas_rep_last_seen_nr
+ && meas_rep->nr <= new_nr;
+ } else {
+ /* new number is past 255 wrap.
+ * e.g. last = 253; new_nr = 4; drop 254..4. */
+ clear = meas_rep->nr > lchan->meas_rep_last_seen_nr
+ || meas_rep->nr <= new_nr;
+ }
+ if (clear)
+ *meas_rep = (struct gsm_meas_rep){};
+ }
+}
+
static void lchan_rx_meas_rep(struct gsm_lchan *lchan, const struct gsm_meas_rep *new_meas_rep)
{
struct gsm_meas_rep *meas_rep;
+ lchan_clear_meas_rep_nr(lchan, new_meas_rep->nr);
+
meas_rep = &lchan->meas_rep[lchan->meas_rep_idx];
*meas_rep = *new_meas_rep;