aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/measurement.c22
-rw-r--r--tests/meas/meas_test.c216
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,