2019-05-30 14:33:38 +00:00
|
|
|
|
module BTS_Tests_LAPDm {
|
2019-05-30 14:33:58 +00:00
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
import from GSM_Types all;
|
|
|
|
|
import from Osmocom_Types all;
|
|
|
|
|
import from LAPDm_RAW_PT all;
|
|
|
|
|
import from LAPDm_Types all;
|
2019-05-31 20:24:57 +00:00
|
|
|
|
import from RSL_Types all;
|
2019-05-30 14:36:11 +00:00
|
|
|
|
import from BTS_Tests all;
|
2019-05-31 20:24:57 +00:00
|
|
|
|
import from Misc_Helpers all;
|
2019-05-30 14:36:11 +00:00
|
|
|
|
|
|
|
|
|
/* test that use exclusively only LAPDm over L1CTL */
|
|
|
|
|
type component lapdm_test_CT {
|
|
|
|
|
port LAPDm_PT LAPDM;
|
|
|
|
|
var lapdm_CT lapdm_component;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/* contrary to BTS_Tests.ttcn, we use LAPDm_PT here, a convenience wrapper
|
|
|
|
|
* around L1CTL to perform encode/decode of abstract LAPDm frames */
|
2017-07-16 13:44:44 +00:00
|
|
|
|
|
2019-05-30 14:45:15 +00:00
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* Test using only L1CTL/LAPDm
|
|
|
|
|
*********************************************************************************/
|
|
|
|
|
|
|
|
|
|
function f_lapdm_init() runs on lapdm_test_CT {
|
2019-05-30 14:36:11 +00:00
|
|
|
|
/* create the LAPDm component */
|
|
|
|
|
lapdm_component := lapdm_CT.create;
|
|
|
|
|
/* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */
|
|
|
|
|
connect(self:LAPDM, lapdm_component:LAPDM_SP);
|
|
|
|
|
/* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally
|
|
|
|
|
* connected to the Unix Domain Socket test port */
|
|
|
|
|
map(lapdm_component:L1CTL, system:L1CTL);
|
|
|
|
|
|
|
|
|
|
/* start the LAPDm parallel component calling it's local function LAPDmStart */
|
|
|
|
|
lapdm_component.start(LAPDmStart());
|
|
|
|
|
}
|
2017-07-17 19:00:48 +00:00
|
|
|
|
|
2019-05-31 20:24:57 +00:00
|
|
|
|
function f_lapdm_exit() runs on lapdm_test_CT {
|
|
|
|
|
lapdm_component.stop;
|
|
|
|
|
lapdm_component.done;
|
|
|
|
|
unmap(lapdm_component:L1CTL, system:L1CTL);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
|
|
|
|
|
function f_establish_dcch() runs on lapdm_test_CT {
|
2019-05-31 20:24:57 +00:00
|
|
|
|
var BCCH_tune_req tune_req := { arfcn := { false, mp_trx0_arfcn }, combined_ccch := true };
|
2019-05-30 14:36:11 +00:00
|
|
|
|
var DCCH_establish_req est_req := { ra := 23 };
|
2017-07-16 13:44:44 +00:00
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
LAPDM.send(tune_req);
|
|
|
|
|
LAPDM.send(est_req);
|
|
|
|
|
LAPDM.receive(DCCH_establish_res:?);
|
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-05-31 20:24:57 +00:00
|
|
|
|
/* 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:?);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
/* 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 := {};
|
|
|
|
|
LAPDM.send(rel_req);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := {
|
|
|
|
|
sacch := sacch,
|
|
|
|
|
sapi := sapi,
|
|
|
|
|
lapdm := frame
|
|
|
|
|
}
|
2017-07-16 21:18:09 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on ConnHdlr return boolean {
|
2019-05-30 14:36:11 +00:00
|
|
|
|
var LAPDm_ph_data phd;
|
|
|
|
|
var boolean result := false;
|
|
|
|
|
timer T := 5.0;
|
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
LAPDM.send(t_PH_DATA(sapi, use_sacch, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=false, l3:=payload)));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
T.start
|
|
|
|
|
alt {
|
2019-06-14 09:44:29 +00:00
|
|
|
|
[] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=false, l3:=payload))) { result := true; }
|
|
|
|
|
[] RSL.receive {repeat;}
|
|
|
|
|
[] LAPDM.receive { repeat; }
|
2019-05-30 14:36:11 +00:00
|
|
|
|
[] T.timeout { }
|
2017-07-16 19:05:18 +00:00
|
|
|
|
}
|
2019-06-14 09:44:29 +00:00
|
|
|
|
LAPDM.send(t_PH_DATA(sapi, use_sacch, ts_LAPDm_RR(sapi, c_r:=cr_MT_CMD, p:=false, nr:=0)));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
return result;
|
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_TC_sabm_ua_dcch_sapi0(charstring id) runs on ConnHdlr {
|
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
var default d := activate(as_ignore_background());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) {
|
|
|
|
|
setverdict(fail);
|
2017-07-16 19:05:18 +00:00
|
|
|
|
}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(pass);
|
2019-06-14 09:44:29 +00:00
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_TC_sabm_ua_dcch_sapi0_nopayload(charstring id) runs on ConnHdlr {
|
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
var default d := activate(as_ignore_background());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
if (f_test_sabm_results_in_ua(0, false, ''O)) {
|
|
|
|
|
setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without");
|
2017-07-16 21:18:09 +00:00
|
|
|
|
}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(pass);
|
2019-06-14 09:44:29 +00:00
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_TC_sabm_ua_dcch_sapi3(charstring id) runs on ConnHdlr {
|
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
var default d := activate(as_ignore_background());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
|
|
|
|
|
setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3");
|
2017-07-17 19:00:48 +00:00
|
|
|
|
}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(pass);
|
2019-06-14 09:44:29 +00:00
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_TC_sabm_ua_dcch_sapi4(charstring id) runs on ConnHdlr {
|
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
var default d := activate(as_ignore_background());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
|
|
|
|
|
setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4");
|
2017-07-17 19:00:48 +00:00
|
|
|
|
}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(pass);
|
2019-06-14 09:44:29 +00:00
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_sabm_ua_dcch_sapi0() 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_ua_dcch_sapi0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_sabm_ua_dcch_sapi0_nopayload() 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_ua_dcch_sapi0_nopayload));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_sabm_ua_dcch_sapi3() 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_ua_dcch_sapi3));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
testcase TC_sabm_ua_dcch_sapi4() 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_ua_dcch_sapi4));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function f_TC_sabm_contention(charstring id) runs on ConnHdlr {
|
2019-05-30 14:36:11 +00:00
|
|
|
|
var LAPDm_ph_data phd;
|
|
|
|
|
const octetstring payload := '0102030405'O;
|
|
|
|
|
const GsmSapi sapi := 0;
|
|
|
|
|
const boolean use_sacch := false;
|
|
|
|
|
timer T := 5.0;
|
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
2019-05-30 14:36:11 +00:00
|
|
|
|
|
|
|
|
|
/* first frame is our real SABM */
|
2019-06-14 09:44:29 +00:00
|
|
|
|
LAPDM.send(t_PH_DATA(sapi, use_sacch, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=false, l3:=payload)));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
/* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */
|
2019-06-14 09:44:29 +00:00
|
|
|
|
LAPDM.send(t_PH_DATA(sapi, use_sacch, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=false, l3:='ABCDEF'O)));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
T.start
|
|
|
|
|
alt {
|
2019-06-14 09:44:29 +00:00
|
|
|
|
[] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=false, l3:=payload))) { setverdict(pass); repeat; }
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=false, l3:=?))) {
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(fail, "Second SABM was responded to during contention resolution");
|
2019-06-14 09:44:29 +00:00
|
|
|
|
}
|
|
|
|
|
[] RSL.receive {repeat;}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
[] LAPDM.receive { repeat };
|
|
|
|
|
[] T.timeout { }
|
2017-07-17 19:49:24 +00:00
|
|
|
|
}
|
2019-06-14 09:44:29 +00:00
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_sabm_contention() 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_contention));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-17 19:49:24 +00:00
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
/* we test that a re-transmitted SABM with identical payload will result in the retransmission of a
|
|
|
|
|
* UA. This is required during the contention resolution procedure as specified in 8.4.1.4 */
|
2019-06-14 09:44:29 +00:00
|
|
|
|
function f_TC_sabm_retransmit(charstring id) runs on ConnHdlr {
|
2019-05-30 14:36:11 +00:00
|
|
|
|
const octetstring payload := '00FEFEDEADBEEF'O;
|
2019-06-14 09:44:29 +00:00
|
|
|
|
fp_common_init();
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
var default d := activate(as_ignore_background());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
if (not f_test_sabm_results_in_ua(0, false, payload)) {
|
2019-06-14 09:44:29 +00:00
|
|
|
|
setverdict(fail);
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
|
|
|
|
if (not f_test_sabm_results_in_ua(0, false, payload)) {
|
2019-06-14 09:44:29 +00:00
|
|
|
|
setverdict(fail);
|
2017-07-30 20:51:04 +00:00
|
|
|
|
}
|
2019-05-30 14:36:11 +00:00
|
|
|
|
setverdict(pass);
|
2019-06-14 09:44:29 +00:00
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2019-06-14 09:44:29 +00:00
|
|
|
|
testcase TC_sabm_retransmit() 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));
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-31 20:24:57 +00:00
|
|
|
|
/*********************************************************************************
|
|
|
|
|
* 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();
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-02 20:58:58 +00:00
|
|
|
|
/* Mobile-Originated LAPDm establishment on given Link ID */
|
|
|
|
|
private function f_establish_mo(RslLinkId link_id) runs on ConnHdlr
|
|
|
|
|
{
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var octetstring l3_mo := f_rnd_octstring(5);
|
|
|
|
|
|
|
|
|
|
/* MO Establish Request via LADPm: SAPI = 0, C = 0, P = 1, M = 0, 0 ≤ L ≤ N201.. */
|
|
|
|
|
if (is_sacch) {
|
|
|
|
|
/* no payload permitted, as this is not contention resolution */
|
|
|
|
|
l3_mo := ''O;
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=true, l3:=l3_mo)));
|
|
|
|
|
RSL.receive(tr_RSL_EST_IND_NOL3(g_chan_nr, link_id));
|
|
|
|
|
} else {
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, 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, is_sacch, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=true, l3:=l3_mo)));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-31 20:24:57 +00:00
|
|
|
|
/* 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; }
|
|
|
|
|
}
|
2019-06-01 19:41:29 +00:00
|
|
|
|
/* ignore all DCCH frames */
|
|
|
|
|
private altstep as_lapdm_dcch() runs on ConnHdlr {
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, ?)) { repeat; }
|
|
|
|
|
}
|
2019-05-31 20:24:57 +00:00
|
|
|
|
/* ignore all LAPDm idle frames (UI) */
|
|
|
|
|
private altstep as_lapdm_idle() runs on ConnHdlr {
|
2019-06-01 19:41:29 +00:00
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, ?, tr_LAPDm_UI(?, ?, ''O))) { repeat; }
|
2019-05-31 20:24:57 +00:00
|
|
|
|
}
|
|
|
|
|
/* 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 */
|
2019-06-11 17:06:38 +00:00
|
|
|
|
private altstep as_ignore_background(boolean want_dcch := true, boolean ignore_rsl_errors := false) runs on ConnHdlr {
|
2019-06-01 19:41:29 +00:00
|
|
|
|
[want_dcch] as_lapdm_acch();
|
|
|
|
|
[not want_dcch] as_lapdm_dcch();
|
2019-05-31 20:24:57 +00:00
|
|
|
|
[] as_lapdm_idle();
|
|
|
|
|
[] as_rsl_meas_rep();
|
2019-06-11 17:06:38 +00:00
|
|
|
|
[not ignore_rsl_errors] as_rsl_fail_err();
|
|
|
|
|
[ignore_rsl_errors] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, ?, ?)) { repeat;}
|
2019-05-31 20:24:57 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 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;
|
|
|
|
|
|
2019-06-02 20:58:58 +00:00
|
|
|
|
f_establish_mo(link_id);
|
2019-05-31 20:24:57 +00:00
|
|
|
|
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 25.2.6.1 ns sequence error
|
|
|
|
|
sends wrong N(S), expects REJ, sends wrong N(S) with P=1, expects REJ with F=1 */
|
|
|
|
|
private function f_TC_ns_seq_error(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(ignore_rsl_errors := true));
|
|
|
|
|
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. */
|
|
|
|
|
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 MS shall then send an I frame containing Identity Request with incorrect N(S)
|
|
|
|
|
but correctly acknowledging the MS's I frame; P bit set to zero. */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false,
|
|
|
|
|
nr:=1, ns:=0, l3:=l3_mo)));
|
|
|
|
|
|
|
|
|
|
/* no rsl data ind due to wrong ns */
|
|
|
|
|
|
|
|
|
|
/* The BTS shall send a REJ frame. */
|
|
|
|
|
timer T1 := 2.0;
|
|
|
|
|
T1.start;
|
|
|
|
|
alt{
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_REJ(sapi, c_r:=cr_MT_RSP, p:=false, nr:=1)));
|
|
|
|
|
[] T1.timeout{ setverdict(fail, "Missing first REJ")}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
f_sleep(2.0); // T200
|
|
|
|
|
|
|
|
|
|
/* The MS shall, after T200, send another I frame with incorrect N(S), P bit set to 1 this time. */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=true,
|
|
|
|
|
nr:=1, ns:=0, l3:=l3_mo)));
|
|
|
|
|
|
|
|
|
|
/* The BTS shall respond with a REJ, F bit set to 1. */
|
|
|
|
|
T1.start;
|
|
|
|
|
alt{
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_REJ(sapi, c_r:=cr_MT_RSP, p:=true, nr:=1)));
|
|
|
|
|
[] T1.timeout{ setverdict(fail, "Missing second REJ")}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_ns_seq_error() 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_ns_seq_error));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 25.2.6.2 nr sequence error */
|
|
|
|
|
private function f_TC_nr_seq_error(charstring id) runs on ConnHdlr {
|
|
|
|
|
const integer sapi := 0;
|
|
|
|
|
var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(sapi));
|
|
|
|
|
var default d;
|
|
|
|
|
var integer n201 := 20;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
n201 := 18;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
|
|
|
|
d := activate(as_ignore_background(ignore_rsl_errors := true));
|
|
|
|
|
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 shall send an I frame containing an information field of length N201 and an
|
|
|
|
|
incorrect receive sequence number. */
|
|
|
|
|
l3_mo := f_rnd_octstring(n201);
|
|
|
|
|
/* SAPI = 0, C = 1, P = 0, M = 0, L = N201, N(S) = 0, N(R) = 1. * */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false,
|
|
|
|
|
nr:=1, ns:=0, l3:=l3_mo)));
|
|
|
|
|
|
|
|
|
|
/* The BTS may: a) send a DISC frame within N200×T200; */
|
|
|
|
|
/* DISC SAPI = 0, C = 0, P = 1, M = 0, L = 0. */
|
|
|
|
|
timer T1 := 2.0;
|
|
|
|
|
T1.start;
|
|
|
|
|
alt{
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_DISC(sapi, c_r:=cr_MT_CMD, p:=true)));
|
|
|
|
|
[] T1.timeout{ setverdict(fail, "Missing DISC from BTS")}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* a) the MS shall respond with a UA frame.
|
|
|
|
|
SAPI = 0, R = 0, F = 1, M = 0, L = 0. */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_UA(sapi, c_r:=cr_MO_CMD, f:=true, l3:=l3_mo)));
|
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_nr_seq_error() 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_nr_seq_error));
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-10 13:35:30 +00:00
|
|
|
|
private function f_TC_rec_invalid_frame_txrx(integer sapi, LapdmFrame x, integer line_nr) runs on ConnHdlr {
|
2019-06-11 17:06:38 +00:00
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, x));
|
|
|
|
|
f_sleep(2.0); // T200
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, false, ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=true, nr:=0)));
|
2019-12-10 13:35:30 +00:00
|
|
|
|
timer T1 := 2.0;
|
|
|
|
|
T1.start;
|
|
|
|
|
alt {
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=true , nr := 0))) { T1.stop; }
|
|
|
|
|
[] T1.timeout{ Misc_Helpers.f_shutdown(__BFILE__, line_nr, fail, "Missing LAPDm_RR RSP"); }
|
|
|
|
|
}
|
2019-06-11 17:06:38 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* 25.2.7 Test on receipt of invalid frames
|
|
|
|
|
sends a bunch of different invalid frames, expects the BTS to ignore all of them */
|
|
|
|
|
private function f_TC_rec_invalid_frame(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(ignore_rsl_errors := true));
|
|
|
|
|
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)));
|
2019-12-10 13:35:30 +00:00
|
|
|
|
T.start
|
|
|
|
|
alt {
|
|
|
|
|
[] RSL.receive(tr_RSL_EST_IND(g_chan_nr, link_id, l3_mo)) {}
|
|
|
|
|
[] T.timeout{ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Missing RSL EST IND"); }
|
|
|
|
|
}
|
|
|
|
|
alt {
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* UA: SAPI = 0, R = 0, F = 1, M = 0, L = L of SABM. */
|
2019-12-10 13:35:30 +00:00
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_UA(sapi, cr_MT_RSP, f:=true, l3:=l3_mo))) { T.stop; }
|
|
|
|
|
[] T.timeout{ Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Missing LAPDm UA RSP"); }
|
|
|
|
|
}
|
2019-06-11 17:06:38 +00:00
|
|
|
|
|
|
|
|
|
/* 1: One RR frame: SAPI = 0, R = 0, F = 0, M = 0, L > 0, N(R) = 1.
|
|
|
|
|
RR frame with the Length indicator greater than zero and a faulty N(R); */
|
|
|
|
|
var LapdmFrame x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.payload := f_rnd_octstring(5);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 3: One REJ frame: SAPI = 0, R = 0, F = 0, M = 0, L = 0, N(R) = 1, EA = 0.
|
|
|
|
|
EJ frame with the EA bit set to zero and a faulty N(R); */
|
|
|
|
|
x:= valueof(ts_LAPDm_REJ(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.addr.ea := false;
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 4: One SABM frame: SAPI = 0, C = 1, P = 1, M = 0, L = 0, EL = 0.
|
|
|
|
|
SABM frame with the EL bit set to zero; */
|
|
|
|
|
l3_mo := ''O;
|
|
|
|
|
x:= valueof(ts_LAPDm_SABM(sapi, c_r:=cr_MO_CMD, p:=true, l3:=l3_mo));
|
|
|
|
|
x.ab.el := 0;
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 5: One DM frame: SAPI = 0, R = 0, F = 1, M = 0, L > 0.
|
|
|
|
|
DM frame with the Length indicator greater than zero;*/
|
|
|
|
|
x:= valueof(ts_LAPDm_DM(sapi, c_r:=cr_MO_CMD, f:=true));
|
|
|
|
|
x.ab.payload := f_rnd_octstring(5);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 6: One DISC frame: SAPI = 0, C = 1, P = 1, M = 1, L = 0.
|
|
|
|
|
DISC frame with the M bit set to 1; */
|
|
|
|
|
x:= valueof(ts_LAPDm_DISC(sapi, c_r:=cr_MO_CMD, p:=true));
|
|
|
|
|
x.ab.m := true;
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 7: One UA frame: SAPI = 0, R = 0, F = 0, M = 0, L = 0, EA = 0.
|
|
|
|
|
UA frame with the EA bit set to zero*/
|
|
|
|
|
x:= valueof(ts_LAPDm_UA(sapi, c_r:=cr_MO_CMD, f:=false, l3:=''O));
|
|
|
|
|
x.ab.addr.ea := false;
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 8: One I frame: SAPI = 0, C = 1, P = 0, M = 0, L > N201, N(R) = 0, N(S) = 6.
|
|
|
|
|
I frame with the Length indicator greater than N201;*/
|
|
|
|
|
x:= valueof(ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=true, nr := 0, ns := 6, l3 := f_rnd_octstring(25)))
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 9: One I frame: SAPI = 0, C = 1, P = 0, M = 1, L < N201, N(R) = 0, N(S) = 7.
|
|
|
|
|
I frame with the M bit set to 1 and the Length indicator less than N201;*/
|
|
|
|
|
x:= valueof(ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=true, nr := 0, ns := 7, l3 := f_rnd_octstring(5)))
|
|
|
|
|
x.ab.m := true;
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 10: One RR frame: SAPI = 0, C = 1, P = 1, M = 0, L = 0, N(R) = 0. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=true, nr:=0));
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
|
|
|
|
|
/* command frames with correct Address and Length indicator field and a non-implemented control field */
|
|
|
|
|
/* 12: One command frame with Control Field = xxx1 1101. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('00011101'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 13: One command frame with Control field = xxx1 1011. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('00011011'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 14: One command frame with Control field = xxx1 0111. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('00010001'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 15: One command frame with Control field = 01x1 1111. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('01011111'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 16: One command frame with Control field = 1xx1 1111. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('10011111'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 17: One command frame with Control field = 0011 0011. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('00110011'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
/* 18: One command frame with Control field = 1xx1 0011. */
|
|
|
|
|
x:= valueof(ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=false, nr:=1));
|
|
|
|
|
x.ab.ctrl.other := bit2int('10010011'B);
|
2019-12-10 13:35:30 +00:00
|
|
|
|
f_TC_rec_invalid_frame_txrx(0, x, __LINE__);
|
2019-06-11 17:06:38 +00:00
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
testcase TC_rec_invalid_frame() runs on test_CT {
|
|
|
|
|
var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
|
|
|
|
|
pars.t_guard := 60.0;
|
|
|
|
|
f_testmatrix_each_chan(pars, refers(f_TC_rec_invalid_frame));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-01 09:46:25 +00:00
|
|
|
|
type record LapdmDlConfig {
|
|
|
|
|
integer n201,
|
|
|
|
|
integer t200
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type record LapdmDlState {
|
|
|
|
|
integer v_s,
|
|
|
|
|
integer v_a,
|
|
|
|
|
integer v_r
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
template (value) LapdmDlState t_init_LapdmDlState := {
|
|
|
|
|
v_s := 0,
|
|
|
|
|
v_a := 0,
|
|
|
|
|
v_r := 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function inc_mod8(inout integer v)
|
|
|
|
|
{
|
|
|
|
|
v := (v + 1) mod 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private function f_lapdm_transceive_mo(inout LapdmDlState dls, RslLinkId link_id, octetstring l3)
|
|
|
|
|
runs on ConnHdlr {
|
|
|
|
|
var LAPDm_ph_data pd;
|
|
|
|
|
var integer offset := 0;
|
|
|
|
|
var integer n201 := 20;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
n201 := 18;
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (offset < lengthof(l3)) {
|
|
|
|
|
var integer remain_len := lengthof(l3) - offset;
|
|
|
|
|
var integer seg_len := remain_len;
|
|
|
|
|
if (remain_len > n201) {
|
|
|
|
|
seg_len := n201;
|
|
|
|
|
}
|
|
|
|
|
var octetstring segment := substr(l3, offset, seg_len);
|
|
|
|
|
var boolean more;
|
|
|
|
|
if (offset + lengthof(segment) < lengthof(l3)) {
|
|
|
|
|
more := true;
|
|
|
|
|
} else {
|
|
|
|
|
more := false;
|
|
|
|
|
}
|
|
|
|
|
/* send the next segment */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch,
|
|
|
|
|
ts_LAPDm_I(link_id.sapi, c_r:=cr_MO_CMD, p:=false,
|
|
|
|
|
nr:=dls.v_a, ns:=dls.v_s, l3:=segment, m:=more)));
|
|
|
|
|
inc_mod8(dls.v_s);
|
|
|
|
|
offset := offset + lengthof(segment);
|
|
|
|
|
|
|
|
|
|
/* wait for it to be acknowledged */
|
|
|
|
|
alt {
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(link_id.sapi, c_r:=cr_MT_RSP,
|
|
|
|
|
p:=false, nr:=(dls.v_s) mod 8)));
|
2019-06-01 19:41:29 +00:00
|
|
|
|
[] as_ignore_background(not is_sacch);
|
2019-06-01 09:46:25 +00:00
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, is_sacch, ?)) -> value pd {
|
|
|
|
|
setverdict(fail, "received unexpected LAPDm ", pd);
|
|
|
|
|
repeat;
|
|
|
|
|
}
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, ?, ?)) { repeat; }
|
|
|
|
|
[offset < lengthof(l3)] RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, ?)) {
|
|
|
|
|
setverdict(fail, "received RSL DATA IND before message complete");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timer T := 1.0;
|
|
|
|
|
T.start;
|
|
|
|
|
alt {
|
|
|
|
|
[] RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3)) {
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
[] RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, ?)) {
|
|
|
|
|
setverdict(fail, "Received RSL DATA IND with wrong payload");
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout waiting for RSL DATA IND of de-segmented message");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Section 5.8.5 of TS 04.06 */
|
|
|
|
|
const integer c_TS0406_MAX_L3_OCTETS := 251;
|
|
|
|
|
|
2019-06-01 19:41:29 +00:00
|
|
|
|
/* test segmentation and de-segmentation (concatenation) of a large message in uplink
|
|
|
|
|
* on specified SAPI/channel */
|
|
|
|
|
private function f_TC_segm_concat(charstring id, RslLinkId link_id) runs on ConnHdlr {
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
2019-06-01 09:46:25 +00:00
|
|
|
|
var default d;
|
|
|
|
|
timer T := 3.0;
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
2019-06-01 19:41:29 +00:00
|
|
|
|
d := activate(as_ignore_background(not is_sacch));
|
2019-06-01 09:46:25 +00:00
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
|
2019-06-02 20:58:58 +00:00
|
|
|
|
f_establish_mo(link_id);
|
2019-06-01 09:46:25 +00:00
|
|
|
|
|
2019-06-02 20:58:58 +00:00
|
|
|
|
var octetstring l3_mo := f_rnd_octstring(c_TS0406_MAX_L3_OCTETS);
|
2019-06-01 09:46:25 +00:00
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
|
|
|
|
|
var LapdmDlState dls := valueof(t_init_LapdmDlState);
|
|
|
|
|
f_lapdm_transceive_mo(dls, link_id, l3_mo);
|
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
2019-06-01 19:41:29 +00:00
|
|
|
|
private function f_TC_segm_concat_dcch(charstring id) runs on ConnHdlr {
|
|
|
|
|
f_TC_segm_concat(id, valueof(ts_RslLinkID_DCCH(0)));
|
|
|
|
|
}
|
|
|
|
|
private function f_TC_segm_concat_sacch(charstring id) runs on ConnHdlr {
|
|
|
|
|
f_TC_segm_concat(id, link_id :=valueof(ts_RslLinkID_SACCH(0)));
|
|
|
|
|
}
|
|
|
|
|
/* test mobile-originated segmentation/de-segmentation on DCCH */
|
|
|
|
|
testcase TC_segm_concat_dcch() runs on test_CT {
|
2019-06-01 09:46:25 +00:00
|
|
|
|
var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN));
|
2019-06-01 19:41:29 +00:00
|
|
|
|
f_testmatrix_each_chan(pars, refers(f_TC_segm_concat_dcch));
|
2019-06-01 09:46:25 +00:00
|
|
|
|
}
|
2019-06-01 19:41:29 +00:00
|
|
|
|
/* test mobile-originated segmentation/de-segmentation on SACCH */
|
|
|
|
|
testcase TC_segm_concat_sacch() 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_segm_concat_sacch));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-02 20:13:50 +00:00
|
|
|
|
/* TS 04.06 Section 5.8.2.1 */
|
|
|
|
|
private function f_n200_by_chan_nr(RslChannelNr chan_nr, RslLinkId link_id) return integer {
|
|
|
|
|
/* SACCH irrespective of physical channel type */
|
|
|
|
|
if (match(link_id, tr_RslLinkID_SACCH(?))) {
|
|
|
|
|
return 5;
|
|
|
|
|
}
|
|
|
|
|
/* DCCH below */
|
|
|
|
|
select (chan_nr) {
|
|
|
|
|
case (t_RslChanNr_SDCCH4(?, ?)) { return 23; }
|
|
|
|
|
case (t_RslChanNr_SDCCH8(?, ?)) { return 23; }
|
|
|
|
|
case (t_RslChanNr_Bm(?)) { return 34; }
|
|
|
|
|
case (t_RslChanNr_Lm(?, ?)) { return 29; }
|
|
|
|
|
}
|
|
|
|
|
setverdict(fail, "Unknown chan_nr ", chan_nr, " or link_id ", link_id);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Test if there are exactly N200+1 transmissions of I frames; inspired by 25.2.4.1 */
|
|
|
|
|
private function f_TC_t200_n200(charstring id) runs on ConnHdlr {
|
|
|
|
|
var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
var integer n200 := f_n200_by_chan_nr(g_chan_nr, link_id);
|
|
|
|
|
var integer num_retrans := 0;
|
|
|
|
|
timer T := 3.0;
|
|
|
|
|
var default d;
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
|
|
|
|
d := activate(as_ignore_background(true));
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
|
2019-06-02 20:58:58 +00:00
|
|
|
|
f_establish_mo(link_id);
|
2019-05-31 20:24:57 +00:00
|
|
|
|
|
2019-06-02 20:13:50 +00:00
|
|
|
|
var octetstring l3_mt := f_rnd_octstring(20);
|
|
|
|
|
RSL.send(ts_RSL_DATA_REQ(g_chan_nr, link_id, l3_mt));
|
|
|
|
|
/* first transmission, P = 0 */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=false,
|
|
|
|
|
nr:=0, ns:=0, l3:=l3_mt)));
|
|
|
|
|
deactivate(d);
|
|
|
|
|
|
|
|
|
|
alt {
|
|
|
|
|
/* re-transmission, P = 1 */
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, is_sacch,
|
|
|
|
|
tr_LAPDm_I(sapi, c_r:=cr_MT_CMD, p:=true, nr:=0, ns:=0, l3:=l3_mt))) {
|
|
|
|
|
num_retrans := num_retrans + 1;
|
|
|
|
|
if (num_retrans < n200) {
|
|
|
|
|
repeat;
|
|
|
|
|
} else if (num_retrans == n200) {
|
|
|
|
|
T.start; /* wait for some more time if there are more retransmissions */
|
|
|
|
|
repeat;
|
|
|
|
|
} else {
|
|
|
|
|
/* break */
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, false, tr_LAPDm_I(sapi, ?, ?, ?, ?, ?))) {
|
|
|
|
|
setverdict(fail, "Received unexpected I frame");
|
|
|
|
|
}
|
|
|
|
|
[not is_sacch] as_lapdm_acch();
|
|
|
|
|
[is_sacch] as_lapdm_dcch();
|
|
|
|
|
[] as_lapdm_idle();
|
|
|
|
|
[] as_rsl_meas_rep();
|
|
|
|
|
[num_retrans == n200] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, link_id, '01'O)) {
|
|
|
|
|
/* break */
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Missing RSL RLL ERROR INDICATION");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (num_retrans == n200) {
|
|
|
|
|
setverdict(pass, "Received ", num_retrans, " on channel ", g_chan_nr, " link ", link_id);
|
|
|
|
|
} else if (num_retrans < n200) {
|
|
|
|
|
setverdict(fail, "Too few retransmissions (", num_retrans, "); N200=", n200,
|
|
|
|
|
" on channel ", g_chan_nr, " link ", link_id);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
testcase TC_t200_n200() 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_t200_n200));
|
|
|
|
|
}
|
2019-05-31 20:24:57 +00:00
|
|
|
|
|
2019-06-02 21:14:04 +00:00
|
|
|
|
/* Ensure BTS repeats RR frame after retransmitting I frame to emulate RR loss;
|
|
|
|
|
Inspired by TS 51.010-1 25.2.4.3 */
|
|
|
|
|
private function f_TC_rr_response_frame_loss(charstring id) runs on ConnHdlr {
|
|
|
|
|
var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
timer T := 3.0;
|
|
|
|
|
var default d;
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
|
|
|
|
d := activate(as_ignore_background(true));
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
|
|
|
|
|
f_establish_mo(link_id);
|
|
|
|
|
|
|
|
|
|
var octetstring l3_mo := f_rnd_octstring(10);
|
|
|
|
|
/* Send an I frame to the BTS: SAPI = 0, C = 1, P = 0, M = 0, L = 3, N(S) = 0, N(R) = 0 */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, 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));
|
|
|
|
|
/* SAPI = 0, R = 1, F = 0, M = 0, L = 0, N(R) = 1. */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=false, nr:=1)));
|
|
|
|
|
|
|
|
|
|
/* Re-send I frame: SAPI = 0, C = 1, P = 1, M = 0, L = 3, N(S) = 0, N(R) = 0. */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=true, nr:=0, ns:=0,
|
|
|
|
|
l3:=l3_mo)));
|
|
|
|
|
|
|
|
|
|
T.start;
|
|
|
|
|
alt {
|
|
|
|
|
/* RR: SAPI = 0, R = 1, F = 1, M = 0, L = 0, N(R) = 1. */
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=true, nr:=1))) {
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
/* REJ: SAPI = 0, R = 1, F = 1, M = 0, L = 0, N(R) = 1. */
|
|
|
|
|
[] LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_REJ(sapi, c_r:=cr_MT_RSP, p:=true, nr:=1))) {
|
|
|
|
|
setverdict(pass);
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {
|
|
|
|
|
setverdict(fail, "Timeout waiting for RR or REJ");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
testcase TC_rr_response_frame_loss() 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_rr_response_frame_loss));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-02 21:23:45 +00:00
|
|
|
|
/* Ensure BTS ignores I frames with wrong C/R bit; Inspired by TS 51.010-1 25.2.5.1 */
|
|
|
|
|
private function f_TC_incorrect_cr(charstring id) runs on ConnHdlr {
|
|
|
|
|
var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
timer T := 3.0;
|
|
|
|
|
var default d;
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
|
|
|
|
d := activate(as_ignore_background(true));
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
|
|
|
|
|
f_establish_mo(link_id);
|
|
|
|
|
|
|
|
|
|
var octetstring l3_mo := f_rnd_octstring(10);
|
|
|
|
|
/* Send an I frame to the BTS: SAPI = 0, C = 0, P = 1, M = 0, L = 3, N(S) = 0, N(R) = 0 */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_I(sapi, c_r:=cr_MO_RSP, p:=true, nr:=0, ns:=0,
|
|
|
|
|
l3:=l3_mo)));
|
|
|
|
|
T.start;
|
|
|
|
|
alt {
|
|
|
|
|
[] RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3_mo)) {
|
|
|
|
|
setverdict(fail, "BTS didn't ignore I frame with wrong C/R bit");
|
|
|
|
|
}
|
|
|
|
|
[] RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, link_id, '0C'O)) {
|
|
|
|
|
repeat;
|
|
|
|
|
}
|
|
|
|
|
/* ensure BTS still sends idle frames */
|
|
|
|
|
[] as_lapdm_idle() {
|
|
|
|
|
setverdict(pass, "still sending idle frames");
|
|
|
|
|
}
|
|
|
|
|
[] T.timeout {}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Send RR command P=1 */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=true, nr:=0)));
|
|
|
|
|
|
|
|
|
|
/* The BTS shall respond with a RR response, F bit set to 1. */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=true, nr:=0)));
|
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
testcase TC_incorrect_cr() 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_incorrect_cr));
|
|
|
|
|
}
|
2019-06-04 19:46:07 +00:00
|
|
|
|
|
|
|
|
|
/* test that the BTS will take no action when it receives an SABM frame with the C bit set wrong (R)
|
|
|
|
|
Inspired by TS 51.010-1 25.2.5.2 */
|
|
|
|
|
private function f_TC_sabm_incorrect_c(charstring id) runs on ConnHdlr {
|
|
|
|
|
var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0));
|
|
|
|
|
var integer sapi := link_id.sapi;
|
|
|
|
|
var boolean is_sacch := false;
|
|
|
|
|
if (link_id.c == SACCH) {
|
|
|
|
|
is_sacch := true;
|
|
|
|
|
}
|
|
|
|
|
timer T := 3.0;
|
|
|
|
|
var default d;
|
|
|
|
|
|
|
|
|
|
fp_common_init();
|
|
|
|
|
|
|
|
|
|
/* some common altstep for meas res and other background noise */
|
|
|
|
|
d := activate(as_ignore_background(true));
|
|
|
|
|
RSL.clear;
|
|
|
|
|
LAPDM.clear;
|
|
|
|
|
|
|
|
|
|
f_establish_mo(link_id);
|
|
|
|
|
|
|
|
|
|
/* Send I-frame SAPI = 0, C = 1, P = 0, M = 0, L = 3, N(S) = 0, N(R) = 0 */
|
|
|
|
|
var octetstring l3_mo := '010203'O;
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_I(sapi, c_r:=cr_MO_CMD, p:=false, nr:=0, ns:=0,
|
|
|
|
|
l3:=l3_mo)));
|
|
|
|
|
/* Expect RR SAPI = 0, R = 1, F = 0, M = 0, L = 0, N(R) = 1 */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=false, nr:=1)));
|
|
|
|
|
RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3_mo));
|
|
|
|
|
/* Send SABM SAPI = 0, C = 0, P = 1, M = 0, L = 0 */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_SABM(sapi, c_r:=cr_MO_RSP, p:=true, l3:=''O)));
|
|
|
|
|
/* Expect RSL ERR IND */
|
|
|
|
|
RSL.receive(tr_RSL_ERROR_IND(g_chan_nr, link_id, '0C'O));
|
|
|
|
|
/* Expect fill frame C = 0, P = 0, M = 0, L = 0 */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_UI(0, ?, ''O)));
|
|
|
|
|
/* Send RR command (P=1) SAPI = 0, C = 1, P = 1, M = 0, L = 0, N(R) = 0 */
|
|
|
|
|
LAPDM.send(t_PH_DATA(0, is_sacch, ts_LAPDm_RR(sapi, c_r:=cr_MO_CMD, p:=true, nr:=0)));
|
|
|
|
|
/* Expect RR response (F=1) SAPI = 0, R = 1, F = 1, M = 0, L = 0, N(R) = 1 */
|
|
|
|
|
LAPDM.receive(t_PH_DATA(0, is_sacch, tr_LAPDm_RR(sapi, c_r:=cr_MT_RSP, p:=true, nr:=1)));
|
|
|
|
|
|
|
|
|
|
deactivate(d);
|
|
|
|
|
|
|
|
|
|
fp_common_fini();
|
|
|
|
|
}
|
|
|
|
|
testcase TC_sabm_incorrect_c() 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_incorrect_c));
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-30 14:36:11 +00:00
|
|
|
|
control {
|
|
|
|
|
execute(TC_sabm_ua_dcch_sapi0());
|
|
|
|
|
execute(TC_sabm_ua_dcch_sapi0_nopayload());
|
|
|
|
|
execute(TC_sabm_ua_dcch_sapi3());
|
|
|
|
|
execute(TC_sabm_ua_dcch_sapi4());
|
|
|
|
|
execute(TC_sabm_contention());
|
|
|
|
|
execute(TC_sabm_retransmit());
|
2019-05-31 20:24:57 +00:00
|
|
|
|
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());
|
2019-06-11 17:06:38 +00:00
|
|
|
|
execute(TC_ns_seq_error());
|
|
|
|
|
execute(TC_nr_seq_error());
|
|
|
|
|
execute(TC_rec_invalid_frame());
|
2019-06-01 19:41:29 +00:00
|
|
|
|
execute(TC_segm_concat_dcch());
|
|
|
|
|
execute(TC_segm_concat_sacch());
|
2019-06-02 20:13:50 +00:00
|
|
|
|
execute(TC_t200_n200());
|
2019-06-02 21:14:04 +00:00
|
|
|
|
execute(TC_rr_response_frame_loss());
|
2019-06-02 21:23:45 +00:00
|
|
|
|
execute(TC_incorrect_cr());
|
2019-06-04 19:46:07 +00:00
|
|
|
|
execute(TC_sabm_incorrect_c());
|
2019-05-30 14:36:11 +00:00
|
|
|
|
}
|
2017-07-16 19:05:18 +00:00
|
|
|
|
|
2017-07-16 05:35:10 +00:00
|
|
|
|
}
|