diff options
-rw-r--r-- | include/osmo-bts/gsm_data_shared.h | 2 | ||||
-rw-r--r-- | include/osmo-bts/measurement.h | 2 | ||||
-rw-r--r-- | src/common/measurement.c | 156 | ||||
-rw-r--r-- | tests/meas/meas_test.c | 440 | ||||
-rw-r--r-- | tests/meas/meas_test.ok | 478 |
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 |