BTS_Tests: introduce and use as_l1_sacch_l1h()

The new altstep reduces code duplication and simplifies access
to the L1 SACCH Header.  It uses dec_SacchL1Header() to decode
the header, and would apply the received TA / MS Power level
values by default (see 'do_apply' parameter).

Change-Id: Ie593d9b06aea694fb0903a6d26ee387d8da4c82d
Related: SYS#4918
This commit is contained in:
Vadim Yanitskiy 2020-11-11 07:02:28 +07:00 committed by laforge
parent 09294d9052
commit ab5769cd74
1 changed files with 66 additions and 68 deletions

View File

@ -1825,6 +1825,25 @@ private altstep as_l1_sacch() runs on ConnHdlr {
}
}
/* handle incoming downlink SACCH, decode the L1 header into the given record */
private altstep as_l1_sacch_l1h(inout SacchL1Header l1h,
boolean do_apply := true)
runs on ConnHdlr
{
var L1ctlDlMessage l1_dl;
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Parse the L1 SACCH header (MS Power Level & Timing Advance) */
l1h := dec_SacchL1Header(substr(l1_dl.payload.data_ind.payload, 0, 2));
log(%definitionId, "(): Rx SACCH L1 header: ", l1h);
if (do_apply) {
/* Update TA and MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, l1h.actual_ta, l1h.ms_power_lvl);
}
}
}
private altstep as_l1_dcch_loop() runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_DCCH(?))) -> value l1_dl {
@ -2563,7 +2582,7 @@ second rssi -110, ms power 7+6, expected decrease to 7 within 6 seconds,
These power levels are valid for all bands and require no special handling */
private function f_TC_rsl_ms_pwr_dyn_ass_updown(charstring id) runs on ConnHdlr {
var uint5_t pwr_var := 7;
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
f_trxc_fake_rssi(rxlev2dbm(10));
f_l1_tune(L1CTL);
@ -2586,10 +2605,8 @@ private function f_TC_rsl_ms_pwr_dyn_ass_updown(charstring id) runs on ConnHdlr
timer T2 := 6.0;
T2.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Update sent MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, oct2int(l1_dl.payload.data_ind.payload[0]));
if (oct2int(l1_dl.payload.data_ind.payload[0]) < (pwr_var + 6)) {
[] as_l1_sacch_l1h(l1h) {
if (l1h.ms_power_lvl < (pwr_var + 6)) {
repeat;
}
T2.stop;
@ -2607,10 +2624,8 @@ private function f_TC_rsl_ms_pwr_dyn_ass_updown(charstring id) runs on ConnHdlr
timer T4 := 6.0;
T4.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Update sent MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, oct2int(l1_dl.payload.data_ind.payload[0]));
if (oct2int(l1_dl.payload.data_ind.payload[0]) > pwr_var) {
[] as_l1_sacch_l1h(l1h) {
if (l1h.ms_power_lvl > pwr_var) {
repeat;
}
T4.stop;
@ -2631,7 +2646,7 @@ private function f_TC_rsl_ms_pwr_dyn_ass_updown(charstring id) runs on ConnHdlr
/* check that we do not exceed the max power */
private function f_TC_rsl_ms_pwr_dyn_max(charstring id) runs on ConnHdlr {
var uint5_t pwr_var := 7;
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
/* set a low value to ensure power increases */
f_trxc_fake_rssi(rxlev2dbm(10));
@ -2652,14 +2667,12 @@ private function f_TC_rsl_ms_pwr_dyn_max(charstring id) runs on ConnHdlr {
timer T1 := 10.0;
T1.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Update sent MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, oct2int(l1_dl.payload.data_ind.payload[0]));
repeat;
}
[] as_l1_sacch_l1h(l1h) { repeat; }
[] L1CTL.receive { repeat; }
[] T1.timeout {
if( oct2int(l1_dl.payload.data_ind.payload[0]) != pwr_var){
if (not isbound(l1h)) {
setverdict(fail, "No SACCH blocks were received");
} else if (l1h.ms_power_lvl != pwr_var) {
setverdict(fail, "Power level in L1 header should not have changed");
}
}
@ -2672,7 +2685,7 @@ private function f_TC_rsl_ms_pwr_dyn_max(charstring id) runs on ConnHdlr {
/* see if we reach the band max power */
private function f_TC_rsl_ms_pwr_dyn_up(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
var uint5_t pwr_var := 15;
var uint5_t pwr_max_var := f_get_max_power_from_band();
@ -2698,19 +2711,16 @@ private function f_TC_rsl_ms_pwr_dyn_up(charstring id) runs on ConnHdlr {
timer T1 := 10.0;
T1.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Update sent MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, oct2int(l1_dl.payload.data_ind.payload[0]));
repeat;
}
[] as_l1_sacch_l1h(l1h) { repeat; }
[] L1CTL.receive { repeat; }
[] T1.timeout {
var int8_t rcv := oct2int(l1_dl.payload.data_ind.payload[0]);
if( f_power_level_is_highest_dbm(rcv) ){
if (not isbound(l1h)) {
setverdict(fail, "No SACCH blocks were received");
} else if (f_power_level_is_highest_dbm(l1h.ms_power_lvl)) {
setverdict(pass, "Power level in L1 header reduced as expected");
} else {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
log2str("Power Level in L1 header did not reach the expected value, e:",pwr_max_var," r:",rcv));
setverdict(fail, "Power level := ", l1h.ms_power_lvl, " did not ",
"reach the expected value := ", pwr_max_var);
}
}
}
@ -2722,7 +2732,7 @@ private function f_TC_rsl_ms_pwr_dyn_up(charstring id) runs on ConnHdlr {
/* see if we reach the band min power */
private function f_TC_rsl_ms_pwr_dyn_down(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
/* set a high value to ensure power decreases */
f_trxc_fake_rssi(rxlev2dbm(50));
@ -2749,18 +2759,15 @@ private function f_TC_rsl_ms_pwr_dyn_down(charstring id) runs on ConnHdlr {
timer T1 := 10.0;
T1.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* Update sent MS power to follow what BTS requests */
f_L1CTL_PARAM(L1CTL, g_pars.l1_pars.ms_actual_ta, oct2int(l1_dl.payload.data_ind.payload[0]));
repeat;
}
[] as_l1_sacch_l1h(l1h) { repeat; }
[] L1CTL.receive { repeat; }
[] T1.timeout {
if( f_power_level_is_lowest_dbm(oct2int(l1_dl.payload.data_ind.payload[0])) ){
setverdict(pass, "Power level in L1 header increased to lowest power value");
if (not isbound(l1h)) {
setverdict(fail, "No SACCH blocks were received");
} else if (f_power_level_is_lowest_dbm(l1h.ms_power_lvl)) {
setverdict(pass, "Power level increased to lowest power value");
} else {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
"Power level in L1 header NOT increased to lowest power value");
setverdict(fail, "Power level NOT increased to lowest power value");
}
}
}
@ -2773,7 +2780,7 @@ private function f_TC_rsl_ms_pwr_dyn_down(charstring id) runs on ConnHdlr {
/* see if we change the power level without receiving power parameters, which should not happen
rsl chan act WITHOUT power parameters */
private function f_TC_rsl_ms_pwr_dyn_active(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
/* set a high value to ensure power decreases */
f_trxc_fake_rssi(rxlev2dbm(50));
@ -2795,8 +2802,8 @@ private function f_TC_rsl_ms_pwr_dyn_active(charstring id) runs on ConnHdlr {
timer T1 := 10.0;
T1.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
if ( oct2int(l1_dl.payload.data_ind.payload[0]) != pwr_var) {
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.ms_power_lvl != pwr_var) {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
"BS power control should not be active unless we receive a power parameters IE!");
}
@ -2814,7 +2821,7 @@ private function f_TC_rsl_ms_pwr_dyn_active(charstring id) runs on ConnHdlr {
/* see if we change the power level without receiving power parameters, which should not happen
ms power control WITHOUT power parameters */
private function f_TC_rsl_ms_pwr_dyn_active2(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
/* set a high value to ensure power decreases */
f_trxc_fake_rssi(rxlev2dbm(50));
@ -2839,8 +2846,8 @@ private function f_TC_rsl_ms_pwr_dyn_active2(charstring id) runs on ConnHdlr {
timer T1 := 10.0;
T1.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
if ( oct2int(l1_dl.payload.data_ind.payload[0]) != pwr_var) {
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.ms_power_lvl != pwr_var) {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
"BS power control should not be active unless we receive a power parameters IE!");
}
@ -2856,12 +2863,12 @@ private function f_TC_rsl_ms_pwr_dyn_active2(charstring id) runs on ConnHdlr {
}
private function f_wait_for_l1_power_level(integer level) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
timer T0 := 10.0;
T0.start;
alt {
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
if (not (l1_dl.payload.data_ind.payload[0] == int2oct(level, 1))) {
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.ms_power_lvl != level) {
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
"Power level in L1 header != signaled (RSL) power level.");
}
@ -3169,7 +3176,7 @@ testcase TC_meas_res_sign_tchh_toa256() runs on test_CT {
/* establish DChan, and send MS POWER CONTROL messages via RSL, verify that
* the BTS is forwarding those values to the MS via the SACCH L1 header. */
private function f_tc_rsl_ms_pwr_ctrl(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var SacchL1Header l1h;
var RSL_IE_MS_Power ms_power;
var RSL_Message rsl;
var uint5_t power_level := 0;
@ -3191,15 +3198,11 @@ private function f_tc_rsl_ms_pwr_ctrl(charstring id) runs on ConnHdlr {
RSL.send(rsl);
alt {
/* Pick all SACCH blocks for checking */
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* The first byte of the L1 header contains the power level.
* The reserved bits and the fpc bit is set to 0, so we may
* compare directly. */
if (not (l1_dl.payload.data_ind.payload[0] == int2oct(power_level, 1))) {
setverdict(fail, "Power level in L1 header does not match the signaled (RSL) power level.");
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.ms_power_lvl != power_level) {
setverdict(fail, "Power level := ", l1h.ms_power_lvl, "does not ",
"match the signaled (RSL) power level := ", power_level);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
/* Signal a new power level via RSL for the next turn. */
@ -3240,9 +3243,8 @@ testcase TC_rsl_ms_pwr_ctrl() runs on test_CT {
/* establish DChan, verify that the BTS sets the TA in the first SACCH L1 header.
TA for the IMM ASS messages is still controlled by g_pars.l1_pars.ms_actual_ta! */
private function f_tc_rsl_chan_initial_ta(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var uint5_t ta_to_test := 16;
var SacchL1Header l1h;
f_l1_tune(L1CTL);
RSL.clear;
@ -3254,12 +3256,8 @@ private function f_tc_rsl_chan_initial_ta(charstring id) runs on ConnHdlr {
alt {
/* Pick all SACCH blocks for checking */
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* The second byte of the L1 header contains the TA. */
if (not (l1_dl.payload.data_ind.payload[1] == int2oct(ta_to_test, 1))) {
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.actual_ta != ta_to_test) {
setverdict(fail, "TA in L1 header does not match the signaled (RSL) TA.");
}
@ -3289,8 +3287,8 @@ testcase TC_rsl_chan_initial_ta() runs on test_CT {
/* establish DChan, verify that the BTS sets MS power in the first SACCH L1 header. */
private function f_tc_rsl_chan_initial_ms_pwr(charstring id) runs on ConnHdlr {
var L1ctlDlMessage l1_dl;
var uint5_t ms_power_level := 7;
var SacchL1Header l1h;
var RSL_IE_MS_Power ms_power;
ms_power.reserved := 0;
@ -3306,10 +3304,10 @@ private function f_tc_rsl_chan_initial_ms_pwr(charstring id) runs on ConnHdlr {
T.start;
alt {
/* Pick all SACCH blocks for checking */
[] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, tr_RslLinkID_SACCH(?))) -> value l1_dl {
/* The first byte of the L1 header contains the power level.. */
if (not (l1_dl.payload.data_ind.payload[0] == int2oct(ms_power_level, 1))) {
setverdict(fail, "Power Level in L1 header does not match the signaled (RSL) MS Power Level.");
[] as_l1_sacch_l1h(l1h, do_apply := false) {
if (l1h.ms_power_lvl != ms_power_level) {
setverdict(fail, "Power level := ", l1h.ms_power_lvl, "does not ",
"match the signaled (RSL) power level := ", ms_power_level);
}
}
/* Ignore all other blocks */