From 324a3cd66e96f9ce901dc540d5c11bd7e434cf8a Mon Sep 17 00:00:00 2001 From: Philipp Maier Date: Tue, 28 Aug 2018 16:59:35 +0200 Subject: measurement: fix is_meas_overdue() and increase testcoverage The tests TC_meas_res_sign_sdcch4 and TC_meas_res_sign_sdcch8 are failing mainly because lchan->ts->nr is confused with lchan->nr. There is also a small problem with one of the formulas that compute fn_missed_end. - Add explainatory comment to the lookup tables on what the index is refering to - use lchan-nr instead of lchan->ts->nr when dealing with SDCCH/4/8 - simplfy and fix the formula - increase the testcoverage of the unit tests, give SDCCH/4/8 also a thorough check. Change-Id: I5d555a21003943bf720c53f3a611029ba45339a9 Related: OS#2975 --- src/common/measurement.c | 22 +++-- tests/meas/meas_test.c | 216 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 7 deletions(-) diff --git a/src/common/measurement.c b/src/common/measurement.c index bc27287c..7b414374 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -115,7 +115,10 @@ bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_upd * 4 4 and 5 52 to 51 64, 90, 12, 38 * 5 4 and 5 65 to 64 77, 103, 25, 51 * 6 6 and 7 78 to 77 90, 12, 38, 64 - * 7 6 and 7 91 to 90 103, 25, 51, 77 */ + * 7 6 and 7 91 to 90 103, 25, 51, 77 + * + * Note: The array index of the following three lookup tables refes to a + * timeslot number. */ static const uint8_t tchf_meas_rep_fn104[] = { [0] = 90, @@ -156,7 +159,10 @@ static const uint8_t tchh1_meas_rep_fn104[] = { * * SDCCH/8 12 to 11 * SDCCH/4 37 to 36 - */ + * + * + * Note: The array index of the following three lookup tables refes to a + * subslot number. */ /* FN of the first burst whose block completes before reaching fn%102=11 */ static const uint8_t sdcch8_meas_rep_fn102[] = { @@ -311,6 +317,7 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t { uint32_t fn_mod; uint32_t last_fn_mod; + uint32_t fn_rounded; uint8_t interval_end; uint8_t modulus; const uint8_t *tbl; @@ -341,12 +348,12 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t case GSM_PCHAN_SDCCH8_SACCH8C: case GSM_PCHAN_SDCCH8_SACCH8C_CBCH: modulus = 102; - interval_end = sdcch8_meas_rep_fn102[lchan->ts->nr]; + interval_end = sdcch8_meas_rep_fn102[lchan->nr]; break; case GSM_PCHAN_CCCH_SDCCH4: case GSM_PCHAN_CCCH_SDCCH4_CBCH: modulus = 102; - interval_end = sdcch4_meas_rep_fn102[lchan->ts->nr]; + interval_end = sdcch4_meas_rep_fn102[lchan->nr]; break; default: return false; @@ -355,6 +362,7 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t fn_mod = fn % modulus; last_fn_mod = lchan->meas.last_fn % modulus; + fn_rounded = fn - fn_mod; if (fn_mod > last_fn_mod) { /* When the current frame number is larger then the last frame @@ -362,7 +370,7 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t * 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; + *fn_missed_end = interval_end + fn_rounded; return true; } } else { @@ -375,7 +383,7 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t if (fn < lchan->meas.last_fn) *fn_missed_end = interval_end + GSM_MAX_FN - modulus; else - *fn_missed_end = interval_end + fn - modulus; + *fn_missed_end = interval_end + fn_rounded - modulus; return true; } /* We also check the section that starts from the beginning of @@ -384,7 +392,7 @@ bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t if (fn < lchan->meas.last_fn) *fn_missed_end = interval_end; else - *fn_missed_end = interval_end + fn - fn_mod; + *fn_missed_end = interval_end + fn_rounded; return true; } } diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c index 4009ddb9..680c1c30 100644 --- a/tests/meas/meas_test.c +++ b/tests/meas/meas_test.c @@ -482,6 +482,222 @@ static void test_is_meas_overdue(void) rc = is_meas_overdue(lchan, &fn_missed_end, GSM_MAX_FN - 1); OSMO_ASSERT(!rc); OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* Missing period-end-trigger at fn=66, SDCCH/8, TS0, SS0 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[0]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 47; + rc = is_meas_overdue(lchan, &fn_missed_end, 15 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 66); + + /* Missing period-end-trigger at fn=70, SDCCH/8, TS0, SS1 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[1]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 51; + rc = is_meas_overdue(lchan, &fn_missed_end, 19 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 70); + + /* Missing period-end-trigger at fn=74, SDCCH/8, TS0, SS2 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[2]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 55; + rc = is_meas_overdue(lchan, &fn_missed_end, 23 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 74); + + /* Missing period-end-trigger at fn=78, SDCCH/8, TS0, SS3 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[3]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 59; + rc = is_meas_overdue(lchan, &fn_missed_end, 27 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 78); + + /* Missing period-end-trigger at fn=98, SDCCH/8, TS0, SS4 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[4]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 82; + rc = is_meas_overdue(lchan, &fn_missed_end, 31 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 98); + + /* Missing period-end-trigger at fn=102, SDCCH/8, TS0, SS5 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[5]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 86; + rc = is_meas_overdue(lchan, &fn_missed_end, 35 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 102); + + /* Missing period-end-trigger at fn=106, SDCCH/8, TS0, SS6 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[6]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 90; + rc = is_meas_overdue(lchan, &fn_missed_end, 39 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 4 + 102); + + /* Missing period-end-trigger at fn=200, SDCCH/8, TS0, SS7 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[7]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 94; + rc = is_meas_overdue(lchan, &fn_missed_end, 43 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 8 + 102); + + /* No dropout, SDCCH/8, TS0, SS0 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[0]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 47; + rc = is_meas_overdue(lchan, &fn_missed_end, 66); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS1 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[1]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 51; + rc = is_meas_overdue(lchan, &fn_missed_end, 70); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS2 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[2]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 55; + rc = is_meas_overdue(lchan, &fn_missed_end, 74); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS3 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[3]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 59; + rc = is_meas_overdue(lchan, &fn_missed_end, 78); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS4 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[4]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 82; + rc = is_meas_overdue(lchan, &fn_missed_end, 98); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS5 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[5]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 86; + rc = is_meas_overdue(lchan, &fn_missed_end, 102); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS6 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[6]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 90; + rc = is_meas_overdue(lchan, &fn_missed_end, 4 + 102); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/8, TS0, SS7 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[7]; + lchan->ts->pchan = GSM_PCHAN_SDCCH8_SACCH8C; + lchan->meas.last_fn = 94; + rc = is_meas_overdue(lchan, &fn_missed_end, 8 + 102); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* Missing period-end-trigger at fn=88, SDCCH/4, TS0, SS0 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[0]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 57; + rc = is_meas_overdue(lchan, &fn_missed_end, 37 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 88); + + /* Missing period-end-trigger at fn=92, SDCCH/4, TS0, SS1 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[1]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 61; + rc = is_meas_overdue(lchan, &fn_missed_end, 41 + 102); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 92); + + /* Missing period-end-trigger at fn=6, SDCCH/4, TS0, SS2 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[2]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = GSM_MAX_FN - 102 + 98; + rc = is_meas_overdue(lchan, &fn_missed_end, 47); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 6); + + /* Missing period-end-trigger at fn=10, SDCCH/4, TS0, SS3 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[3]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 0; + rc = is_meas_overdue(lchan, &fn_missed_end, 51); + OSMO_ASSERT(rc); + OSMO_ASSERT(fn_missed_end == 10); + + /* No dropout, SDCCH/4, TS0, SS0 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[0]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 57; + rc = is_meas_overdue(lchan, &fn_missed_end, 88); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/4, TS0, SS1 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[1]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 61; + rc = is_meas_overdue(lchan, &fn_missed_end, 92); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/4, TS0, SS2 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[2]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = GSM_MAX_FN - 102 + 98; + rc = is_meas_overdue(lchan, &fn_missed_end, 6); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); + + /* No dropout, SDCCH/4, TS0, SS3 */ + fn_missed_end = LCHAN_FN_DUMMY; + lchan = &trx->ts[0].lchan[3]; + lchan->ts->pchan = GSM_PCHAN_CCCH_SDCCH4; + lchan->meas.last_fn = 0; + rc = is_meas_overdue(lchan, &fn_missed_end, 10); + OSMO_ASSERT(!rc); + OSMO_ASSERT(fn_missed_end == LCHAN_FN_DUMMY); } static void test_is_meas_complete_single(struct gsm_lchan *lchan, -- cgit v1.2.3