From 0472ab441586101286e7caf765782824bbc98d1b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 12 Mar 2018 15:02:26 +0100 Subject: [PATCH] bts: Add RLL tests This adds a series of test cases to BTS_Tests.ttcn implementing testing of the RLL sub-layr of RSL, i.e. the translation between LAPDm frames on the Um interface and the RLL frames on the Abis side (and vice vrsa). Related: OS#3174 Change-Id: I336378de6106e5369600cbb49e0c47cc59864630 --- bts/BTS_Tests.ttcn | 453 +++++++++++++++++++++++++++++++++++- library/L1CTL_PortType.ttcn | 2 +- library/LAPDm_Types.ttcn | 115 +++++++++ library/RSL_Types.ttcn | 44 +++- 4 files changed, 605 insertions(+), 9 deletions(-) diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index f820cf4fb..5e93ba393 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -105,6 +105,7 @@ type component test_CT extends CTRL_Adapter_CT { /* all logical channels available on the BTS */ var ChannelNrs g_AllChannels; + var ChannelNrs g_AllChanTypes; } /* an individual call / channel */ @@ -141,7 +142,13 @@ type record ConnHdlrPars { RslChannelNr chan_nr, RSL_IE_ChannelMode chan_mode, float t_guard, - ConnL1Pars l1_pars + ConnL1Pars l1_pars, + TestSpecUnion spec optional +} + +/* Test-specific parameters */ +type union TestSpecUnion { + RllTestCase rll } template (value) RachControlParameters ts_RachCtrl_default := { @@ -290,6 +297,16 @@ function f_init(charstring id := "BTS-Test") runs on test_CT { valueof(ts_RslChanNr_SDCCH8(6,4)), valueof(ts_RslChanNr_SDCCH8(6,5)), valueof(ts_RslChanNr_SDCCH8(6,6)), valueof(ts_RslChanNr_SDCCH8(6,7)) }; + g_AllChanTypes := { + /* TS 1..4: TCH/F */ + //valueof(ts_RslChanNr_Bm(1)), + /* TS 5: TCH/H */ + //valueof(ts_RslChanNr_Lm(5,1)), + /* TS 0: SDCCH/4 */ + valueof(ts_RslChanNr_SDCCH4(0,2)), + /* TS 6: SDCCH/8 */ + valueof(ts_RslChanNr_SDCCH8(6,4)) + }; f_init_rsl(id); RSL_CCHAN.receive(ASP_IPA_Event:{up_down := ASP_IPA_EVENT_UP}); @@ -480,7 +497,8 @@ private template ConnHdlrPars t_Pars(template RslChannelNr chan_nr, bs_power_level := 0, ms_power_level := 0, ms_actual_ta := 0 - } + }, + spec := omit } /*********************************************************************** @@ -1313,6 +1331,7 @@ function f_TC_meas_res_periodic(charstring id) runs on ConnHdlr { f_rsl_chan_deact(); f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); } + testcase TC_meas_res_sign_tchf() runs on test_CT { var ConnHdlr vc_conn; var ConnHdlrPars pars; @@ -1372,7 +1391,7 @@ testcase TC_meas_res_sign_tchh_toa256() runs on test_CT { } -/* Test if a channel without valid uplink bursts generates RSL CONN FAIL IND */ +/* Test if a channel without valid uplink bursts generates RSL CONN FAIL IND (TS 48.058 4.10) */ private function f_TC_conn_fail_crit(charstring id) runs on ConnHdlr { f_l1_tune(L1CTL); RSL.clear; @@ -2993,6 +3012,421 @@ testcase TC_dyn_ipa_pdch_act_tchf_act_nack() runs on test_CT { } +/*********************************************************************** + * LAPDm / RLL related + ***********************************************************************/ + +private function f_tx_lapdm(template (value) LapdmFrame l, + template (value) RslLinkId link_id) runs on ConnHdlr { + var octetstring l2 := enc_LapdmFrame(valueof(l)); + if (valueof(link_id.c) == SACCH) { + /* prepend dummy L1 header */ + l2 := '0000'O & l2; + } + log("encoding ", l, " to ", l2); + L1CTL.send(ts_L1CTL_DATA_REQ(g_chan_nr, link_id, l2)); +} + +type record RllTestCase { + uint3_t sapi, + RslLinkId link_id, + octetstring l3, + boolean exp +} +type record of RllTestCase RllTestCases; +template RllTestCase t_EITC(uint3_t sapi, RslLinkId id, octetstring l3, boolean exp) := { + sapi := sapi, + link_id := id, + l3 := l3, + exp := exp +} + +/* execute the same callback function with a set of different parameters (tcs) on a + * variety of logical channels */ +private function f_rll_testmatrix(RllTestCases tcs, void_fn fn) runs on test_CT { + var ConnHdlrPars pars; + var ConnHdlr vc_conn; + f_init(testcasename()); + + /* test on each of the channels we have */ + for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) { + pars := valueof(t_Pars(g_AllChanTypes[i], ts_RSL_ChanMode_SIGN)); + + /* test each of the test cases on the current channel */ + for (var integer j := 0; j < sizeof(tcs); j := j+1) { + pars.spec.rll := tcs[j]; + log(testcasename(), ": XXX Starting ", tcs[j] , " on ", g_AllChanTypes[i]); + vc_conn := f_start_handler(fn, pars); + vc_conn.done; + } + } + + f_shutdown(); +} + +/* test if SABM on Um triggers EST IND (TS 48.058 3.1) */ +private function f_TC_rll_est_ind(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + timer T := 3.0; + + f_l1_tune(L1CTL); + RSL.clear; + + /* activate the logical channel */ + f_est_dchan(); + L1CTL.clear; + + f_tx_lapdm(ts_LAPDm_SABM(tc.sapi, cr_MO_CMD, true, tc.l3), tc.link_id); + T.start; + alt { + [tc.l3 != ''O] RSL.receive(tr_RSL_EST_IND(g_chan_nr, tc.link_id, tc.l3)) { + if (tc.exp) { + setverdict(pass); + } else { + setverdict(fail, "Unexpected EST IND with L3 in ", tc); + } + } + [tc.l3 == ''O] RSL.receive(tr_RSL_EST_IND_NOL3(g_chan_nr, tc.link_id)) { + if (tc.exp) { + setverdict(pass); + } else { + setverdict(fail, "Unexpected EST IND without L3 in ", tc); + } + } + [tc.exp] T.timeout { + setverdict(fail, "Timeout waiting for EST IND"); + } + [not tc.exp] T.timeout { + setverdict(pass); + } + } + + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_est_ind() runs on test_CT { + var RllTestCases tcs := { + /* normal SAPI0 establishment */ + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), '01020304'O, true)), + /* SAPI 0 requires contention resolution */ + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), ''O, false)), + /* SAPI 3 doesn't support contention resolution */ + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), '01020304'O, false)), + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), '01020304'O, false)), + /* normal SAPI3 establishment on main DCCH */ + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), ''O, true)), + /* normal SAPI3 establishment on SACCH */ + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), ''O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_est_ind)); +} + +/* test if RLL EST REQ trigeres SABM on Um; UA on Um triggers EST CONF (TS 48.058 3.2) */ +private function f_TC_rll_est_req(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + var L1ctlDlMessage dl; + timer T := 3.0; + + f_l1_tune(L1CTL); + RSL.clear; + + /* activate the logical channel */ + f_est_dchan(); + L1CTL.clear; + + /* Send a RSL EST REQ for SAPI3 on main DCCH */ + RSL.send(ts_RSL_EST_REQ(g_chan_nr, tc.link_id)); + T.start; + alt { + [] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, ?)) -> value dl { + var LapdmFrame lapdm; + var octetstring l2 := dl.payload.data_ind.payload; + if (dl.dl_info.link_id.c == SACCH) { + /* remove L1 header */ + l2 := substr(l2, 2, lengthof(l2)-2); + } + lapdm.ab := dec_LapdmFrameAB(l2); + if (match(lapdm, tr_LAPDm_SABM(tc.sapi, cr_MT_CMD, true, ''O))) { + setverdict(pass); + } else { + repeat; + } + } + [] L1CTL.receive { repeat; } + [] T.timeout { + setverdict(fail, "Timeout waiting for SABM"); + self.stop; + } + } + + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_est_req_DCCH_3() runs on test_CT { + var RllTestCases tcs := { + /* normal SAPI3 establishment on main DCCH */ + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), ''O, true))//, + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_est_req)); +} +testcase TC_rll_est_req_ACCH_3() runs on test_CT { + var RllTestCases tcs := { + /* normal SAPI3 establishment on SACCH */ + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), ''O, true)) + } + f_rll_testmatrix(tcs, refers(f_TC_rll_est_req)); +} + +/* altstep to receive a LAPDm frame matching the given template */ +private altstep as_l1_exp_lapdm(template LapdmFrame exp) runs on ConnHdlr { + var L1ctlDlMessage dl; + [] L1CTL.receive(tr_L1CTL_DATA_IND(g_chan_nr, ?)) -> value dl { + var LapdmFrame lapdm; + var octetstring l2 := dl.payload.data_ind.payload; + if (dl.dl_info.link_id.c == SACCH) { + /* remove L1 header */ + l2 := substr(l2, 2, lengthof(l2)-2); + } + if (ischosen(exp.ab)) { + lapdm.ab := dec_LapdmFrameAB(l2); + } else if (ischosen(exp.b4)) { + lapdm.b4 := dec_LapdmFrameB4(l2); + } else if (ischosen(exp.bbis)) { + lapdm.bbis := dec_LapdmFrameBbis(l2); + } + log("Rx LAPDm ", lapdm); + if (match(lapdm, exp)) { + setverdict(pass); + } else { + repeat; + } + } + [] L1CTL.receive { repeat; } +} +private function f_l1_exp_lapdm(template LapdmFrame exp, float t := 3.0) runs on ConnHdlr { + timer T := t; + T.start; + alt { + [] T.timeout { + setverdict(fail, "Timeout waiting for LAPDm ", exp); + self.stop; + } + [] as_l1_exp_lapdm(exp); + } +} + +/* establish one Radio Link Layer via SABM -> UA. Use l3 for contention resolution */ +private function f_est_rll_mo(uint3_t sapi, RslLinkId link_id, octetstring l3) runs on ConnHdlr { + /* send SABM from MS -> BTS */ + f_tx_lapdm(ts_LAPDm_SABM(sapi, cr_MO_CMD, true, l3), link_id); + /* expect RLL EST IND on Abis */ + alt { + [l3 != ''O] RSL.receive(tr_RSL_EST_IND(g_chan_nr, link_id, l3)); + [l3 == ''O] RSL.receive(tr_RSL_EST_IND_NOL3(g_chan_nr, link_id)); + [] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, link_id, ?)) { + setverdict(fail, "Failing due to RSL_ERROR_IND"); + self.stop; + } + [] RSL.receive { repeat; } + } + /* expect UA from BTS -> MS */ + f_l1_exp_lapdm(tr_LAPDm_UA(sapi, cr_MT_RSP, true, l3)); +} + +/* test if DISC on Um triggers RLL REL IND (TS 48.058 3.3) */ +private function f_TC_rll_rel_ind(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + + f_l1_tune(L1CTL); + RSL.clear; + + /* activate the logical channel */ + f_est_dchan(); + L1CTL.clear; + + /* first establish the link-layer */ + f_est_rll_mo(tc.sapi, tc.link_id, tc.l3); + + /* then send the DISC */ + f_tx_lapdm(ts_LAPDm_DISC(tc.sapi, cr_MO_CMD, true), tc.link_id); + /* ... and expect the REL IND on the RSL side */ + alt { + [] RSL.receive(tr_RSL_REL_IND(g_chan_nr, tc.link_id)) { + setverdict(pass); + } + } + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_rel_ind_DCCH_0() runs on test_CT { + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), '01020304'O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind)); +} + +testcase TC_rll_rel_ind_ACCH_0() runs on test_CT { + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_SACCH(0)), ''O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind)); +} +testcase TC_rll_rel_ind_DCCH_3() runs on test_CT { + var RllTestCases tcs := { + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), ''O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind)); +} +testcase TC_rll_rel_ind_ACCH_3() runs on test_CT { + var RllTestCases tcs := { + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), ''O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_rel_ind)); +} + +/* test if RLL REL REQ triggers DISC on Um; UA/DM triggers RLL REL CONF (TS 48.058 3.4) */ +private function f_TC_rll_rel_req(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + f_l1_tune(L1CTL); + RSL.clear; + + /* activate the logical channel */ + f_est_dchan(); + L1CTL.clear; + + /* first establish the link-layer */ + f_est_rll_mo(tc.sapi, tc.link_id, tc.l3); + + /* then send the REL REQ via RSL */ + RSL.send(ts_RSL_REL_REQ(g_chan_nr, tc.link_id, RSL_REL_MODE_NORMAL)); + /* ... and expect the DISC on the Um side */ + alt { + [] as_l1_exp_lapdm(tr_LAPDm_DISC(tc.sapi, cr_MO_CMD, true)) { + /* FIXME: send a UA in resposne to the DISC */ + } + } + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_rel_req() runs on test_CT { + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), '01020304'O, true)), + valueof(t_EITC(0, valueof(ts_RslLinkID_SACCH(0)), ''O, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), ''O, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), ''O, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_rel_req)); +} + +/* test if RLL DATA REQ triggers I-frames on Um (TS 48.058 3.5) */ +testcase TC_rll_data_req() runs on test_CT { +} + +/* test if I-frames on Um trigger RLL DATA IND (TS 48.058 3.6) */ +testcase TC_rll_data_ind() runs on test_CT { +} + +/* test if RLL UNIT DATA REQ triggers UI-frame on Um (TS 48.058 3.7) */ +private function f_TC_rll_ud_req(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + + f_l1_tune(L1CTL); + RSL.clear; + + f_est_dchan(); + L1CTL.clear; + + /* Send UNITDATA REQ on RSL side */ + RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, tc.link_id, tc.l3)); + /* Expect it to arrive on the other side */ + if (tc.link_id.c == SACCH) { + f_l1_exp_lapdm(tr_LAPDm_B4_UI(tc.sapi, cr_MT_CMD, false, tc.l3)); + } else { + f_l1_exp_lapdm(tr_LAPDm_UI(tc.sapi, cr_MT_CMD, false, tc.l3)); + } + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_unit_data_req_DCCH() runs on test_CT { + var octetstring l3 := f_rnd_octstring(15); + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), l3, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), l3, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_ud_req)); +} +testcase TC_rll_unit_data_req_ACCH() runs on test_CT { + var octetstring l3 := f_rnd_octstring(19); + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_SACCH(0)), l3, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), l3, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_ud_req)); +} + +/* test if UI-frames on Um trigger RLL UNIT DATA IND (TS 48.058 3.8) */ +private function f_TC_rll_ud_ind(charstring id) runs on ConnHdlr { + var RllTestCase tc := g_pars.spec.rll; + + f_l1_tune(L1CTL); + RSL.clear; + + f_est_dchan(); + L1CTL.clear; + + /* Send LAPDm UI frame. There is no B4 format in uplink! */ + f_tx_lapdm(ts_LAPDm_UI(tc.sapi, cr_MO_CMD, false, tc.l3), tc.link_id); + /* Expdct RLL UNITDATA IND on RSL side */ + alt { + [] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, tc.link_id, tc.l3)) { + setverdict(pass); + } + [] RSL.receive { repeat; } + } + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_rll_unit_data_ind_DCCH() runs on test_CT { + var octetstring l3 := f_rnd_octstring(15); + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_DCCH(0)), l3, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_DCCH(3)), l3, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_ud_ind)); +} +testcase TC_rll_unit_data_ind_ACCH() runs on test_CT { + var octetstring l3 := f_rnd_octstring(18); + var RllTestCases tcs := { + valueof(t_EITC(0, valueof(ts_RslLinkID_SACCH(0)), l3, true)), + valueof(t_EITC(3, valueof(ts_RslLinkID_SACCH(3)), l3, true)) + }; + f_rll_testmatrix(tcs, refers(f_TC_rll_ud_ind)); +} + + +/* test generation of RLL ERR IND based on Um errors (TS 48.058 3.9) */ +/* protocol error as per 44.006 */ +/* link layer failure (repetition of I-frame N200 times without ACK */ +/* repetition of SABM or DISC N200 times without ACK */ +/* receptiom of SABM in multi-frame established state */ + + + + /* TODO Areas: @@ -3095,6 +3529,19 @@ control { execute( TC_dyn_ipa_pdch_tchf_act() ); execute( TC_dyn_ipa_pdch_tchf_act_pdch_act_nack() ); execute( TC_dyn_ipa_pdch_act_tchf_act_nack() ); + + execute( TC_rll_est_ind() ); + execute( TC_rll_est_req_DCCH_3() ); + execute( TC_rll_est_req_ACCH_3() ); + execute( TC_rll_rel_ind_DCCH_0() ); + execute( TC_rll_rel_ind_DCCH_3() ); + execute( TC_rll_rel_ind_ACCH_0() ); + execute( TC_rll_rel_ind_ACCH_3() ); + execute( TC_rll_rel_req() ); + execute( TC_rll_unit_data_req_DCCH() ); + execute( TC_rll_unit_data_req_ACCH() ); + execute( TC_rll_unit_data_ind_DCCH() ); + execute( TC_rll_unit_data_ind_ACCH() ); } diff --git a/library/L1CTL_PortType.ttcn b/library/L1CTL_PortType.ttcn index 77b2494ae..f8bc67035 100644 --- a/library/L1CTL_PortType.ttcn +++ b/library/L1CTL_PortType.ttcn @@ -97,7 +97,7 @@ module L1CTL_PortType { alt { [] pt.receive(tr_L1CTL_DATA_IND(t_RslChanNr_PCH_AGCH(0))) -> value dl { rr := dec_GsmRrMessage(dl.payload.data_ind.payload); - log("PCH/AGCN DL RR: ", rr); + log("PCH/AGCH DL RR: ", rr); if (match(rr, t_RR_IMM_ASS(ra, rach_fn))) { log("Received IMM.ASS for our RACH!"); } else { diff --git a/library/LAPDm_Types.ttcn b/library/LAPDm_Types.ttcn index 91f55fabb..487748d76 100644 --- a/library/LAPDm_Types.ttcn +++ b/library/LAPDm_Types.ttcn @@ -10,6 +10,12 @@ module LAPDm_Types { type BIT3 LapdmUBits; type BIT2 LapdmU2Bits; + /* 44.006 6.3.2 */ + const boolean cr_MO_CMD := false; + const boolean cr_MO_RSP := true; + const boolean cr_MT_CMD := true; + const boolean cr_MT_RSP := false; + /* TS 44.006 Figure 4 */ type record LapdmAddressField { BIT1 spare, @@ -193,4 +199,113 @@ module LAPDm_Types { /* automatic decoding to the generic LapdmFrame will not work, you have to call one of the * type-specific decoder routines above */ + /* SABM frame with L3 payload */ + template (value) LapdmFrame ts_LAPDm_SABM(LapdmSapi sapi, boolean c_r, boolean p, + octetstring l3) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlSABM(p), + len := 0, /* overwritten in encoder */ + m := false, + el := 1, + payload := l3 + } + } + template LapdmFrame tr_LAPDm_SABM(template LapdmSapi sapi, template boolean c_r, + template boolean p, template octetstring l3) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlSABM(p), + len := ?, + m := false, + el := 1, + payload := l3 + } + } + + template (value) LapdmFrame ts_LAPDm_UA(LapdmSapi sapi, boolean c_r, boolean f, + octetstring l3) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlUA(f), + len := 0, /* overwritten in encoder */ + m := false, + el := 1, + payload := l3 + } + } + template LapdmFrame tr_LAPDm_UA(template LapdmSapi sapi, template boolean c_r, + template boolean f, template octetstring l3) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlUA(f), + len := ?, + m := false, + el := 1, + payload := l3 + } + } + + template LapdmFrame ts_LAPDm_DISC(LapdmSapi sapi, boolean c_r, boolean p) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlDISC(p), + len := 0, + m := false, + el := 1, + payload := ''O + } + } + template LapdmFrame tr_LAPDm_DISC(template LapdmSapi sapi, template boolean c_r, + template boolean p) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlDISC(p), + len := ?, + m := false, + el := 1, + payload := ''O + } + } + + template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlUI(p), + len := 0, + m := false, + el := 1, + payload := l3 + } + } + template LapdmFrame tr_LAPDm_UI(template LapdmSapi sapi, template boolean c_r, + template boolean p, template octetstring l3) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlUI(p), + len := ?, + m := false, + el := 1, + payload := l3 + } + } + + template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := { + b4 := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlUI(p), + payload := l3 + } + } + template LapdmFrame tr_LAPDm_B4_UI(template LapdmSapi sapi, template boolean c_r, + template boolean p, template octetstring l3) := { + b4 := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlUI(p), + payload := l3 + } + } + + + } with { encode "RAW"; /*variant "FIELDORDER(msb)" */} diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn index 246ea3fbb..2d9c92ecc 100644 --- a/library/RSL_Types.ttcn +++ b/library/RSL_Types.ttcn @@ -625,13 +625,19 @@ module RSL_Types { RSL_IPA_Codec codec } + /* 9.3.20 */ + type enumerated RSL_IE_ReleaseMode { + RSL_REL_MODE_NORMAL ('00'B), + REL_REL_MODE_LOCAL ('01'B) + } + /* union of all IE bodies */ type union RSL_IE_Body { RslChannelNr chan_nr, RslLinkId link_id, RSL_L16V l3_info, RSL_LV rlm_cause, - uint8_t release_mode, + RSL_IE_ReleaseMode release_mode, RSL_IE_ActivationType act_type, RSL_IE_ChannelMode chan_mode, uint8_t handover_ref, @@ -926,25 +932,38 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie tr_RSL_IE(RSL_IE_Body:{l3_info := tr_RSL_L16V(l3_info)}) } } + template RSL_Message tr_RSL_EST_IND_NOL3(template RslChannelNr chan_nr, template RslLinkId link_id) := +{ + msg_disc := tr_RSL_MsgDisc(RSL_MDISC_RLL, false), + msg_type := RSL_MT_EST_IND, + ies := { + tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), + tr_RSL_IE(RSL_IE_Body:{link_id := link_id}) + } + } + /* 8.3.7 BSC -> BTS */ template (value) RSL_Message ts_RSL_REL_REQ(template (value) RslChannelNr chan_nr, - template (value) RslLinkId link_id) := { + template (value) RslLinkId link_id, + template (value) RSL_IE_ReleaseMode rel_mode := RSL_REL_MODE_NORMAL) := { msg_disc := ts_RSL_MsgDisc(RSL_MDISC_RLL, false), msg_type := RSL_MT_REL_REQ, ies :={ t_RSL_IE(RSL_IE_CHAN_NR, RSL_IE_Body:{chan_nr := chan_nr}), - t_RSL_IE(RSL_IE_LINK_IDENT, RSL_IE_Body:{link_id := link_id}) + t_RSL_IE(RSL_IE_LINK_IDENT, RSL_IE_Body:{link_id := link_id}), + t_RSL_IE(RSL_IE_RELEASE_MODE, RSL_IE_Body:{release_mode := rel_mode}) } } template RSL_Message tr_RSL_REL_REQ(template RslChannelNr chan_nr, - template RslLinkId link_id) := { + template RslLinkId link_id, + template RSL_IE_ReleaseMode rel_mode := ?) := { msg_disc := tr_RSL_MsgDisc(RSL_MDISC_RLL, false), msg_type := RSL_MT_REL_REQ, ies :={ tr_RSL_IE(RSL_IE_Body:{chan_nr := chan_nr}), tr_RSL_IE(RSL_IE_Body:{link_id := link_id}), - * + tr_RSL_IE(RSL_IE_Body:{release_mode := rel_mode}) } } @@ -993,6 +1012,13 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie modifies ts_RSL_DATA_REQ := { msg_type := RSL_MT_UNIT_DATA_REQ } + template RSL_Message tr_RSL_UNITDATA_REQ(template RslChannelNr chan_nr, + template RslLinkId link_id, + template octetstring l3_info) + modifies tr_RSL_DATA_REQ := { + msg_type := RSL_MT_UNIT_DATA_REQ + } + /* 8.3.11 BTS -> BSC */ template (value) RSL_Message ts_RSL_UNITDATA_IND(template (value) RslChannelNr chan_nr, @@ -1001,6 +1027,14 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie modifies ts_RSL_DATA_IND := { msg_type := RSL_MT_UNIT_DATA_IND } + template RSL_Message tr_RSL_UNITDATA_IND(template RslChannelNr chan_nr, + template (value) RslLinkId link_id, + template octetstring l3_info) + modifies tr_RSL_DATA_IND := { + msg_type := RSL_MT_UNIT_DATA_IND + } + + /* DEDICATED CANNEL MANAGEMENT MESSAGES */