osmo-bts/tests/meas/meas_testcases.h

579 lines
14 KiB
C

#define ULM(ber, ta, sub, neg_rssi) \
{ .ber10k = (ber), .ta_offs_256bits = (ta), .ci_cb = 10, .is_sub = sub, .inv_rssi = (neg_rssi) }
struct meas_testcase {
const char *name;
/* input data */
const struct bts_ul_meas *ulm;
unsigned int ulm_count;
uint32_t final_fn;
uint8_t ts;
enum gsm_phys_chan_config pchan;
/* results */
struct {
int success;
uint8_t rx_lev_full;
uint8_t rx_qual_full;
int16_t toa256_mean;
int16_t toa256_min;
int16_t toa256_max;
uint16_t toa256_std_dev;
} res;
};
static struct bts_ul_meas ulm1[] = {
/* Note: The assumptions about the frame number and the subset
* allegiance is random since for the calculation only the amount
* is of relevance. This is true for all following testcases */
ULM(0, 0, 0, 90),
ULM(0, 256, 0, 90),
ULM(0, -256, 0, 90),
};
static const struct meas_testcase mtc1 = {
.name = "TOA256 Min-Max negative/positive",
.ulm = ulm1,
.ulm_count = ARRAY_SIZE(ulm1),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 110-90,
.rx_qual_full = 0,
.toa256_mean = 0,
.toa256_max = 256,
.toa256_min = -256,
.toa256_std_dev = 209,
},
};
static struct bts_ul_meas ulm2[] = {
ULM(0, 256, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 1, 90),
ULM(0, 256, 0, 90),
ULM(0, 256, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 1, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 256, 1, 90),
ULM(0, 256, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 256, 0, 90),
ULM(0, 256, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 258, 0, 90),
ULM(0, 254, 0, 90),
ULM(0, 256, 0, 90),
ULM(0, 256, 0, 90),
};
static const struct meas_testcase mtc2 = {
.name = "TOA256 small jitter around 256",
.ulm = ulm2,
.ulm_count = ARRAY_SIZE(ulm2),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 110-90,
.rx_qual_full = 7,
.toa256_mean = 256,
.toa256_max = 258,
.toa256_min = 254,
.toa256_std_dev = 1,
},
};
static struct bts_ul_meas ulm3[] = {
ULM(0, 0, 0, 90),
ULM(0, 0, 0, 80),
ULM(0, 0, 0, 80),
ULM(0, 0, 0, 100),
ULM(0, 0, 0, 100),
};
static const struct meas_testcase mtc3 = {
.name = "RxLEv averaging",
.ulm = ulm3,
.ulm_count = ARRAY_SIZE(ulm3),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 110-90,
.rx_qual_full = 0,
.toa256_mean = 0,
.toa256_max = 0,
.toa256_min = 0,
.toa256_std_dev = 0,
},
};
static struct bts_ul_meas ulm4[] = {};
static const struct meas_testcase mtc4 = {
.name = "Empty measurements",
.ulm = ulm4,
.ulm_count = ARRAY_SIZE(ulm4),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 1,
.rx_qual_full = 7,
.toa256_mean = 0,
.toa256_max = 0,
.toa256_min = 0,
.toa256_std_dev = 0,
},
};
static struct bts_ul_meas ulm5[] = {
/* one 104 multiframe can at max contain 26 blocks (TCH/F),
* each of which can at maximum be 64 bits in advance (TA range) */
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
};
static const struct meas_testcase mtc5 = {
.name = "TOA256 26 blocks with max TOA256",
.ulm = ulm5,
.ulm_count = ARRAY_SIZE(ulm5),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 110-90,
.rx_qual_full = 0,
.toa256_mean = 64*256,
.toa256_max = 64*256,
.toa256_min = 64*256,
.toa256_std_dev = 0,
},
};
/* This testcase models a good case as we can see it when all TCH
* and SACCH blocks are received */
static struct bts_ul_meas ulm_tch_f_complete[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
};
static const struct meas_testcase mtc_tch_f_complete = {
.name = "Complete TCH/F measurement period (26 measurements, 3 sub-frames)",
.ulm = ulm_tch_f_complete,
.ulm_count = ARRAY_SIZE(ulm_tch_f_complete),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 0,
.toa256_mean = 64*256,
.toa256_max = 64*256,
.toa256_min = 64*256,
.toa256_std_dev = 0,
},
};
/* This testcase models an error case where two of 3 expected sub measurements
* are lost. The calculation logic must detect this and replace those
* measurements. Note that this example also lacks some blocks due to DTX,
* which is normal. */
static struct bts_ul_meas ulm_tch_f_dtx_with_lost_subs[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
};
static const struct meas_testcase mtc_tch_f_dtx_with_lost_subs = {
/* This testcase models a good case as we can see it when all TCH
* and SACCH blocks are received */
.name = "Incomplete TCH/F measurement period (16 measurements, 1 sub-frame)",
.ulm = ulm_tch_f_dtx_with_lost_subs,
.ulm_count = ARRAY_SIZE(ulm_tch_f_dtx_with_lost_subs),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 7,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};
/* This testcase models a good-case with DTX. Some measurements are missing
* because no block was transmitted, all sub measurements are there. */
static struct bts_ul_meas ulm_tch_f_dtx[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
};
static const struct meas_testcase mtc_tch_f_dtx = {
.name = "Incomplete but normal TCH/F measurement period (16 measurements, 3 sub-frames)",
.ulm = ulm_tch_f_dtx,
.ulm_count = ARRAY_SIZE(ulm_tch_f_dtx),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 7,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};
/* This testcase models a good case as we can see it when all TCH
* and SACCH blocks are received */
static struct bts_ul_meas ulm_tch_h_complete[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
};
static const struct meas_testcase mtc_tch_h_complete = {
.name = "Complete TCH/H measurement period (26 measurements, 5 sub-frames)",
.ulm = ulm_tch_h_complete,
.ulm_count = ARRAY_SIZE(ulm_tch_h_complete),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_H,
.res = {
.success = 1,
.rx_lev_full = 110 - 90,
.rx_qual_full = 0,
.toa256_mean = 64*256,
.toa256_max = 64*256,
.toa256_min = 64*256,
.toa256_std_dev = 0,
},
};
static struct bts_ul_meas ulm_tch_h_dtx_with_lost_subs[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
};
static const struct meas_testcase mtc_tch_h_dtx_with_lost_subs = {
.name = "Incomplete TCH/H measurement period (14 measurements, 3 sub-frames)",
.ulm = ulm_tch_h_dtx_with_lost_subs,
.ulm_count = ARRAY_SIZE(ulm_tch_h_dtx_with_lost_subs),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_H,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 7,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};
/* This testcase models a good-case with DTX. Some measurements are missing
* because no block was transmitted, all sub measurements are there. */
static struct bts_ul_meas ulm_tch_h_dtx[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
};
static const struct meas_testcase mtc_tch_h_dtx = {
.name = "Incomplete but normal TCH/F measurement period (16 measurements, 5 sub-frames)",
.ulm = ulm_tch_h_dtx,
.ulm_count = ARRAY_SIZE(ulm_tch_h_dtx),
.final_fn = 38,
.ts = 2,
.pchan = GSM_PCHAN_TCH_H,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 7,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};
/* This testcase assumes that too many measurements were collected. This can
* happen when the measurement calculation for a previous cycle were not
* executed. In this case the older part of the excess data must be discarded.
* the calculation algorithm must make sure that the calculation only takes
* place on the last measurement interval */
static struct bts_ul_meas ulm_overrun[] = {
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
/* All measurements above must be discarded */
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
ULM(0, 64*256, 0, 90),
};
static const struct meas_testcase mtc_overrun = {
.name = "TCH/F measurement period with too much measurement values (overrun)",
.ulm = ulm_overrun,
.ulm_count = ARRAY_SIZE(ulm_overrun),
.final_fn = 25,
.ts = 1,
.pchan = GSM_PCHAN_TCH_F,
.res = {
.success = 1,
.rx_lev_full = 110 - 90,
.rx_qual_full = 0,
.toa256_mean = 64*256,
.toa256_max = 64*256,
.toa256_min = 64*256,
.toa256_std_dev = 0,
},
};
/* Test SDCCH4 with all frames received */
static struct bts_ul_meas ulm_sdcch4_complete[] = {
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 1, 90),
};
static const struct meas_testcase mtc_sdcch4_complete = {
.name = "Complete SDCCH4 measurement period (3 measurements)",
.ulm = ulm_sdcch4_complete,
.ulm_count = ARRAY_SIZE(ulm_sdcch4_complete),
.final_fn = 88,
.ts = 0,
.pchan = GSM_PCHAN_CCCH_SDCCH4,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 0,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};
/* Test SDCCH8 with all frames received */
static struct bts_ul_meas ulm_sdcch8_complete[] = {
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 1, 90),
ULM(0, 64*256, 1, 90),
};
static const struct meas_testcase mtc_sdcch8_complete = {
.name = "Complete SDCCH8 measurement period (3 measurements)",
.ulm = ulm_sdcch8_complete,
.ulm_count = ARRAY_SIZE(ulm_sdcch8_complete),
.final_fn = 66,
.ts = 0,
.pchan = GSM_PCHAN_SDCCH8_SACCH8C,
.res = {
.success = 1,
.rx_lev_full = 20,
.rx_qual_full = 0,
.toa256_mean = 16384,
.toa256_max = 16384,
.toa256_min = 16384,
.toa256_std_dev = 0,
},
};