diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index a0d668d64..fc714fe19 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -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 */