diff options
-rw-r--r-- | include/osmo-bts/measurement.h | 2 | ||||
-rw-r--r-- | src/common/measurement.c | 5 | ||||
-rw-r--r-- | tests/meas/meas_test.c | 133 | ||||
-rw-r--r-- | tests/meas/meas_test.ok | 25 |
4 files changed, 163 insertions, 2 deletions
diff --git a/include/osmo-bts/measurement.h b/include/osmo-bts/measurement.h index 5c3def0e..b4fc35b9 100644 --- a/include/osmo-bts/measurement.h +++ b/include/osmo-bts/measurement.h @@ -12,6 +12,8 @@ void lchan_meas_process_measurement(struct gsm_lchan *lchan, struct bts_ul_meas void lchan_meas_reset(struct gsm_lchan *lchan); +bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_update); + int is_meas_complete(struct gsm_lchan *lchan, uint32_t fn); bool is_meas_overdue(struct gsm_lchan *lchan, uint32_t *fn_missed_end, uint32_t fn); diff --git a/src/common/measurement.c b/src/common/measurement.c index b0ef8694..bc27287c 100644 --- a/src/common/measurement.c +++ b/src/common/measurement.c @@ -27,8 +27,9 @@ static bool array_contains(const uint8_t *arr, unsigned int len, uint8_t val) { return false; } -/* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false) */ -static bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_update) +/* Decide if a given frame number is part of the "-SUB" measurements (true) or not (false) + * (this function is only used internally, it is public to call it from unit-tests) */ +bool ts45008_83_is_sub(struct gsm_lchan *lchan, uint32_t fn, bool is_amr_sid_update) { uint32_t fn104 = fn % 104; diff --git a/tests/meas/meas_test.c b/tests/meas/meas_test.c index 01667718..4009ddb9 100644 --- a/tests/meas/meas_test.c +++ b/tests/meas/meas_test.c @@ -719,6 +719,138 @@ void test_lchan_meas_process_measurement(bool no_sacch, bool dropouts) } } +static bool test_ts45008_83_is_sub_is_sacch(uint32_t fn) +{ + if (fn % 104 == 12) + return true; + if (fn % 104 == 25) + return true; + if (fn % 104 == 38) + return true; + if (fn % 104 == 51) + return true; + if (fn % 104 == 64) + return true; + if (fn % 104 == 77) + return true; + if (fn % 104 == 90) + return true; + if (fn % 104 == 103) + return true; + + return false; +} + +static bool test_ts45008_83_is_sub_is_sub(uint32_t fn, uint8_t ss) +{ + fn = fn % 104; + + if (fn >= 52 && fn <= 59) + return true; + + if (ss == 0) { + if (fn == 0) + return true; + if (fn == 2) + return true; + if (fn == 4) + return true; + if (fn == 6) + return true; + if (fn == 52) + return true; + if (fn == 54) + return true; + if (fn == 56) + return true; + if (fn == 58) + return true; + } else if (ss == 1) { + if (fn == 14) + return true; + if (fn == 16) + return true; + if (fn == 18) + return true; + if (fn == 20) + return true; + if (fn == 66) + return true; + if (fn == 68) + return true; + if (fn == 70) + return true; + if (fn == 72) + return true; + } else + OSMO_ASSERT(false); + + return false; +} + +static void test_ts45008_83_is_sub_single(uint8_t ts, uint8_t ss, bool fr) +{ + struct gsm_lchan *lchan; + bool rc; + unsigned int i; + + lchan = &trx->ts[ts].lchan[ss]; + + printf("Checking: "); + + if (fr) { + printf("TCH/F"); + lchan->type = GSM_LCHAN_TCH_F; + lchan->ts->pchan = GSM_PCHAN_TCH_F; + lchan->tch_mode = GSM48_CMODE_SPEECH_V1; + } else { + printf("TCH/H"); + lchan->type = GSM_LCHAN_TCH_H; + lchan->ts->pchan = GSM_PCHAN_TCH_H; + lchan->tch_mode = GSM48_CMODE_SPEECH_V1; + } + + printf(" TS=%u ", ts); + printf("SS=%u", ss); + + /* Walk trough the first 100 intervals and check for unexpected + * results (false positive and false negative) */ + for (i = 0; i < 104 * 100; i++) { + rc = ts45008_83_is_sub(lchan, i, false); + if (rc) { + if (!test_ts45008_83_is_sub_is_sacch(i) + && !test_ts45008_83_is_sub_is_sub(i, ss)) { + printf("==> Unexpected SUB frame at fn=%u", i); + OSMO_ASSERT(false); + } + } else { + if (test_ts45008_83_is_sub_is_sacch(i) + && test_ts45008_83_is_sub_is_sub(i, ss)) { + printf("==> Unexpected non-SUB frame at fn=%u", + i); + OSMO_ASSERT(false); + } + } + } + printf("\n"); +} + +static void test_ts45008_83_is_sub(void) +{ + unsigned int i; + + printf("\n\n"); + printf("===========================================================\n"); + printf("Testing ts45008_83_is_sub()\n"); + + for (i = 0; i < 7; i++) + test_ts45008_83_is_sub_single(i, 0, true); + for (i = 0; i < 7; i++) + test_ts45008_83_is_sub_single(i, 0, false); + for (i = 0; i < 7; i++) + test_ts45008_83_is_sub_single(i, 1, false); +} + int main(int argc, char **argv) { void *tall_bts_ctx; @@ -785,6 +917,7 @@ int main(int argc, char **argv) test_lchan_meas_process_measurement(true, false); test_lchan_meas_process_measurement(false, true); test_lchan_meas_process_measurement(true, true); + test_ts45008_83_is_sub(); printf("Success\n"); diff --git a/tests/meas/meas_test.ok b/tests/meas/meas_test.ok index d8f81744..ac32acf6 100644 --- a/tests/meas/meas_test.ok +++ b/tests/meas/meas_test.ok @@ -1055,4 +1055,29 @@ 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) + + +=========================================================== +Testing ts45008_83_is_sub() +Checking: TCH/F TS=0 SS=0 +Checking: TCH/F TS=1 SS=0 +Checking: TCH/F TS=2 SS=0 +Checking: TCH/F TS=3 SS=0 +Checking: TCH/F TS=4 SS=0 +Checking: TCH/F TS=5 SS=0 +Checking: TCH/F TS=6 SS=0 +Checking: TCH/H TS=0 SS=0 +Checking: TCH/H TS=1 SS=0 +Checking: TCH/H TS=2 SS=0 +Checking: TCH/H TS=3 SS=0 +Checking: TCH/H TS=4 SS=0 +Checking: TCH/H TS=5 SS=0 +Checking: TCH/H TS=6 SS=0 +Checking: TCH/H TS=0 SS=1 +Checking: TCH/H TS=1 SS=1 +Checking: TCH/H TS=2 SS=1 +Checking: TCH/H TS=3 SS=1 +Checking: TCH/H TS=4 SS=1 +Checking: TCH/H TS=5 SS=1 +Checking: TCH/H TS=6 SS=1 Success |