Harald Welte has submitted this change and it was merged. ( https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14341 )
Change subject: bts: Extend LAPDm test suite with a number of new tests ...................................................................... bts: Extend LAPDm test suite with a number of new tests This adds the following test cases to BTS_Tests_LAPDm.ttcn: * TC_sabm_retransmit_bts() * TC_sabm_invalid_resp() * TC_sabm_dm() * TC_establish_ign_first_sabm() * TC_iframe_seq_and_ack() * TC_iframe_timer_recovery() Change-Id: I4e1136c0c0f10d5bc8d01e826ae5d92f17a0b2aa --- M bts/BTS_Tests.ttcn M bts/BTS_Tests_LAPDm.ttcn M library/LAPDm_Types.ttcn 3 files changed, 511 insertions(+), 7 deletions(-) Approvals: Harald Welte: Looks good to me, approved Jenkins Builder: Verified diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index c43774d..e48c05a 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -61,9 +61,11 @@ import from Osmocom_VTY_Functions all; import from TELNETasp_PortType all; +import from BTS_Tests_LAPDm all; friend module BTS_Tests_SMSCB; friend module BTS_Tests_virtphy; +friend module BTS_Tests_LAPDm; /* The tests assume a BTS with the following timeslot configuration: * TS0 : Combined CCCH + SDCCH/4 @@ -155,7 +157,7 @@ } /* an individual call / channel */ -type component ConnHdlr extends RSL_DchanHdlr { +type component ConnHdlr extends RSL_DchanHdlr, lapdm_test_CT { port L1CTL_PT L1CTL; port TRXC_CODEC_PT BTS_TRXC; @@ -551,7 +553,7 @@ "RF CHAN REL", true); } -private template ConnHdlrPars t_Pars(template RslChannelNr chan_nr, +friend template ConnHdlrPars t_Pars(template RslChannelNr chan_nr, template RSL_IE_ChannelMode chan_mode, float t_guard := 20.0) := { chan_nr := valueof(chan_nr), @@ -699,7 +701,7 @@ } /* execute the same callback function on a variety of logical channels */ -private function f_testmatrix_each_chan(ConnHdlrPars pars, void_fn fn) runs on test_CT { +friend function f_testmatrix_each_chan(ConnHdlrPars pars, void_fn fn) runs on test_CT { var ConnHdlr vc_conn; f_init(); diff --git a/bts/BTS_Tests_LAPDm.ttcn b/bts/BTS_Tests_LAPDm.ttcn index 33aa174..2eade0a 100644 --- a/bts/BTS_Tests_LAPDm.ttcn +++ b/bts/BTS_Tests_LAPDm.ttcn @@ -4,7 +4,9 @@ import from Osmocom_Types all; import from LAPDm_RAW_PT all; import from LAPDm_Types all; +import from RSL_Types all; import from BTS_Tests all; +import from Misc_Helpers all; /* test that use exclusively only LAPDm over L1CTL */ type component lapdm_test_CT { @@ -14,8 +16,6 @@ /* contrary to BTS_Tests.ttcn, we use LAPDm_PT here, a convenience wrapper * around L1CTL to perform encode/decode of abstract LAPDm frames */ -type component lapdm_bts_CT extends lapdm_test_CT, test_CT { -} /********************************************************************************* * Test using only L1CTL/LAPDm @@ -34,9 +34,15 @@ lapdm_component.start(LAPDmStart()); } +function f_lapdm_exit() runs on lapdm_test_CT { + lapdm_component.stop; + lapdm_component.done; + unmap(lapdm_component:L1CTL, system:L1CTL); +} + /* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */ function f_establish_dcch() runs on lapdm_test_CT { - var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true }; + var BCCH_tune_req tune_req := { arfcn := { false, mp_trx0_arfcn }, combined_ccch := true }; var DCCH_establish_req est_req := { ra := 23 }; LAPDM.send(tune_req); @@ -44,6 +50,16 @@ LAPDM.receive(DCCH_establish_res:?); } +/* master function switching to a dedicated radio channel */ +function f_switch_dcch(Arfcn arfcn, RslChannelNr chan_nr, GsmTsc tsc) runs on lapdm_test_CT { + var BCCH_tune_req tune_req := { arfcn := arfcn, combined_ccch := true }; + var DCCH_switch_req sw_req := { arfcn, chan_nr, tsc }; + + LAPDM.send(tune_req); + LAPDM.send(sw_req); + LAPDM.receive(DCCH_switch_res:?); +} + /* helper function releasing dedicated radio channel physically (no Um signaling!) */ function f_release_dcch() runs on lapdm_test_CT { var DCCH_release_req rel_req := {}; @@ -252,6 +268,434 @@ log("DEC: ", dec_LapdmFrameAB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O)); } +/********************************************************************************* + * Test using both L1CTL/LAPDm and RSL + *********************************************************************************/ + +private function fp_common_init() runs on ConnHdlr +{ + /* undo what f_start_handler is doing and pull LAPDm_CT into the loop */ + unmap(self:L1CTL, system:L1CTL); + f_lapdm_init(); + /* activate the channel on the BTS side */ + f_rsl_chan_act(g_pars.chan_mode, false, {}); + /* activate the channel on the MS side */ + f_switch_dcch({false, mp_trx0_arfcn}, g_chan_nr, 7); +} + +private function fp_common_fini() runs on ConnHdlr +{ + f_release_dcch(); + f_rsl_chan_deact(); + f_lapdm_exit(); +} + +/* Verify that the BTS is re-transmitting SABM messages after T200 timeout, inspired + by 3GPP TS 51.010-1 25.2.1.1.2.1 + 25.2.1.2.4 */ +private function f_TC_sabm_retransmit_bts(charstring id) runs on ConnHdlr { + const integer sapi := 3; /* BTS may not establish SAPI=0 outbound */ + fp_common_init(); + + LAPDM.clear; + RSL.send(ts_RSL_EST_REQ(g_chan_nr, ts_RslLinkID_DCCH(sapi))); + + timer T := 8.0; + var integer sabm_received := 0; + T.start; + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))) { + sabm_received := sabm_received + 1; + repeat; + } + [] LAPDM.receive { repeat; } + [] T.timeout { } + } + if (sabm_received == 0) { + setverdict(fail, "No SABM observed at all!"); + } else if (sabm_received != 6) { + setverdict(fail, "Incorrect number of SABM re-transmissions of observed: ", + sabm_received); + } else { + setverdict(pass, "Received ", sabm_received, " SABM"); + } + + fp_common_fini(); +} +testcase TC_sabm_retransmit_bts() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_sabm_retransmit_bts)); +} + + +type record LapdmNamedFrame { + charstring name, + LapdmFrame lapdm +}; + +/* Test that the BTS will ignore receipt of frames other than a UA when + * received in response to the SABM frame, inspired from 3GPP TS 51.010-1 + * Section 25.2.1.1.2.3 */ +private function f_TC_sabm_invalid_resp2(charstring id, LapdmNamedFrame err_frame) runs on ConnHdlr { + var integer sapi := err_frame.lapdm.ab.addr.sapi; + fp_common_init(); + + /* Establish Request via RSL; Expect SABM on LAPDm side */ + LAPDM.clear; + RSL.send(ts_RSL_EST_REQ(g_chan_nr, ts_RslLinkID_DCCH(sapi))); + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))); + [] LAPDM.receive { repeat; } + } + + /* send erroneous response to SABM */ + LAPDM.send(t_PH_DATA(0, false, err_frame.lapdm)); + + /* expect a SABM retransmission of the BTS */ + timer T := 3.0; + T.start; + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))) { + setverdict(pass); + } + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UI(0, ?, ''O))) { repeat; } + [] LAPDM.receive(t_PH_DATA(0, false, ?)) { + setverdict(fail, "Received unexpected LAPDm frame instead of SABM after sending ", + err_frame.name); + } + [] LAPDM.receive { repeat; } + [] T.timeout { + setverdict(fail, "Timeout waiting for SABM retransmission after sending ", + err_frame.name); + } + } + + fp_common_fini(); +} +private function f_TC_sabm_invalid_resp(charstring id) runs on ConnHdlr { + const integer sapi := 3; /* BTS may not establish SAPI=0 outbound */ + var LapdmNamedFrame err_frame[3] := { + { "I", valueof(ts_LAPDm_I(sapi, c_r := cr_MO_CMD, p := true, nr := 0, ns := 0, + l3 := '01020304'O)) }, + { "RR", valueof(ts_LAPDm_RR(sapi, c_r := cr_MO_CMD, p := true, nr := 0)) }, + { "REJ" , valueof(ts_LAPDm_REJ(sapi, c_r := cr_MO_CMD, p := true, nr := 0)) } + }; + var integer i; + + for (i := 0; i < lengthof(err_frame); i := i+1) { + f_TC_sabm_invalid_resp2(id, err_frame[i]) + } +} +testcase TC_sabm_invalid_resp() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_sabm_invalid_resp)); +} + +/* Test that the BTS will not re-transmit SABM frames after receiving a DM response, + * inspired from 3GPP TS 51.010-1 Section 25.2.1.1.3 */ +private function f_TC_sabm_dm(charstring id) runs on ConnHdlr { + const integer sapi := 3; /* BTS may not establish SAPI=0 outbound */ + fp_common_init(); + + /* Establish Request via RSL; Expect SABM on LAPDm side */ + LAPDM.clear; + RSL.send(ts_RSL_EST_REQ(g_chan_nr, ts_RslLinkID_DCCH(sapi))); + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))); + [] LAPDM.receive { repeat; } + } + + /* send DM response to SABM */ + RSL.clear; + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_DM(sapi, c_r:=cr_MO_RSP, f:=true))); + alt { + [] RSL.receive(tr_RSL_REL_IND(g_chan_nr, tr_RslLinkID_DCCH(sapi))); + [] RSL.receive { repeat; } + } + + /* expect no SABM retransmission of the BTS */ + timer T := 3.0; + T.start; + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))) { + setverdict(fail, "Received unexpected SABM retransmission"); + } + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UI(0, ?, ''O))) { repeat; } + [] LAPDM.receive(t_PH_DATA(0, false, ?)) { + setverdict(fail, "Received unexpected LAPDm frame"); + } + [] LAPDM.receive { repeat; } + [] T.timeout { + setverdict(pass); + } + } + + fp_common_fini(); +} +testcase TC_sabm_dm() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_sabm_dm)); +} + +/* Test the full LAPDm establishment while simulating the loss of the initial SABM or UA + * frame, requiring the BTS to re-transmit one SABM and then following up all the way to + * dedicated mode; inspired by 3GPP TS 51.010-1 25.2.1.2.2 */ +private function f_TC_establish_ign_first_sabm(charstring id) runs on ConnHdlr { + const integer sapi := 3; /* BTS may not establish SAPI=0 outbound */ + var integer num_sabm := 0; + var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(sapi)); + timer T := 3.0; + + fp_common_init(); + + /* Establish Request via RSL */ + LAPDM.clear; + RSL.send(ts_RSL_EST_REQ(g_chan_nr, link_id)); + /* Expect two SABM (retransmit) */ + T.start; + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_SABM(sapi, ?, ?, ''O))) { + num_sabm := num_sabm + 1; + if (num_sabm < 2) { + repeat; + } + } + [] LAPDM.receive { repeat; } + } + + /* send UA response to SABM */ + RSL.clear; + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_UA(sapi, c_r:=cr_MO_RSP, f:=true, l3:=''O))); + alt { + [] RSL.receive(tr_RSL_EST_CONF(g_chan_nr, link_id)); + [] RSL.receive { repeat; } + } + + /* Send I frame from BTS to MS */ + var octetstring l3 := f_rnd_octstring(10); + RSL.send(ts_RSL_DATA_REQ(g_chan_nr, link_id, l3)); + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=false, + nr:=0, ns:=0, l3:=l3))); + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UI(0, ?, ''O))) { repeat; } + [] LAPDM.receive(t_PH_DATA(0, true, ?)) { repeat; } + [] LAPDM.receive { setverdict(fail, "Unexpected LAPDm received"); } + } + /* Send RR frame in response */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_RR(sapi, c_r:=cr_MO_RSP, p:=false, nr:=1))); + + /* expect idle UI Frame from BTS */ + alt { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UI(0, ?, ''O))) { + setverdict(pass); + } + [] LAPDM.receive(t_PH_DATA(0, true, ?)) { repeat; } + [] LAPDM.receive { setverdict(fail, "Unexpected LAPDm received"); } + } + + fp_common_fini(); +} +testcase TC_establish_ign_first_sabm() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_establish_ign_first_sabm)); +} + +/* ignore all SACCH frames */ +private altstep as_lapdm_acch() runs on ConnHdlr { + [] LAPDM.receive(t_PH_DATA(0, true, ?)) { repeat; } +} +/* ignore all LAPDm idle frames (UI) */ +private altstep as_lapdm_idle() runs on ConnHdlr { + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UI(0, ?, ''O))) { repeat; } +} +/* ignore all measurement reports */ +private altstep as_rsl_meas_rep() runs on ConnHdlr { + [] RSL.receive(tr_RSL_MEAS_RES(g_chan_nr)) { repeat; } +} +/* fail if we receive an RSL ERROR IND */ +private altstep as_rsl_fail_err() runs on ConnHdlr { + var RSL_Message rx_rsl; + [] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, ?, ?)) { + setverdict(fail, "Received RSL ERROR IND ", rx_rsl); + } +} +/* all of the above */ +private altstep as_ignore_background() runs on ConnHdlr { + [] as_lapdm_acch(); + [] as_lapdm_idle(); + [] as_rsl_meas_rep(); + [] as_rsl_fail_err(); +} + +/* Test the operation of Layer 2 sequence numbering. + * dedicated mode; inspired by 3GPP TS 51.010-1 25.2.2.1 */ +private function f_TC_iframe_seq_and_ack(charstring id) runs on ConnHdlr { + const integer sapi := 0; + var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(sapi)); + var octetstring l3 := f_rnd_octstring(18); + var default d; + timer T := 3.0; + + fp_common_init(); + + /* some common altstep for meas res and other background noise */ + d := activate(as_ignore_background()); + RSL.clear; + LAPDM.clear; + + /* MO Establish Request via LADPm: SAPI = 0, C = 0, P = 1, M = 0, 0 ≤ L ≤ N201.. */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=true, l3:=l3))); + RSL.receive(tr_RSL_EST_IND(g_chan_nr, link_id, l3)); + /* UA: SAPI = 0, R = 0, F = 1, M = 0, L = L of SABM. */ + LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=true, l3:=l3))); + + var integer last_ns_rx := 0; + + for (var integer i := 0; i < 10; i := i+1) { + var octetstring l3_mo := f_rnd_octstring(12); + var octetstring l3_mt := f_rnd_octstring(12); + var LAPDm_ph_data pd; + + log("Starting iteration ", i); + /* MT I frame */ + RSL.send(ts_RSL_DATA_REQ(g_chan_nr, link_id, l3_mt)); + alt { + /* SAPI = 0, R = 1, F = 0, M = 0, L = 0. */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=false, + nr:=i mod 8))) { + log("Ignoring RR in iteration ", i); + repeat; + } + /* SAPI = 0, C = 1, P = 0, M = 0, 0 ≤ L ≤ N201. */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=false, + nr:=i mod 8, ns:=i mod 8, + l3:=l3_mt))) -> value pd { + last_ns_rx := pd.lapdm.ab.ctrl.i.n_s; + } + } + /* respond with MO I-frame: SAPI = 0, C = 0, P = 0, M = 0, 0 <= L <= N201. */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false, + nr:=(last_ns_rx+1)mod 8, + ns:=i mod 8, l3 := l3_mo))); + RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3_mo)); + } + log("Completed iteration"); + + deactivate(d); + fp_common_fini(); +} +testcase TC_iframe_seq_and_ack() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_iframe_seq_and_ack)); +} + +/* To test that the BTS is able to respond to I frames whilst in the timer recovery state. + * Inspired by 3GPP TS 51.010-1 25.2.2.2 */ + +/* + 1) The BTS is brought into the multiple frame established state + 2) The MS sends an L3 Request asking for IMEI to the MS. + 3) The BTS shall respond with a RR frame though this may be incorporated with + the L3 Response I frame. The MS does not respond to the I frame. + 4) The BTS shall wait for expiry of timer T200 and then repeat the I frame but + with the P bit set to 1. + 5) The MS then sends a valid L3 Request I frame asking for IMEI which + does not acknowledge receipt of the I frame from the BTS. +On the FACCH the BTS may send an RR frame acknowledging the I frame. + 6) The BTS shall repeat the I frame, this frame will acknowledge receipt of + the second I frame from the MS. + 7) The MS then acknowledges receipt of the MS I frame by sending a RR frame. + 8) The BTS shall send the next I frame. The MS acknowledges this I frame. +*/ +private function f_TC_iframe_timer_recovery(charstring id) runs on ConnHdlr { + const integer sapi := 0; + var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(sapi)); + var default d; + timer T := 3.0; + + fp_common_init(); + + /* some common altstep for meas res and other background noise */ + d := activate(as_ignore_background()); + RSL.clear; + LAPDM.clear; + + var octetstring l3_mo := f_rnd_octstring(12); + var octetstring l3_mt := f_rnd_octstring(12); + + /* 1) The BTS is brought into the multiple frame established state */ + + /* MO Establish Request via LADPm: SAPI = 0, C = 0, P = 1, M = 0, 0 ≤ L ≤ N201.. */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=true, l3:=l3_mo))); + RSL.receive(tr_RSL_EST_IND(g_chan_nr, link_id, l3_mo)); + /* UA: SAPI = 0, R = 0, F = 1, M = 0, L = L of SABM. */ + LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=true, l3:=l3_mo))); + + /* 2) The MS sends an L3 Request to the BTS */ + l3_mo := f_rnd_octstring(18); + /* SAPI = 0, C = 1, P = 0, M = 0, 0 ≤ L ≤ N201, N(S) = 0, N(R) = 0. * */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false, + nr:=0, ns:=0, l3:=l3_mo))); + RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3_mo)); + /* 3) The BTS shall respond with a RR frame though this may be incorporated with + the L3 Response I frame. The MS does not respond to the I frame. */ + RSL.send(ts_RSL_DATA_REQ(g_chan_nr, link_id, l3_mt)); + alt { + /* SAPI = 0, R = 1, F = 0, M = 0, L = 0, N(R) = 1. */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=false, nr:=1))) { + repeat; + } + /* SAPI = 0, C = 0, P = 0, M = 0, 0 ≤ L ≤ N201, N(R) = 1, N(S) = 0 */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=false, + nr:=1, ns:=0, l3:=l3_mt))); + } + + /* 4) The BTS shall wait for expiry of timer T200 and then repeat the I frame but + with the P bit set to 1. */ + /* SAPI = 0, C = 0, P = 1, M = 0, 0 ≤ L ≤ N201, N(R) = 1, N(S) = 0. * */ + LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=true, + nr:=1, ns:=0, l3:=l3_mt))); + + /* 5) The MS then sends a valid L3 Request I frame asking for IMEI which + does not acknowledge receipt of the I frame from the BTS. */ + /* SAPI = 0, C = 1, P = 0, M = 0, 0 ≤ L ≤ N201, N(S) = 1, N(R) = 0. * */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false, + nr:=0, ns:=1, l3 := l3_mo))); + RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3_mo)); + alt { + /* On the FACCH the BTS may send an RR frame acknowledging the I frame. */ + /* SAPI = 0, R = 1, F = 0, M = 0, L = 0, N(R) = 2. */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=false, nr:=2))) { + repeat; + } + /* 6) The BTS shall repeat the I frame, this frame will acknowledge + receipt of the second I frame from the MS. */ + /* SAPI = 0, C = 0, P = 1, M = 0, 0 ≤ L ≤ N201, N(R) = 2, N(S) = 0. * */ + [] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=true, + nr:=2, ns:=0, l3:=l3_mt))); + } + + /* 7) The MS then acknowledges receipt of the BTS I frame by sending a RR * frame. */ + /* SAPI = 0, R = 0, F = 1, 0, M = 0, L = 0, N(R) = 1 */ + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_RR(sapi, c_r:=cr_MO_RSP, p:=true, nr:=1))); + + /* 8) The BTS shall send the next I frame. The MS acknowledges this I frame. */ + l3_mt := f_rnd_octstring(16); + RSL.send(ts_RSL_DATA_REQ(g_chan_nr, link_id, l3_mt)); + /* SAPI = 0, C = 0, P = 0, M = 0, 0 ≤ L ≤ N201, N(R) = 2, N(S) = 1 */ + LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=false, + nr:=2, ns:=1, l3:=l3_mt))); + LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_RR(sapi, c_r:=cr_MO_RSP, p:=true, nr:=2))); + + deactivate(d); + fp_common_fini(); +} +testcase TC_iframe_timer_recovery() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + f_testmatrix_each_chan(pars, refers(f_TC_iframe_timer_recovery)); +} + + + control { execute(TC_foo()); execute(TC_sabm_ua_dcch_sapi0()); @@ -260,6 +704,12 @@ execute(TC_sabm_ua_dcch_sapi4()); execute(TC_sabm_contention()); execute(TC_sabm_retransmit()); + execute(TC_sabm_retransmit_bts()); + execute(TC_sabm_invalid_resp()); + execute(TC_sabm_dm()); + execute(TC_establish_ign_first_sabm()); + execute(TC_iframe_seq_and_ack()); + execute(TC_iframe_timer_recovery()); } } diff --git a/library/LAPDm_Types.ttcn b/library/LAPDm_Types.ttcn index a1ca5fe..577c9bd 100644 --- a/library/LAPDm_Types.ttcn +++ b/library/LAPDm_Types.ttcn @@ -105,7 +105,7 @@ s := { n_r := nr, p_f := pf, s := '00'B } }; template (value) LapdmCtrl ts_LapdmCtrlRR(uint3_t nr, boolean pf) := { - s := { n_r := nr, p_f := pf, s := '00'B } + s := { n_r := nr, p_f := pf, s := '00'B, spare := '01'B } }; template LapdmCtrl tr_LapdmCtrlRNR(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := { @@ -115,6 +115,10 @@ template LapdmCtrl tr_LapdmCtrlREJ(template uint3_t nr, template boolean pf) modifies tr_LapdmCtrlS := { s := { n_r := nr, p_f := pf, s := '10'B } }; + template (value) LapdmCtrl ts_LapdmCtrlREJ(uint3_t nr, boolean pf) := { + s := { n_r := nr, p_f := pf, s := '10'B, spare := '01'B } + }; + template LapdmCtrl tr_LapdmCtrlSABM(template boolean p) := { u := { u := '001'B, p_f := p, u2 := '11'B, spare := '11'B } @@ -126,6 +130,9 @@ template LapdmCtrl tr_LapdmCtrlDM(template boolean f) := { u := { u := '000'B, p_f := f, u2 := '11'B, spare := '11'B } }; + template (value) LapdmCtrl ts_LapdmCtrlDM(boolean f) := { + u := { u := '000'B, p_f := f, u2 := '11'B, spare := '11'B } + }; template LapdmCtrl tr_LapdmCtrlUI(template boolean p := false) := { u := { u := '000'B, p_f := p, u2 := '00'B, spare := '11'B } @@ -261,6 +268,28 @@ } } + template (value) LapdmFrame ts_LAPDm_DM(LapdmSapi sapi, boolean c_r, boolean f) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlDM(f), + len := 0, /* overwritten in encoder */ + m := false, + el := 1, + payload := ''O + } + } + template LapdmFrame tr_LAPDm_DM(template LapdmSapi sapi, template boolean c_r, + template boolean f) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlDM(f), + len := ?, + m := false, + el := 1, + payload := ''O + } + } + template LapdmFrame ts_LAPDm_DISC(LapdmSapi sapi, boolean c_r, boolean p) := { ab := { addr := ts_LapdmAddr(sapi, c_r), @@ -368,6 +397,29 @@ } } + template LapdmFrame tr_LAPDm_REJ(template LapdmSapi sapi, template boolean c_r, + template boolean p, template uint3_t nr) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlREJ(nr, p), + len := 0, + m := false, + el := 1, + payload := ''O + } + } + template (value) LapdmFrame ts_LAPDm_REJ(LapdmSapi sapi, boolean c_r, + boolean p, uint3_t nr) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlREJ(nr, p), + len := 0, + m := false, + el := 1, + payload := ''O + } + } + } with { encode "RAW"; /*variant "FIELDORDER(msb)" */} -- To view, visit https://gerrit.osmocom.org/c/osmo-ttcn3-hacks/+/14341 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-ttcn3-hacks Gerrit-Branch: master Gerrit-Change-Id: I4e1136c0c0f10d5bc8d01e826ae5d92f17a0b2aa Gerrit-Change-Number: 14341 Gerrit-PatchSet: 5 Gerrit-Owner: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Harald Welte <lafo...@gnumonks.org> Gerrit-Reviewer: Jenkins Builder Gerrit-MessageType: merged