aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmo-bts/gsm_data_shared.h2
-rw-r--r--include/osmo-bts/measurement.h2
-rw-r--r--src/common/measurement.c156
-rw-r--r--tests/meas/meas_test.c440
-rw-r--r--tests/meas/meas_test.ok478
5 files changed, 1072 insertions, 6 deletions
diff --git a/include/osmo-bts/gsm_data_shared.h b/include/osmo-bts/gsm_data_shared.h
index baa01454..794eaeae 100644
--- a/include/osmo-bts/gsm_data_shared.h
+++ b/include/osmo-bts/gsm_data_shared.h
@@ -260,6 +260,8 @@ struct gsm_lchan {
uint8_t l1_info[2];
struct gsm_meas_rep_unidir ul_res;
int16_t ms_toa256;
+ /* Frame number of the last measurement indication receceived */
+ uint32_t last_fn;
/* Osmocom extended measurement results, see LC_UL_M_F_EXTD_VALID */
struct {
/* minimum value of toa256 during measurement period */
diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h
index d98e9f0b..57eeef5b 100644
--- a/include/osmo-bts/measurement.h
+++ b/include/osmo-bts/measurement.h
@@ -12,4 +12,6 @@ void lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas
void lchan_meas_reset(struct gsm_lchan *lchan);
+bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t fn);
+
#endif
diff --git a/src/common/measurement.c b/src/common/measurement.c
index bd2c0b79..41844b1f 100644
--- a/src/common/measurement.c
+++ b/src/common/measurement.c
@@ -9,6 +9,7 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/measurement.h>
#include <osmo-bts/scheduler.h>
+#include <osmo-bts/rsl.h>
/* Tables as per TS 45.008 Section 8.3 */
static const uint8_t ts45008_83_tch_f[] = { 52, 53, 54, 55, 56, 57, 58, 59 };
@@ -217,6 +218,32 @@ static uint8_t translate_tch_meas_rep_fn104(uint8_t fn_mod)
return 0;
}
+/* Same as above, but the inverse function */
+static uint8_t translate_tch_meas_rep_fn104_inv(uint8_t fn_mod)
+{
+ switch (fn_mod) {
+ case 103:
+ return 25;
+ case 12:
+ return 38;
+ case 25:
+ return 51;
+ case 38:
+ return 64;
+ case 51:
+ return 77;
+ case 64:
+ return 90;
+ case 77:
+ return 103;
+ case 90:
+ return 12;
+ }
+
+ /* Invalid / not of interest */
+ return 0;
+}
+
/* determine if a measurement period ends at the given frame number */
static int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
{
@@ -271,7 +298,101 @@ static int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn)
return rc;
}
-/* receive a L1 uplink measurement from L1 */
+/* Check if a measurement period is overdue. This situation may occur when the
+ * SACCH frame that closes the measurement interval was not received. Then the
+ * end of the measurement will not be detected. Using this function we can
+ * detect if we missed a measurement period end and we also find the frame
+ * number of the lost SACCH frame. (this function is only used internally,
+ * it is public to call it from unit-tests) */
+bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t fn)
+{
+ uint32_t fn_mod;
+ uint32_t last_fn_mod;
+ uint8_t interval_end;
+ uint8_t modulus;
+ const uint8_t *tbl;
+ enum gsm_phys_chan_config pchan = ts_pchan(lchan->ts);
+
+ /* On the very first measurement we will not be able to do this check
+ * as we do not have a reference yet. So we have to assume that we
+ * did not miss the interval end yet. */
+ if (lchan->meas.last_fn == LCHAN_FN_DUMMY)
+ return false;
+
+ /* Determine the interval ending and the modulus to calculate with */
+ switch (pchan) {
+ case GSM_PCHAN_TCH_F:
+ modulus = 104;
+ interval_end = tchf_meas_rep_fn104[lchan->ts->nr];
+ interval_end = translate_tch_meas_rep_fn104_inv(interval_end);
+ break;
+ case GSM_PCHAN_TCH_H:
+ modulus = 104;
+ last_fn_mod = lchan->meas.last_fn % 104;
+ if (lchan->nr == 0)
+ tbl = tchh0_meas_rep_fn104;
+ else
+ tbl = tchh1_meas_rep_fn104;
+ interval_end = tbl[lchan->ts->nr];
+ interval_end = translate_tch_meas_rep_fn104_inv(interval_end);
+ break;
+ case GSM_PCHAN_SDCCH8_SACCH8C:
+ case GSM_PCHAN_SDCCH8_SACCH8C_CBCH:
+ modulus = 102;
+ last_fn_mod = lchan->meas.last_fn % 102;
+ interval_end = sdcch8_meas_rep_fn102[lchan->ts->nr];
+ break;
+ case GSM_PCHAN_CCCH_SDCCH4:
+ case GSM_PCHAN_CCCH_SDCCH4_CBCH:
+ modulus = 102;
+ interval_end = sdcch8_meas_rep_fn102[lchan->ts->nr];
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ fn_mod = fn % modulus;
+ last_fn_mod = lchan->meas.last_fn % modulus;
+
+ if (fn_mod > last_fn_mod) {
+ /* When the current frame number is larger then the last frame
+ * number we check if the interval ending falls in between
+ * the two. If it does we calculate the absolute frame number
+ * position on which the interval should have ended. */
+ if (interval_end > last_fn_mod && interval_end < fn_mod) {
+ *fn_missed_end = interval_end + fn - fn_mod;
+ return true;
+ }
+ } else {
+ /* When the current frame number is smaller then the last frame
+ * number, than the modulus interval has wrapped. We then just
+ * check the presence of the interval ending in the section
+ * that starts at the current frame number and ends at the
+ * interval end. */
+ if (interval_end > last_fn_mod) {
+ if (fn < lchan->meas.last_fn)
+ *fn_missed_end = interval_end + GSM_MAX_FN - modulus;
+ else
+ *fn_missed_end = interval_end + fn - modulus;
+ return true;
+ }
+ /* We also check the section that starts from the beginning of
+ * the interval and ends at the current frame number. */
+ if (interval_end < fn_mod) {
+ if (fn < lchan->meas.last_fn)
+ *fn_missed_end = interval_end;
+ else
+ *fn_missed_end = interval_end + fn - fn_mod;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/* receive a L1 uplink measurement from L1 (this function is only used
+ * internally, it is public to call it from unit-tests) */
int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn)
{
if (lchan->state != LCHAN_S_ACTIVE) {
@@ -299,6 +420,8 @@ int lchan_new_ul_meas(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t
memcpy(&lchan->meas.uplink[lchan->meas.num_ul_meas++], ulm,
sizeof(*ulm));
+ lchan->meas.last_fn = fn;
+
return 0;
}
@@ -484,11 +607,31 @@ int lchan_meas_check_compute(struct gsm_lchan *lchan, uint32_t fn)
* interval. */
void lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas *ulm, uint32_t fn)
{
- lchan_new_ul_meas(lchan, ulm, fn);
-
- /* Check measurement period end and prepare the UL
- * measurment report at Meas period End */
- lchan_meas_check_compute(lchan, fn);
+ uint32_t fn_missed_end;
+ bool missed_end;
+
+ /* The measurement processing detects the end of a measurement period
+ * by checking if the received measurement sample is from a SACCH
+ * block. If so, then the measurement computation is performed and the
+ * next cycle starts. However, when the SACCH block is not received
+ * then the associated measurement indication is also skipped. Because
+ * of this we must check now if the measurement interval ended between
+ * the last and the current call of this function */
+ missed_end = is_meas_overdue(lchan, &fn_missed_end, fn);
+
+ if (missed_end) {
+ DEBUGPFN(DMEAS, fn, "%s measurement interval ending missed, catching up...\n", gsm_lchan_name(lchan));
+ /* We missed the end of the interval. Do the computation now
+ * and add the uplink measurement we got as the first sample
+ * of a new interval */
+ lchan_meas_check_compute(lchan, fn_missed_end);
+ lchan_new_ul_meas(lchan, ulm, fn);
+ } else {
+ /* This is the normal case, we first add the measurement sample
+ * to the current interva and run the check+computation */
+ lchan_new_ul_meas(lchan, ulm, fn);
+ lchan_meas_check_compute(lchan, fn);
+ }
}
/* Reset all measurement related struct members to their initial values. This
@@ -497,4 +640,5 @@ void lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas
void lchan_meas_reset(struct gsm_lchan *lchan)
{
memset(&lchan->meas, 0, sizeof(lchan->meas));
+ lchan->meas.last_fn = LCHAN_FN_DUMMY;
}
diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c
index 2ba44d38..d40d7cde 100644
--- a/tests/meas/meas_test.c
+++ b/tests/meas/meas_test.c
@@ -9,6 +9,7 @@
#include <osmo-bts/logging.h>
#include <osmo-bts/bts.h>
#include <osmo-bts/measurement.h>
+#include <osmo-bts/rsl.h>
static struct gsm_bts *bts;
struct gsm_bts_trx *trx;
@@ -117,6 +118,434 @@ static void test_meas_compute(const struct meas_testcase *mtc)
}
+/* This tests the function is_meas_overdue() and since is_meas_overdue()
+ * internally makes use of is_meas_complete(), this also gives
+ * is_meas_complete() a detailed check. */
+static void test_is_meas_overdue(void)
+{
+ struct gsm_lchan *lchan;
+ bool rc;
+ uint32_t fn_missed_end;
+ unsigned int i;
+
+ printf("\n\n");
+ printf("===========================================================\n");
+ printf("Testing is_meas_overdue() and is_meas_complete()\n");
+
+ /* Missing period-end-trigger at fn=12, TCH/F, TS0 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 95;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 17 + 104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 12 + 104);
+
+ /* Missing period-end-trigger at fn=12, TCH/H, TS0 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 95;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 17 + 104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 12 + 104);
+
+ /* Missing period-end-trigger at fn=12, TCH/H, TS1 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[1].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 95;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 17 + 104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 12 + 104);
+
+ /* Missing period-end-trigger at fn=25, TCH/F, TS1 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[1].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 21;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 30);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 25);
+
+ /* Missing period-end-trigger at fn=25, TCH/H, TS0 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 21;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 30);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 25);
+
+ /* Missing period-end-trigger at fn=25, TCH/H, TS1 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[1].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 21;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 30);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 25);
+
+ /* Missing period-end-trigger at fn=38, TCH/F, TS2 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 34;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 43);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 38);
+
+ /* Missing period-end-trigger at fn=38, TCH/H, TS2 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 34;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 43);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 38);
+
+ /* Missing period-end-trigger at fn=38, TCH/H, TS3 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[3].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 34;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 43);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 38);
+
+ /* Missing period-end-trigger at fn=51, TCH/F, TS3 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[3].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 47;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 52);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 51);
+
+ /* Missing period-end-trigger at fn=51, TCH/H, TS2 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 47;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 52);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 51);
+
+ /* Missing period-end-trigger at fn=51, TCH/H, TS3 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[3].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 47;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 52);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 51);
+
+ /* Missing period-end-trigger at fn=64, TCH/F, TS4 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[4].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 60;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 69);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 64);
+
+ /* Missing period-end-trigger at fn=64, TCH/H, TS4 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[4].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 60;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 69);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 64);
+
+ /* Missing period-end-trigger at fn=64, TCH/H, TS4 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[5].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 60;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 69);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 64);
+
+ /* Missing period-end-trigger at fn=77, TCH/F, TS5 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[5].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 73;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 78);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 77);
+
+ /* Missing period-end-trigger at fn=77, TCH/H, TS4 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[4].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 73;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 78);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 77);
+
+ /* Missing period-end-trigger at fn=77, TCH/H, TS5 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[5].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 73;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 78);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 77);
+
+ /* Missing period-end-trigger at fn=90, TCH/F, TS6 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[6].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 86;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 91);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 90);
+
+ /* Missing period-end-trigger at fn=90, TCH/H, TS6 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[6].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 86;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 91);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 90);
+
+ /* Missing period-end-trigger at fn=90, TCH/H, TS7 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[7].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 86;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 91);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 90);
+
+ /* Missing period-end-trigger at fn=103, TCH/F, TS7 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[7].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 0+104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 103);
+
+ /* Missing period-end-trigger at fn=103, TCH/H, TS6 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[6].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 0+104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 103);
+
+ /* Missing period-end-trigger at fn=103, TCH/H, TS7 */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[7].lchan[1];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 0+104);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 103);
+
+ /* Dropout inside the interval, no period-end-trigger missed */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 56;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 69);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, but right after period-end-trigger */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 38;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 39);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, two neigbouring frames at random position
+ * (should not happen in the real world) */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 43;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 44);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, Two neigbouring frames (period end, right side) */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 38;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 39);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, Two neigbouring frames (period end, left side,
+ * should not happen in the real world) */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 37;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 38);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, test directly on a the trigger frame */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 34;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 38);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* No dropout, previous frame is trigger frame
+ * (should not happen in the real world) */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_H;
+ lchan->meas.last_fn = 38;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 38);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* Missing period-end-trigger at fn=38+i*104, TCH/F, TS2 to
+ * see the modulus is correct. */
+ for (i = 0; i < 100; i++) {
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[2].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = 34 + 104 * 1;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 43 + 104 * 1);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 38 + 104 * 1);
+ }
+
+ /* See whats happening if we miss a period-end-triggerend at the
+ * hyperframe beginning. */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+95;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 17);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == 12);
+
+ /* See whats happening if we miss a period-end-triggerend at the
+ * hyperframe ending. */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[6].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+86;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 8);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == GSM_MAX_FN-104+90);
+
+ /* See whats happening if we miss a period-end-triggerend exactly at the
+ * hyperframe ending. */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[7].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 0);
+ OSMO_ASSERT(rc);
+ OSMO_ASSERT(fn_missed_end == GSM_MAX_FN-1);
+
+ /* Test a wrap around at the hyperframe ending, while no measurements
+ * are lost */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 0);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* Test a wrap around at the hyperframe ending, measurements are lost,
+ * but not the one that triggers the period end */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[0].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+95;
+ rc = is_meas_overdue(lchan, &fn_missed_end, 4);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+
+ /* Test a wrap around right before the hyperframe ending, while no
+ * measurements are lost. */
+ fn_missed_end = LCHAN_FN_DUMMY;
+ lchan = &trx->ts[7].lchan[0];
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ lchan->meas.last_fn = GSM_MAX_FN-104+99;
+ rc = is_meas_overdue(lchan, &fn_missed_end, GSM_MAX_FN-1);
+ OSMO_ASSERT(!rc);
+ OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY);
+}
+
+/* This tests the robustness of lchan_meas_process_measurement(). This is the
+ * function that is called from l1_sap.c each time a measurement indication is
+ * received. The process must still go on when measurement indications (blocks)
+ * are lost or otherwise spaced out. Even the complete absence of the
+ * measurement indications from the SACCH which are used to detect the interval
+ * end must not keep the interval from beeing processed. */
+void test_lchan_meas_process_measurement(bool no_sacch, bool dropouts)
+{
+ struct gsm_lchan *lchan = &trx->ts[2].lchan[0];
+ unsigned int i;
+ unsigned int k = 0;
+ unsigned int fn = 0;
+ struct bts_ul_meas ulm;
+
+ printf("\n\n");
+ printf("===========================================================\n");
+ printf("Testing lchan_meas_process_measurement()\n");
+ if (no_sacch)
+ printf(" * SACCH blocks not generated.\n");
+ if (dropouts)
+ printf
+ (" * Simulate dropouts by leaving out every 4th measurement\n");
+
+ ulm.ber10k = 0;
+ ulm.ta_offs_256bits = 256;
+ ulm.c_i = 0;
+ ulm.is_sub = 0;
+ ulm.inv_rssi = 90;
+
+ lchan->ts->pchan = GSM_PCHAN_TCH_F;
+ reset_lchan_meas(lchan);
+
+ /* feed uplink measurements into the code */
+ for (i = 0; i < 100; i++) {
+
+ if (dropouts == false || i % 4)
+ lchan_meas_process_measurement(lchan, &ulm, fn);
+ else
+ printf
+ ("(leaving out measurement sample for frame number %u)\n",
+ fn);
+
+ fn += 4;
+ if (k == 2) {
+ fn++;
+ k = 0;
+ } else
+ k++;
+
+ if (fn % 104 == 39 && no_sacch == false) {
+ printf
+ ("(now adding measurement sample for SACCH block)\n");
+ lchan_meas_process_measurement(lchan, &ulm, fn - 1);
+ } else
+ printf
+ ("(leaving out measurement sample for SACCH block)\n");
+ }
+}
+
int main(int argc, char **argv)
{
void *tall_bts_ctx;
@@ -172,6 +601,17 @@ int main(int argc, char **argv)
test_meas_compute(&mtc4);
test_meas_compute(&mtc5);
+ printf("\n");
+ printf("***************************************************\n");
+ printf("*** MEASUREMENT INTERVAL ENDING DETECTION TESTS ***\n");
+ printf("***************************************************\n");
+
+ test_is_meas_overdue();
+ test_lchan_meas_process_measurement(false, false);
+ test_lchan_meas_process_measurement(true, false);
+ test_lchan_meas_process_measurement(false, true);
+ test_lchan_meas_process_measurement(true, true);
+
printf("Success\n");
return 0;
diff --git a/tests/meas/meas_test.ok b/tests/meas/meas_test.ok
index 026899d6..77b652ea 100644
--- a/tests/meas/meas_test.ok
+++ b/tests/meas/meas_test.ok
@@ -573,4 +573,482 @@ meas.ms_toa256 | 16384 | 16384
meas.ext.toa256_std_dev | 0 | 0
meas.ul_res.full.rx_lev | 20 | 20
meas.ul_res.full.rx_qual | 0 | 0
+
+***************************************************
+*** MEASUREMENT INTERVAL ENDING DETECTION TESTS ***
+***************************************************
+
+
+===========================================================
+Testing is_meas_overdue() and is_meas_complete()
+
+
+===========================================================
+Testing lchan_meas_process_measurement()
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+
+
+===========================================================
+Testing lchan_meas_process_measurement()
+ * SACCH blocks not generated.
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+
+
+===========================================================
+Testing lchan_meas_process_measurement()
+ * Simulate dropouts by leaving out every 4th measurement
+(leaving out measurement sample for frame number 0)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 17)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 34)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 52)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 69)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 86)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 104)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 121)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 138)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 156)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 173)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 190)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 208)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 225)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 242)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 260)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 277)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 294)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 312)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 329)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 346)
+(now adding measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 364)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 381)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 398)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 416)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+
+
+===========================================================
+Testing lchan_meas_process_measurement()
+ * SACCH blocks not generated.
+ * Simulate dropouts by leaving out every 4th measurement
+(leaving out measurement sample for frame number 0)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 17)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 34)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 52)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 69)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 86)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 104)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 121)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 138)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 156)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 173)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 190)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 208)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 225)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 242)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 260)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 277)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 294)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 312)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 329)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 346)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 364)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 381)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 398)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for frame number 416)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
+(leaving out measurement sample for SACCH block)
Success