From f957469956a10a21abe788314fd99feab5dcf224 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Wed, 10 Oct 2018 14:55:34 +0200 Subject: 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 --- src/osmo-bsc/abis_rsl.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) 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; -- cgit v1.2.3