5951 lines
219 KiB
Plaintext
5951 lines
219 KiB
Plaintext
module PCU_Tests {
|
|
|
|
/* "RAW" PCU tests: Talk directly to the PCU socket of OsmoPCU on the one hand side (emulating
|
|
the BTS/BSC side PCU socket server) and the Gb interface on the other hand side. No NS/BSSGP
|
|
Emulation is used; rather, we simply use the NS_CodecPort to implement both standard and non-
|
|
standard procedures on the NS and BSSGP level. The goal of these tests is to test exactly
|
|
those NS and BSSGP implementations on the BSS (PCU) side. */
|
|
|
|
/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
|
|
* (C) 2019-2020 Vadim Yanitskiy <axilirator@gmail.com>
|
|
* All rights reserved.
|
|
*
|
|
* Released under the terms of GNU General Public License, Version 2 or
|
|
* (at your option) any later version.
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
friend module PCU_Tests_NS;
|
|
|
|
import from General_Types all;
|
|
import from Osmocom_Types all;
|
|
import from GSM_Types all;
|
|
import from GSM_RR_Types all;
|
|
|
|
import from Osmocom_VTY_Functions all;
|
|
import from TELNETasp_PortType all;
|
|
|
|
import from MobileL3_GMM_SM_Types all;
|
|
import from RLCMAC_CSN1_Types all;
|
|
import from RLCMAC_CSN1_Templates all;
|
|
import from RLCMAC_Types all;
|
|
import from RLCMAC_Templates all;
|
|
|
|
import from MobileL3_CommonIE_Types all;
|
|
import from L3_Templates all;
|
|
|
|
import from NS_Types all;
|
|
import from BSSGP_Types all;
|
|
import from Osmocom_Gb_Types all;
|
|
|
|
import from BSSGP_Emulation all; /* BssgpConfig */
|
|
import from NS_Emulation all; /* NSConfiguration */
|
|
|
|
import from UD_Types all;
|
|
import from PCUIF_Types all;
|
|
import from PCUIF_CodecPort all;
|
|
import from PCUIF_Components all;
|
|
import from IPL4asp_Types all;
|
|
import from Native_Functions all;
|
|
import from SGSN_Components all;
|
|
import from GPRS_Components all;
|
|
|
|
import from StatsD_Types all;
|
|
import from StatsD_CodecPort all;
|
|
import from StatsD_CodecPort_CtrlFunct all;
|
|
import from StatsD_Checker all;
|
|
|
|
import from IPA_Emulation all;
|
|
import from Osmocom_CTRL_Types all;
|
|
import from Osmocom_CTRL_Adapter all;
|
|
import from Osmocom_CTRL_Functions all;
|
|
|
|
modulepar {
|
|
charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
|
|
|
|
float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
|
|
|
|
charstring mp_pcu_statsd_ip := "127.0.0.1";
|
|
integer mp_pcu_statsd_port := 8125;
|
|
|
|
charstring mp_ctrl_neigh_ip := "127.0.0.1";
|
|
integer mp_ctrl_neigh_port := 4248;
|
|
}
|
|
|
|
|
|
/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
|
|
friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
|
|
:= {
|
|
version := PCUIF_Types.mp_pcuif_version,
|
|
flags := flags,
|
|
trx := ts_PCUIF_InfoTrxs_def(GPRS_Components.mp_base_arfcn),
|
|
bsic := 7,
|
|
mcc := 262,
|
|
mnc := 42,
|
|
mnc_3_digits := 0,
|
|
lac := 13135,
|
|
rac := 0,
|
|
nsei := mp_nsconfig.nsei,
|
|
nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
|
|
cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
|
|
cell_id := 20960,
|
|
repeat_time := 5 * 50,
|
|
repeat_count := 3,
|
|
bvci := mp_gb_cfg.bvc[0].bvci,
|
|
t3142 := 20,
|
|
t3169 := 5,
|
|
t3191 := 5,
|
|
t3193_10ms := 160,
|
|
t3195 := 5,
|
|
n3101 := 10,
|
|
n3103 := 4,
|
|
n3105 := 8,
|
|
cv_countdown := 15,
|
|
dl_tbf_ext := 250 * 10, /* ms */
|
|
ul_tbf_ext := 250 * 10, /* ms */
|
|
initial_cs := 2,
|
|
initial_mcs := 1,
|
|
nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
|
|
local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
|
|
remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
|
|
remote_addr := f_PCUIF_RemoteAddr(
|
|
f_PCUIF_AF2addr_type(mp_nsconfig.nsvc[0].provider.ip.address_family), mp_nsconfig.nsvc[0].provider.ip.local_ip)
|
|
}
|
|
|
|
/* Passed in RAN-INFO message from emulated neighbor using RIM */
|
|
const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
|
|
const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
|
|
const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
|
|
const octetstring si_default := si1_default & si3_default & si13_default;
|
|
|
|
const MultislotCap_GPRS mscap_gprs_def := {
|
|
gprsmultislotclass := '00011'B,
|
|
gprsextendeddynalloccap := '0'B
|
|
};
|
|
const MultislotCap_EGPRS mscap_egprs_def := {
|
|
egprsmultislotclass := '00011'B,
|
|
egprsextendeddynalloccap := '0'B
|
|
};
|
|
template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
|
|
template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
|
|
|
|
const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
|
|
gprsmultislotclass := '00011'B,
|
|
gprsextendeddynalloccap := '0'B
|
|
};
|
|
const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
|
|
egprsmultislotclass := '00011'B,
|
|
egprsextendeddynalloccap := '0'B
|
|
};
|
|
template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
|
|
template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
|
|
|
|
type record lqual_range {
|
|
/* component reference to the IPA_Client component used for RSL */
|
|
uint8_t low,
|
|
uint8_t high
|
|
}
|
|
|
|
type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
|
|
/* PCU interface abstraction component */
|
|
var RAW_PCUIF_CT vc_PCUIF;
|
|
|
|
/* StatsD */
|
|
var StatsD_Checker_CT vc_STATSD;
|
|
|
|
/* Connection to the PCUIF component */
|
|
port RAW_PCU_MSG_PT PCUIF;
|
|
/* VTY connection to the PCU */
|
|
port TELNETasp_PT PCUVTY;
|
|
|
|
/* Uplink CS/MCS thresholds, default from pcu_main.c: */
|
|
var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
|
|
{low := 5, high := 8},
|
|
{low := 7, high := 13},
|
|
{low := 12,high := 35}};
|
|
var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
|
|
{low := 5, high := 8},
|
|
{low := 7, high := 13},
|
|
{low := 12,high := 15},
|
|
{low := 14, high := 17},
|
|
{low := 16, high := 18},
|
|
{low := 17,high := 20},
|
|
{low := 19, high := 24},
|
|
{low := 23,high := 35}};
|
|
var uint8_t g_cs_initial_dl := 1;
|
|
var uint8_t g_cs_initial_ul := 1;
|
|
var uint8_t g_mcs_initial_dl := 1;
|
|
var uint8_t g_mcs_initial_ul := 1;
|
|
var uint8_t g_cs_max_dl := 4;
|
|
var uint8_t g_cs_max_ul := 4;
|
|
var uint8_t g_mcs_max_dl := 9;
|
|
var uint8_t g_mcs_max_ul := 9;
|
|
|
|
var boolean g_force_two_phase_access := false;
|
|
|
|
/* Guard timeout */
|
|
timer g_T_guard := 60.0;
|
|
};
|
|
|
|
private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
|
|
[] g_T_guard.timeout {
|
|
setverdict(fail, "Timeout of T_guard");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
|
|
f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
|
|
|
|
f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
|
|
f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
|
|
}
|
|
|
|
private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
|
|
var charstring cmd;
|
|
|
|
cmd := "cs link-quality-ranges" &
|
|
" cs1 " & int2str(g_cs_lqual_ranges[0].high) &
|
|
" cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
|
|
" cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
|
|
" cs4 " & int2str(g_cs_lqual_ranges[3].low);
|
|
f_vty_config2(PCUVTY, {"pcu"}, cmd);
|
|
|
|
cmd := "mcs link-quality-ranges" &
|
|
" mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
|
|
" mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
|
|
" mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
|
|
" mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
|
|
" mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
|
|
" mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
|
|
" mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
|
|
" mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
|
|
" mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
|
|
f_vty_config2(PCUVTY, {"pcu"}, cmd);
|
|
}
|
|
|
|
private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
|
|
f_pcuvty_set_neigh_caches(0, 0);
|
|
}
|
|
|
|
private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
|
|
runs on RAW_PCU_Test_CT {
|
|
if (neigh_cache_secs == -1) {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
|
|
} else {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
|
|
}
|
|
if (si_cache_secs == -1) {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
|
|
} else {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
|
|
}
|
|
}
|
|
|
|
private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
|
|
map(self:PCUVTY, system:PCUVTY);
|
|
f_vty_set_prompts(PCUVTY);
|
|
f_vty_transceive(PCUVTY, "enable");
|
|
|
|
/* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
|
|
if (egprs_only) {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
|
|
} else {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
|
|
}
|
|
|
|
if (g_force_two_phase_access) {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
|
|
} else {
|
|
f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
|
|
}
|
|
}
|
|
|
|
function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
|
|
runs on RAW_PCU_Test_CT {
|
|
/* Start the guard timer */
|
|
g_T_guard.start;
|
|
activate(as_Tguard_RAW());
|
|
|
|
/* Init PCU interface component */
|
|
vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
|
|
connect(vc_PCUIF:MTC, self:PCUIF);
|
|
map(vc_PCUIF:PCU, system:PCU);
|
|
|
|
/* Create one BTS component (we may want more some day) */
|
|
vc_BTS := RAW_PCU_BTS_CT.create("BTS");
|
|
connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
|
|
connect(vc_BTS:TC, self:BTS);
|
|
|
|
f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
|
|
|
|
f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
|
|
/* This is normally done in the ConnHdlr component, but here
|
|
* the Test_CT doubles as ConnHdlr */
|
|
connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
|
|
|
|
vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
|
|
vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
|
|
|
|
/* Wait until the BTS is ready (SI13 negotiated) */
|
|
BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
|
|
}
|
|
|
|
/* Register TLLI of each allocated GprsMS instance */
|
|
private function f_multi_ms_bssgp_register()
|
|
runs on RAW_PCU_Test_CT {
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
|
|
}
|
|
}
|
|
|
|
/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
|
|
private function f_multi_ms_establish_tbf(boolean do_activate := false)
|
|
runs on RAW_PCU_Test_CT {
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(g_ms[i]);
|
|
|
|
/* Send a random block, so this TBF becomes "active" */
|
|
if (do_activate) {
|
|
/* FIXME: use the new APU by Pau to get correct TRX/TS here */
|
|
var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
|
|
var octetstring dummy := f_rnd_octstring(12);
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t poll_fn;
|
|
|
|
f_ms_tx_ul_data_block(g_ms[i], dummy, with_tlli := true, fn := g_ms[i].ul_tbf.start_time_fn, nr := nr);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
|
|
}
|
|
}
|
|
}
|
|
|
|
private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
|
|
template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
|
|
runs on RAW_PCU_Test_CT return PollFnCtx {
|
|
var PollFnCtx pollctx;
|
|
|
|
/* Single block (two phase) packet access */
|
|
var uint16_t ra := bit2int(chan_req_sb);
|
|
if (g_force_two_phase_access) {
|
|
/* If 2phase access is enforced by the network, then let's
|
|
* request a One phase packet access, we'll receive a single block
|
|
* anyway
|
|
*/
|
|
ra := bit2int(chan_req_def);
|
|
}
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_use_ra(ms, ra, ra_is_11bit := 0);
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Make sure we've got an Uplink TBF assignment */
|
|
if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
|
|
setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Send PACKET RESOURCE REQUEST
|
|
* (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
|
|
*/
|
|
if (istemplatekind(pkt_res_req, "omit")) {
|
|
pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
|
|
}
|
|
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(valueof(pkt_res_req)), ms.ul_tbf.start_time_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
/* Store 1st UlTBF context before receiving next one, will
|
|
* overwrite the TS allocation on MS with info from new UL TBF:
|
|
*/
|
|
pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
|
|
f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
return pollctx;
|
|
}
|
|
|
|
testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
|
|
var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
|
|
var GprsTlli tlli := TLLI_UNUSED;
|
|
timer T;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
|
|
BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
|
|
|
|
T.start(2.0);
|
|
alt {
|
|
[] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
|
|
setverdict(pass);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
|
|
testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
|
|
var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
timer T;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
|
|
/* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
|
|
BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
|
|
|
|
T.start(2.0);
|
|
alt {
|
|
[] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
|
|
setverdict(pass);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
/* Make sure we don't receive data for that TBF since it was released
|
|
* before. Also check our TBF is not polled for UL. */
|
|
f_rx_rlcmac_dl_block_exp_dummy(dl_block);
|
|
if (dl_block.ctrl.mac_hdr.usf != USF_UNUSED) {
|
|
setverdict(fail, "Unexpected USF ", dl_block.ctrl.mac_hdr.usf);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* New data arrives, PCU should page the MS since no TBF active exists: */
|
|
/* Send some more data, it will never reach the MS */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test of correct Timing Advance at the time of TBF establishment
|
|
* (derived from timing offset of the Access Burst). */
|
|
testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
|
|
var GprsMS ms;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* We cannot send too many TBF requests in a short time because
|
|
* at some point the PCU will fail to allocate a new TBF. */
|
|
for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
|
|
/* Establish an Uplink TBF (send RACH.ind with current TA) */
|
|
ms.ta := ta;
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Make sure Timing Advance IE matches out expectations */
|
|
if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
|
|
setverdict(fail, "Timing Advance mismatch: ",
|
|
ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
|
|
" vs expected ", ta);
|
|
break;
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
|
|
* procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
|
|
* IUT that causes it to send an unreasonable Timing Advance value > 0 despite
|
|
* no active TBF exists at the moment of establishment (idle mode). */
|
|
testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will initiate Packet Downlink
|
|
* Assignment on CCCH (PCH). We don't care about the payload. */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Make sure that Timing Advance is 0 (the actual value is not known yet).
|
|
* As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
|
|
* the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
|
|
if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
|
|
setverdict(fail, "Timing Advance value doesn't match");
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify that the PCU generates valid PTCCH/D messages
|
|
* while neither Uplink nor Downlink TBF is established. */
|
|
testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
|
|
var BTS_PTCCH_Block pcu_msg;
|
|
timer T;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Sent an RTS.req for PTCCH/D */
|
|
BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
|
|
sapi := PCU_IF_SAPI_PTCCH, fn := 0,
|
|
arfcn := 871, block_nr := 0));
|
|
|
|
T.start(5.0);
|
|
alt {
|
|
/* Make sure the message is encoded correctly
|
|
* TODO: do we expect all TA values to be equal '1111111'B? */
|
|
[] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg);
|
|
|
|
[] BTS.receive(PCUIF_Message:?) { repeat; }
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for a PTCCH/D block");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test of correct Timing Advance during an active Uplink TBF.
|
|
*
|
|
* Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
|
|
* are not continuous and there can be long time gaps between them. This happens
|
|
* due to a bursty nature of packet data. The actual Timing Advance of a MS may
|
|
* significantly change between such rare Uplink transmissions, so GPRS introduces
|
|
* additional mechanisms to control Timing Advance, and thus reduce interference
|
|
* between neighboring TDMA time-slots.
|
|
*
|
|
* At the moment of Uplink TBF establishment, initial Timing Advance is measured
|
|
* from ToA (Timing of Arrival) of an Access Burst. This is covered by another
|
|
* test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
|
|
* sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
|
|
* among with the initial Timing Advance value. And here PTCCH comes to play.
|
|
*
|
|
* PTCCH is a unidirectional channel on which the network can instruct a sub-set
|
|
* of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
|
|
* continuously. To ensure continuous measurements of the signal propagation
|
|
* delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
|
|
* defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
|
|
*
|
|
* The purpose of this test case is to verify the assignment of Timing Advance
|
|
* Index, and the process of Timing Advance notification on PTCCH/D. The MTC
|
|
* first establishes several Uplink TBFs, but does not transmit any Uplink
|
|
* blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
|
|
* indications to the PCU, checking the correctness of two received PTCCH/D
|
|
* messages (period of PTCCH/D is two multi-frames).
|
|
*/
|
|
|
|
/* List of ToA values for Access Bursts to be sent on PTCCH/U,
|
|
* each ToA (Timing of Arrival) value is in units of 1/4 of
|
|
* a symbol (i.e. 1 symbol is 4 QTA units). */
|
|
type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
|
|
const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0,
|
|
0, 0, 0, 0
|
|
};
|
|
|
|
private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
|
|
in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
|
|
runs on RAW_PCU_Test_CT {
|
|
var RAW_PCU_Event event;
|
|
var integer ss;
|
|
|
|
/* Send Access Bursts on PTCCH/U for every TA Index */
|
|
[] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
|
|
ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
|
|
if (ss < 0) { /* Shall not happen */
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
log("Sending an Access Burst on PTCCH/U",
|
|
", sub-slot=", ss, " (TAI)",
|
|
", fn=", event.data.tdma_fn,
|
|
", ToA=", toa_map[ss], " (QTA)");
|
|
/* TODO: do we care about RA and burst format? */
|
|
BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
|
|
ra := oct2int('3A'O),
|
|
is_11bit := 0,
|
|
burst_type := BURST_TYPE_0,
|
|
fn := event.data.tdma_fn,
|
|
arfcn := 871,
|
|
qta := toa_map[ss],
|
|
sapi := PCU_IF_SAPI_PTCCH));
|
|
repeat;
|
|
}
|
|
}
|
|
|
|
private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
|
|
template PTCCHDownlinkMsg t_ta_msg)
|
|
runs on RAW_PCU_Test_CT {
|
|
var PTCCHDownlinkMsg ta_msg;
|
|
var PCUIF_Message pcu_msg;
|
|
timer T;
|
|
|
|
/* First, send an RTS.req for the upcoming PTCCH/D block */
|
|
BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
|
|
sapi := PCU_IF_SAPI_PTCCH, fn := 0,
|
|
arfcn := 871, block_nr := 0));
|
|
T.start(2.0);
|
|
alt {
|
|
/* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
|
|
* with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
|
|
[] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
|
|
/* In the end of 2nd multi-frame we should receive a PTCCH/D block */
|
|
[] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
|
|
sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
|
|
ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
|
|
log("Rx PTCCH/D message: ", ta_msg);
|
|
|
|
/* Make sure Timing Advance values match our expectations */
|
|
if (not match(ta_msg, t_ta_msg)) {
|
|
setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
|
|
}
|
|
}
|
|
[] BTS.receive { repeat; }
|
|
[] T.timeout {
|
|
setverdict(fail, "Timeout waiting for a PTCCH/D block");
|
|
}
|
|
}
|
|
}
|
|
|
|
testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
|
|
var template PacketUlAssign t_ul_tbf_ass;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Enable forwarding of PTCCH/U TDMA events to us */
|
|
BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
|
|
|
|
/* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
|
|
for (var integer i := 0; i < 7; i := i + 1) {
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* We expect incremental TFI/USF assignment (dynamic allocation) */
|
|
t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
|
|
if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
|
|
setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
|
|
break;
|
|
}
|
|
|
|
/* We also expect Timing Advance Index to be a part of the assignment */
|
|
if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
|
|
setverdict(fail, "Failed to match Timing Advance Index for #", i);
|
|
/* Keep going, the current OsmoPCU does not assign TA Index */
|
|
}
|
|
}
|
|
|
|
/* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
|
|
var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
|
|
for (var integer i := 0; i < 7; i := i + 1) {
|
|
/* ToA in units of 1/4 of a symbol */
|
|
toa_map[i] := (i + 1) * 7 * 4;
|
|
}
|
|
|
|
/* Now we have all 7 TBFs established in one-phase access mode,
|
|
* however we will not be sending any data on them. Instead, we
|
|
* will be sending RACH.ind on PTCCH/U during 4 multi-frame
|
|
* periods (TAI 0..8), and then will check two PTCCH/D blocks.
|
|
*
|
|
* Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
|
|
* time-slots, so at the moment of scheduling a PTCCH/D block
|
|
* the PCU has odd number of PTCCH/U Access Bursts received. */
|
|
f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
|
|
tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
|
|
/* Other values are not known (yet) */
|
|
tai3_ta := ?));
|
|
f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
|
|
tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
|
|
tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
|
|
/* Other values are out of our interest */
|
|
tai6_ta := ?));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
|
|
* OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
|
|
*
|
|
* NOTE: the ranges are intentionally overlapping because OsmoPCU
|
|
* does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
|
|
private template integer CS1_lqual_dB_range := (-infinity .. 6);
|
|
private template integer CS2_lqual_dB_range := (5 .. 8);
|
|
private template integer CS3_lqual_dB_range := (7 .. 13);
|
|
private template integer CS4_lqual_dB_range := (12 .. infinity);
|
|
|
|
testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var GprsMS ms;
|
|
var uint32_t unused_fn, sched_fn;
|
|
var uint4_t cv;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
|
|
/* The actual / old link quality values. We need to keep track of the old
|
|
* (basically previous) link quality value, because OsmoPCU actually
|
|
* changes the coding scheme if not only the actual, but also the old
|
|
* value leaves the current link quality range (window). */
|
|
var integer lqual_old;
|
|
ms.lqual_cb := 0;
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
/* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
|
|
for (var integer i := 150; i >= 0; i := i - 1) {
|
|
/* Update the old / actual link quality */
|
|
lqual_old := ms.lqual_cb;
|
|
ms.lqual_cb := 150 - i;
|
|
|
|
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
|
log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
|
|
if (i > g_bs_cv_max) {
|
|
cv := 15;
|
|
} else {
|
|
cv := i;
|
|
}
|
|
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
|
|
|
|
/* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
|
|
f_rx_rlcmac_dl_block(dl_block, unused_fn);
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
|
continue;
|
|
}
|
|
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
|
|
not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
|
|
setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
|
|
dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
|
|
|
|
/* Match the received Channel Coding Command. Since we are increasing
|
|
* the link quality value on each iteration and not decreasing, there
|
|
* is no need to check the both old and current link quality values. */
|
|
var template ChCodingCommand ch_coding;
|
|
select (lqual_old / 10) {
|
|
case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
|
|
case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
|
|
case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
|
|
case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
|
|
}
|
|
|
|
if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
|
|
setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test the max UL CS set by VTY works fine */
|
|
testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var ChCodingCommand last_ch_coding;
|
|
var uint32_t unused_fn, sched_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Set initial UL CS to 3 */
|
|
g_cs_initial_ul := 3;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Take lqual (dB->cB) so that we stay in that CS */
|
|
ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
/* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
|
|
while (true) {
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
|
|
f_rx_rlcmac_dl_block(dl_block, unused_fn);
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
|
continue;
|
|
}
|
|
|
|
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
|
|
not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
|
|
setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
|
|
break;
|
|
}
|
|
if (last_ch_coding != CH_CODING_CS3) {
|
|
setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Remaining UL blocks are used to make sure regardless of initial
|
|
/* lqual, we can go lower at any time */
|
|
/* 0 dB, make sure we downgrade CS */
|
|
ms.lqual_cb := 0;
|
|
/* 5 UL blocks, check we are in same initial CS: */
|
|
f_ms_tx_ul_data_block_multi(ms, 5);
|
|
/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
|
|
|
|
if (last_ch_coding != CH_CODING_CS1) {
|
|
setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test the max UL CS set by VTY works fine */
|
|
testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var ChCodingCommand last_ch_coding;
|
|
var uint32_t unused_fn, sched_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Set maximum allowed UL CS to 3 */
|
|
g_cs_max_ul := 3;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
/* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
ms.lqual_cb := 40*10; /* 40 dB */
|
|
f_ms_tx_ul_data_block_multi(ms, 16);
|
|
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
|
|
|
|
if (last_ch_coding != CH_CODING_CS3) {
|
|
setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test the initial DL CS set by VTY works fine */
|
|
testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var CodingScheme exp_dl_cs_mcs;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t poll_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Set initial allowed DL CS to 3 */
|
|
g_cs_initial_dl := 3;
|
|
exp_dl_cs_mcs := CS_3;
|
|
/* Set maximum allowed UL CS to 4 */
|
|
g_cs_max_dl := 4;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, poll_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
|
|
function f_dl_data_exp_cs(template (present) CodingScheme exp_final_cs := ?, template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
|
|
var octetstring data := f_rnd_octstring(1400);
|
|
var RlcmacDlBlock prev_dl_block, dl_block;
|
|
var uint32_t ack_fn;
|
|
var uint32_t fn;
|
|
var GprsMS ms;
|
|
var integer tx_data_remain := 10;
|
|
var integer bsn := 0;
|
|
var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
|
|
var integer bsn_mod;
|
|
var template (present) CodingScheme exp_tmp_csmcs;
|
|
|
|
if (using_egprs) {
|
|
exp_tmp_csmcs := mcs_egprs_any;
|
|
bsn_mod := 2048;
|
|
} else {
|
|
exp_tmp_csmcs := cs_gprs_any;
|
|
bsn_mod := 128;
|
|
}
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS */
|
|
f_sleep(X2002);
|
|
|
|
for (var integer i := 0; i < 800; i := i + 1) {
|
|
bsn := i mod bsn_mod;
|
|
f_rx_rlcmac_dl_block(dl_block, fn);
|
|
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
|
|
/* No more data to receive, done */
|
|
break;
|
|
}
|
|
|
|
f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
|
|
|
|
/* Keep Ack/Nack description updated */
|
|
f_dltbf_ack_block(ms.dl_tbf, dl_block);
|
|
|
|
/* TDMA frame number on which we are supposed to send the ACK */
|
|
if (f_dl_block_rrbp_valid(dl_block)) {
|
|
ack_fn := f_dl_block_ack_fn(dl_block, fn);
|
|
f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, using_egprs), ack_fn);
|
|
if (tx_data_remain != 0) {
|
|
/* Submit more data from time to time to keep the TBF ongoing */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
tx_data_remain := tx_data_remain - 1;
|
|
}
|
|
}
|
|
prev_dl_block := dl_block;
|
|
}
|
|
|
|
bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
|
|
f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
|
|
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify DL CS above "cs max" set by VTY is never used */
|
|
testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Set maximum allowed DL CS to 3 */
|
|
g_cs_initial_dl := 1;
|
|
g_cs_max_dl := 3;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
|
|
}
|
|
|
|
/* Check DL CS4 is used in good link conditions if allowed by config */
|
|
testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
|
|
g_cs_initial_dl := 1;
|
|
g_cs_max_dl := 4;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
|
|
}
|
|
|
|
/* Test the initial UL MCS set by VTY works fine */
|
|
testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var PollFnCtx pollctx;
|
|
var EgprsChCodingCommand last_ch_coding;
|
|
var uint32_t unused_fn, sched_fn;
|
|
var GprsMS ms;
|
|
var CodingScheme exp_ul_mcs;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Set initial UL MCS to 3 */
|
|
g_mcs_initial_ul := 3;
|
|
exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Take lqual (dB->cB) so that we stay in that MCS */
|
|
ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
|
|
|
|
/* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_egprs_def));
|
|
|
|
if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
|
|
setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
|
|
while (true) {
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
|
|
f_rx_rlcmac_dl_block(dl_block, unused_fn);
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
|
continue;
|
|
}
|
|
|
|
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
|
|
setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
break;
|
|
}
|
|
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
|
|
break;
|
|
}
|
|
if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
|
|
setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Remaining UL blocks are used to make sure regardless of initial
|
|
* lqual, we can go lower at any time
|
|
* 0 dB, make sure we downgrade MCS */
|
|
ms.lqual_cb := 0;
|
|
/* 5 UL blocks, check we are in same initial MCS: */
|
|
f_ms_tx_ul_data_block_multi(ms, 5);
|
|
/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
|
|
|
|
if (last_ch_coding != CH_CODING_MCS1) {
|
|
setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test the maximum UL MCS set by VTY works fine */
|
|
testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var EgprsChCodingCommand last_ch_coding;
|
|
var PollFnCtx pollctx;
|
|
var uint32_t unused_fn, sched_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Set maximum allowed UL MCS to 5 */
|
|
g_mcs_max_ul := 5;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_egprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
ms.lqual_cb := 40*10; /* 40 dB */
|
|
f_ms_tx_ul_data_block_multi(ms, 16);
|
|
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
|
|
last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
|
|
|
|
if (last_ch_coding != CH_CODING_MCS5) {
|
|
setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test the initial DL CS set by VTY works fine */
|
|
testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var CodingScheme exp_dl_cs_mcs;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t poll_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Set initial allowed DL MCS to 3 */
|
|
g_mcs_initial_dl := 3;
|
|
exp_dl_cs_mcs := MCS_3;
|
|
/* Set maximum allowed DL MCS to 4 */
|
|
g_mcs_max_dl := 4;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
|
|
|
|
/* ACK the DL block */
|
|
f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs)),
|
|
f_dl_block_ack_fn(dl_block, poll_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify DL MCS above "mcs max" set by VTY is never used */
|
|
testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Set maximum allowed DL CS to 3 */
|
|
g_mcs_initial_dl := 1;
|
|
g_mcs_max_dl := 3;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
f_pcuvty_set_link_quality_ranges();
|
|
|
|
f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_mcs_max_dl, true), bssgp_ms_racap_egprs_def);
|
|
}
|
|
|
|
/* Verify PCU drops TBF after some time of inactivity. */
|
|
testcase TC_t3141() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var BTS_PDTCH_Block data_msg;
|
|
var GprsMS ms;
|
|
var uint3_t rx_usf;
|
|
timer T_3141 := 1.0;
|
|
var boolean ul_tbf_usf_req := false;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
/* Only use 1 PDCH to simplify test: */
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish a one-phase access Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
T_3141.start;
|
|
|
|
/* Now we wait for PCU to transmit our USF */
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
|
|
alt {
|
|
[] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
?)) -> value data_msg {
|
|
if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
|
|
setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
|
|
if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
|
|
/* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
|
|
ul_tbf_usf_req := true;
|
|
f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15, with_tlli := false, fn := f_next_pdch_block(data_msg.raw.fn))
|
|
} else if (rx_usf == USF_UNUSED) {
|
|
if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
|
|
if (ul_tbf_usf_req) {
|
|
/* TBF was dropped by T3141, success */
|
|
setverdict(pass);
|
|
break;
|
|
} else {
|
|
log("PCU never requested USF, unexpected");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
} /* else: Keep waiting for TBF to be active by network */
|
|
} else {
|
|
log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
|
|
if (match(data_msg.dl_block,
|
|
tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
|
|
tr_UlAckNackGprs(tlli := ?,
|
|
acknack_desc := ?,
|
|
rel99 := *))))
|
|
{
|
|
log("Received UL ACK/NACK with TLLI set");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
[] T_3141.timeout {
|
|
log("T_3141 expired but TBF is still active, unexpected");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
[] BTS.receive {
|
|
/* We should never receive non-dummy messages, aka UL ACK/NACK,
|
|
* because we never sent the TLLI to the PCU */
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
|
|
* data. It should end up in N3101 reaching N3101_MAX and finally triggering
|
|
* T3169. See OS#5033 */
|
|
testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var BTS_PDTCH_Block data_msg;
|
|
var GprsMS ms;
|
|
var uint3_t rx_usf;
|
|
const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
|
|
var integer n3101 := 0;
|
|
timer T_3169 := 1.0;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
info_ind.n3101 := N3101_MAX;
|
|
info_ind.t3169 := 1;
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish UL TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Now we wait for PCU to transmit our USF */
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
|
|
alt {
|
|
[] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
?)) -> value data_msg {
|
|
if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
|
|
setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
|
|
if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
|
|
log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
|
|
n3101 := n3101 + 1;
|
|
if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
|
|
setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
} else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
|
|
/* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
|
|
log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
|
|
if (not T_3169.running) {
|
|
log("T3169 started");
|
|
T_3169.start;
|
|
}
|
|
} else if(rx_usf == USF_UNUSED and n3101 > 0) {
|
|
setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
} else {
|
|
log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
|
|
}
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
[] T_3169.timeout {
|
|
log("T_3169 expired");
|
|
/* Done in alt */
|
|
}
|
|
[] BTS.receive {
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
/* Now that T3169 has expired, establishing a Ul TBF should provide same
|
|
/* USFs as per previous TBF since they were freed at expiration time: */
|
|
var uint3_t old_usf[8] := ms.ul_tbf.usf;
|
|
var uint5_t old_tfi := ms.ul_tbf.tfi;
|
|
f_ms_establish_ul_tbf(ms);
|
|
if (old_tfi != ms.ul_tbf.tfi) {
|
|
setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
for (var integer i := 0; i < 8; i := i +1) {
|
|
if (ms.ul_tbf.usf[i] != old_usf[i]) {
|
|
setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
|
|
/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
|
|
freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
|
|
the final UL ACK sent at us. */
|
|
testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var BTS_PDTCH_Block data_msg;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var template RlcmacDlBlock exp_ul_ack;
|
|
var template UlAckNackGprs exp_ul_ack_sub;
|
|
var GprsMS ms;
|
|
const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
|
|
var integer N3103 := 0;
|
|
timer T_3169 := 1.0;
|
|
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
info_ind.n3103 := N3103_MAX;
|
|
info_ind.t3169 := 1;
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
|
|
exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
|
|
exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
|
|
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
alt {
|
|
[N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
exp_ul_ack)) -> value data_msg {
|
|
if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
|
|
setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
N3103 := N3103 + 1;
|
|
if (N3103 == N3103_MAX) {
|
|
/* At this point in time (N3103_MAX reached), PCU is
|
|
* moving the TBF to RELEASE state so no data/ctrl for
|
|
* it is tx'ed, hence the dummy blocks: */
|
|
T_3169.start;
|
|
}
|
|
repeat;
|
|
}
|
|
[N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
exp_ul_ack)) -> value data_msg {
|
|
setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
[] as_ms_rx_ignore_dummy(ms, nr);
|
|
[T_3169.running] T_3169.timeout {
|
|
log("T_3169 timeout");
|
|
/* Done in alt, wait for pending RTS initiated previously in
|
|
* above case before continuing (expect /* Dummy block): */
|
|
BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DUMMY_CTRL));
|
|
}
|
|
[] BTS.receive {
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
/* Now that T3169 has expired, establishing a Ul TBF should provide same
|
|
* USFs as per previous TBF since they were freed at expiration time: */
|
|
var uint3_t old_usf[8] := ms.ul_tbf.usf;
|
|
var uint5_t old_tfi := ms.ul_tbf.tfi;
|
|
f_ms_establish_ul_tbf(ms);
|
|
if (old_tfi != ms.ul_tbf.tfi) {
|
|
setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
for (var integer i := 0; i < 8; i := i +1) {
|
|
if (ms.ul_tbf.usf[i] != old_usf[i]) {
|
|
setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify that a Downlink TBF is kept available until T3191 fires, at which
|
|
* point the TBF is no longer available. In order to get to start of T3191, we
|
|
* have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
|
|
* until TBF release procedure starts after draining DL queue. */
|
|
testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data1 := f_rnd_octstring(200);
|
|
var octetstring data2 := f_rnd_octstring(10);
|
|
var uint32_t dl_fn;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var BTS_PDTCH_Block data_msg;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
/* Set timer to 1 sec (default 5) to speedup test: */
|
|
info_ind.t3191 := 1;
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
|
|
while (true) {
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
|
|
|
|
/* Keep Ack/Nack description updated (except for last BSN) */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
|
|
|
|
if (f_dl_block_rrbp_valid(dl_block)) {
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
alt {
|
|
[] as_ms_rx_ignore_dummy(ms, nr);
|
|
[] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
?)) -> value data_msg {
|
|
if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
|
|
log("Received FINAL_ACK");
|
|
ms.dl_tbf.acknack_desc.final_ack := '1'B;
|
|
break;
|
|
}
|
|
if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
|
|
}
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
[] BTS.receive {
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
/* Avoid ACKing the last RLC data block on purpose here, wait for t3191
|
|
to time out. We simply sleep instead of requesting blocks because
|
|
otherwise retransmissions would keep restarting the timer. */
|
|
f_sleep(int2float(info_ind.t3191));
|
|
|
|
/* The TBF should be freed now, so new data should trigger an Assignment: */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
/* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
|
|
testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data1 := f_rnd_octstring(1400);
|
|
var octetstring data2 := f_rnd_octstring(10);
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
/* Set timer to 1 sec (default 5) to speedup test: */
|
|
info_ind.t3191 := 1;
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
|
|
/* Send enough DL data to at least be able to DL ACK once (excl the
|
|
* FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
|
|
* other code paths like trying to Imm Assign on CCCH again, etc.. */
|
|
while (true) {
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
|
|
|
|
if (dl_block.data.mac_hdr.hdr_ext.fbi) {
|
|
log("Received FINAL_ACK");
|
|
ms.dl_tbf.acknack_desc.final_ack := '1'B;
|
|
break;
|
|
}
|
|
|
|
/* Keep Ack/Nack description updated (except for last BSN) */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
|
|
|
|
if (f_dl_block_rrbp_valid(dl_block)) {
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
}
|
|
}
|
|
|
|
/* Avoid ACKing the last RLC data block on purpose here, wait for t3191
|
|
to time out. We simply sleep instead of requesting blocks because
|
|
otherwise retransmissions would keep restarting the timer. */
|
|
f_sleep(int2float(info_ind.t3191));
|
|
|
|
/* The TBF should be freed now, so new data should trigger an Assignment: */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
/* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
|
|
* release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
|
|
* T3193) after DL TBF release */
|
|
testcase TC_t3193() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var boolean ok;
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
/* Now that final DL block is ACKED and TBF is released, T3193 in PCU
|
|
(T3192 in MS) was started and until it fires the MS will be available
|
|
on PDCH in case new data arrives from SGSN. Let's verify it: */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
|
|
freed and no longer available. Trigger it by sending DL blocks and never DL
|
|
ACKing the data (which are requested through RRBP) */
|
|
testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data1 := f_rnd_octstring(1000);
|
|
var octetstring data2 := f_rnd_octstring(10);
|
|
var uint32_t dl_fn;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var BTS_PDTCH_Block data_msg;
|
|
var GprsMS ms;
|
|
const integer N3105_MAX := 2;
|
|
var integer N3105 := 0;
|
|
timer T_3195 := 1.0;
|
|
var integer num_poll_recv := 0;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
/* Speedup test: */
|
|
info_ind.n3105 := N3105_MAX;
|
|
info_ind.t3195 := 1;
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Disable "MS delay release" timer, to avoid old DL data kept in cached
|
|
* MS and retransmitted after the TBF is released and later on created
|
|
* (because the MS is reused) */
|
|
f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
|
|
/* Now we go on receiving DL data and not answering RRBP: */
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
alt {
|
|
[not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DATA)) -> value data_msg {
|
|
if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
|
|
if (num_poll_recv == 0) {
|
|
/* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
|
|
} else {
|
|
log("Ignoring RRBP ", num_poll_recv);
|
|
N3105 := N3105 + 1;
|
|
}
|
|
num_poll_recv := num_poll_recv + 1;
|
|
}
|
|
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
/* At this point in time (N3105_MAX reached), PCU already moved TBF to
|
|
* RELEASE state so no data for it is tx'ed, hence the dummy blocks:
|
|
*/
|
|
[N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
|
|
if (not T_3195.running) {
|
|
T_3195.start;
|
|
/* We even send some new data, nothing should be sent to MS */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
|
|
}
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
[T_3195.running] T_3195.timeout {
|
|
log("T_3195 timeout");
|
|
/* Done in alt, wait for pending RTS initiated previously in
|
|
* above case before continuing (expect /* Dummy block): */
|
|
BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DUMMY_CTRL));
|
|
}
|
|
[] BTS.receive {
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
/* after T_3195 timeout, TBF is released */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
|
|
testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var octetstring total_payload;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
f_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* Send enough blocks to test whole procedure: Until Nth block
|
|
(N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
|
|
*/
|
|
total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* receive one message on BSSGP with all aggregated data in payload: */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
|
|
testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t dl_fn, sched_fn;
|
|
var octetstring payload;
|
|
var template (value) RlcmacUlBlock ul_data;
|
|
var template (value) LlcBlockHdr blk_hdr;
|
|
var template (value) LlcBlocks blocks;
|
|
var integer blk_len;
|
|
var CodingScheme tx_cs;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
|
|
blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
|
|
more := false, e := true);
|
|
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := 15,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := blocks,
|
|
tlli := ms.tlli);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
|
|
|
|
/* ACK and check it was received fine */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
/* receive one message on BSSGP with all aggregated data in payload: */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
|
|
|
|
/* Test sending LLC PDUS of incrementing size */
|
|
var integer max_size := 49;
|
|
for (var integer i := 1; i <= max_size; i := i + 1) {
|
|
var integer cv;
|
|
/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
|
|
log("Sending DATA.ind with LLC payload size ", i);
|
|
if (i < max_size - g_bs_cv_max) {
|
|
cv := 15;
|
|
} else {
|
|
cv := max_size - i;
|
|
}
|
|
|
|
blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
|
|
tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
|
|
payload := f_rnd_octstring(i);
|
|
blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
|
|
more := false, e := true);
|
|
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
|
|
/* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
|
|
ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := cv,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := blocks);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data);
|
|
|
|
/* receive one message on BSSGP with all aggregated data in payload: */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
|
|
|
|
/* we will receive UL ACK/NACK from time to time, handle it. */
|
|
f_rx_rlcmac_dl_block(dl_block, dl_fn);
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
|
continue;
|
|
}
|
|
if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
|
|
not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
|
|
setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
log("Rx Packet Uplink ACK / NACK");
|
|
sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
|
|
var octetstring payload;
|
|
var template (value) RlcmacUlBlock ul_data;
|
|
var template (value) LlcBlockHdr blk_hdr;
|
|
var template (value) LlcBlocks blocks;
|
|
var integer block_len, max_valid_data_len;
|
|
timer T;
|
|
|
|
block_len := f_rlcmac_cs_mcs2block_len(cs);
|
|
/* We need to send with TLLI since we are in One-Phase Access Contenion
|
|
* resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
|
|
* indicator, -1 for spare bits octet at the end */
|
|
max_valid_data_len := block_len - 4 - 3 - 1 - 1;
|
|
payload := f_rnd_octstring(max_valid_data_len + 1); /* +1 to write LLC data on last padding octet */
|
|
blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
|
|
more := false, e := true);
|
|
blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := cv,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := blocks,
|
|
tlli := ms.tlli);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
|
|
|
|
T.start(0.5);
|
|
alt {
|
|
[] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
|
|
setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(pass);
|
|
}
|
|
}
|
|
}
|
|
/* Verify PCU finds out incorrectly formated RLC block and discards it. This
|
|
blocks intentionally contain last byte of data placed in last byte of RLC
|
|
containing padding/spare bits, which is incorrect. Spare bits exist and are
|
|
described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
|
|
discounting padding in octet" */
|
|
testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
|
|
var GprsMS ms;
|
|
var integer block_len, max_valid_data_len;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
|
|
f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
|
|
f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
|
|
* answered, so TBFs for uplink and later for downlink are created.
|
|
*/
|
|
private function f_TC_mo_ping_pong_1phase_access(template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
|
|
* answered, so TBFs for uplink and later for downlink are created.
|
|
*/
|
|
testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
|
|
var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
|
|
f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
|
|
}
|
|
|
|
/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
|
|
* answered, so TBFs for uplink and later for downlink are created.
|
|
*/
|
|
private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
|
|
template (value) MSRadioAccessCapabilityV ms_racap,
|
|
template (present) CodingScheme exp_ul_cs_mcs := ?,
|
|
template (present) CodingScheme exp_dl_cs_mcs := ?)
|
|
runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var uint32_t unused_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
|
|
|
|
if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
|
|
setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_cs_mcs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Send one UL block (without TLLI since we are in Second-Phase Access)
|
|
and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1);
|
|
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
/* Now SGSN sends some DL data, PCU will page on PACCH */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
/* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
|
|
f_sleep(0.5);
|
|
f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
/* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* PCU acks the UL data after having received CV=0) */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
|
|
|
|
/* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_dl_cs_mcs);
|
|
|
|
/* ACK the DL block */
|
|
f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs)),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
|
|
var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
|
|
var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
|
|
|
|
f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
|
|
}
|
|
|
|
testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
|
|
var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
|
|
var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
|
|
|
|
f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_default, ms_racap_egprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
|
|
}
|
|
|
|
testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
|
|
/* Configure PCU to force two phase access */
|
|
g_force_two_phase_access := true;
|
|
|
|
var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
|
|
var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
|
|
|
|
f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
|
|
}
|
|
|
|
/* Test scenario where SGSN wants to send some data against MS and it is
|
|
* answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
|
|
*/
|
|
private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
|
|
template (present) CodingScheme exp_cs_mcs := ?)
|
|
runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
|
|
|
|
/* ACK the DL block, and request UL TBF at the same time */
|
|
f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs), c_ChReqDesc_default),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
/* Expect UL ass */
|
|
f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
|
|
var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
|
|
f_TC_mt_ping_pong(omit, exp_cs_mcs);
|
|
}
|
|
|
|
/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
|
|
/* information about the MS */
|
|
testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
|
|
var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
|
|
f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
|
|
}
|
|
|
|
/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
|
|
* TBF, it will request retransmission through UL ACK/NACK (with missing block
|
|
* in its bitmap) when CV=0 is received (and hence it knows no more data is to
|
|
* be transferred).
|
|
*/
|
|
testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var template (value) RlcmacUlBlock ul_data;
|
|
var uint32_t sched_fn;
|
|
var octetstring total_payload;
|
|
var octetstring payload;
|
|
var octetstring lost_payload;
|
|
var uint5_t tfi;
|
|
var GprsMS ms;
|
|
var uint32_t payload_fill_len;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
tfi := ms.ul_tbf.tfi;
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine. */
|
|
payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true)); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
|
|
f_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
total_payload := payload;
|
|
|
|
payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
|
|
|
|
/* Send 2 packets, skip 1 (inc bsn) and send another one */
|
|
payload := f_rnd_octstring(payload_fill_len);
|
|
f_ms_tx_ul_data_block(ms, payload, cv := 15);
|
|
total_payload := total_payload & payload;
|
|
|
|
payload := f_rnd_octstring(payload_fill_len);
|
|
f_ms_tx_ul_data_block(ms, payload, cv := 15);
|
|
total_payload := total_payload & payload;
|
|
|
|
lost_payload := f_rnd_octstring(payload_fill_len);
|
|
ms.ul_tbf.bsn := ms.ul_tbf.bsn + 1; /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
|
|
total_payload := total_payload & lost_payload;
|
|
|
|
payload := f_rnd_octstring(payload_fill_len)
|
|
f_ms_tx_ul_data_block(ms, payload, cv := 15);
|
|
total_payload := total_payload & payload;
|
|
|
|
/* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
|
|
total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
|
|
|
|
/* On CV=0, we'll receive a UL ACK asking about missing block */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* TODO: check ack ack bitmap (URBB) */
|
|
ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
|
|
tfi := tfi,
|
|
cv := 15,
|
|
bsn := 3,
|
|
blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
|
|
f_ms_tx_ul_block(ms, ul_data);
|
|
|
|
/* Now final ack is recieved */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* receive one message on BSSGP with all aggregated data in payload: */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
|
|
* will retry by retransmitting both the IMM ASS + DL block after poll (ack)
|
|
* timeout occurs (specified by sent RRBP on DL block). */
|
|
testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
|
|
/* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
|
|
* or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
|
|
* should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
|
|
testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
|
|
var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
|
|
var octetstring data := f_rnd_octstring(16);
|
|
var PacketDlAssign dl_tbf_ass;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t ack_fn;
|
|
var uint32_t fn;
|
|
var GprsMS ms;
|
|
timer T := 5.0;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
f_statsd_reset();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS */
|
|
f_sleep(X2002);
|
|
|
|
/* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
|
|
|
|
/* TDMA frame number on which we are supposed to send the ACK */
|
|
ack_fn := f_dl_block_ack_fn(dl_block, fn);
|
|
|
|
/* SGSN sends more blocks during the indicated RRBP */
|
|
for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
|
|
data := f_rnd_octstring(16); /* Random LLC data */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
|
|
|
|
/* Make sure this block has the same TFI as was assigned
|
|
* FIXME: this is only valid for GPRS, not EGPRS. */
|
|
if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
|
|
setverdict(fail, "Rx DL data block with unexpected TFI: ",
|
|
dl_block.data.mac_hdr.hdr_ext.tfi);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Keep Ack/Nack description updated */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
|
|
|
|
/* Break if this is the end of RRBP */
|
|
if (fn == ack_fn) {
|
|
ms.dl_tbf.acknack_desc.final_ack := '1'B;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* This is the end of RRBP, send Packet Downlink Ack/Nack */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc), fn := fn);
|
|
|
|
/* Make sure that the next block (after the Ack) is dummy */
|
|
f_rx_rlcmac_dl_block_exp_dummy(dl_block);
|
|
|
|
var StatsDExpects expect := {
|
|
{ name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
|
|
{ name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
|
|
{ name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
|
|
{ name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
|
|
{ name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
|
|
};
|
|
f_statsd_expect(expect);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
|
|
* Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
|
|
* Check "3GPP TS 44.060" Annex B. */
|
|
testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring dataA := f_rnd_octstring(20);
|
|
var octetstring dataB := f_rnd_octstring(13);
|
|
var octetstring dataC := f_rnd_octstring(3);
|
|
var octetstring dataD := f_rnd_octstring(12);
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
var template (value) RlcmacUlBlock ul_data;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Summary of what's transmitted:
|
|
* 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
|
|
* 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
|
|
* 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
|
|
* 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
|
|
* And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
|
|
* We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
|
|
*/
|
|
|
|
/* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := 3,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
|
|
tlli := ms.tlli);
|
|
/* Indicate no llc header, meaning first LLC block doesn't finish in current
|
|
* RLCMAC block being sent. */
|
|
ul_data.data.mac_hdr.e := true;
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
|
|
|
|
/* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := 2,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
|
|
t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
|
|
t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
|
|
},
|
|
tlli := ms.tlli);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data);
|
|
|
|
/* UL block dataA should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataA));
|
|
|
|
/* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := 1,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
|
|
t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
|
|
t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
|
|
t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
|
|
t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
|
|
},
|
|
tlli := ms.tlli);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data);
|
|
|
|
/* UL block dataB and dataC should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataC));
|
|
|
|
/* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
|
|
ul_data := t_RLCMAC_UL_DATA_TLLI(
|
|
cs := CS_1,
|
|
tfi := ms.ul_tbf.tfi,
|
|
cv := 0,
|
|
bsn := ms.ul_tbf.bsn,
|
|
blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
|
|
t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
|
|
},
|
|
tlli := ms.tlli);
|
|
f_ultbf_inc_bsn(ms.ul_tbf);
|
|
f_ms_tx_ul_block(ms, ul_data);
|
|
|
|
/* UL block dataB and dataD should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataD));
|
|
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
|
|
* ACK/NACK is not answered */
|
|
testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data1 := f_rnd_octstring(200);
|
|
var octetstring data2 := f_rnd_octstring(10);
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
var template (value) TsTrxBtsNum nr;
|
|
var BTS_PDTCH_Block data_msg;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename())
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
|
|
/* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
|
|
while (true) {
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
|
|
|
|
/* Keep Ack/Nack description updated (except for last BSN) */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
|
|
|
|
if (f_dl_block_rrbp_valid(dl_block)) {
|
|
/* Don't transmit DL ACK here on purpose ignore it */
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* PCU starts whole process again */
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
|
|
/* Recv DL data until receiving RRBP to DL ACK (because it's last queued
|
|
/* DL data), after that we receive only DUMMY blocks so we are done */
|
|
var boolean data_received := false;
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
alt {
|
|
[data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DUMMY_CTRL)) { /* done */ }
|
|
[] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
|
|
tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
|
|
tr_RLCMAC_DATA)) -> value data_msg {
|
|
data_received := true;
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
|
|
if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
|
|
log("Received FINAL_ACK");
|
|
ms.dl_tbf.acknack_desc.final_ack := '1'B;
|
|
}
|
|
if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
|
|
}
|
|
nr := ts_TsTrxBtsNum;
|
|
BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
|
|
sapi := PCU_IF_SAPI_PDTCH, fn := 0,
|
|
arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
|
|
block_nr := nr.blk_nr));
|
|
repeat;
|
|
}
|
|
[] BTS.receive {
|
|
setverdict(fail, "Unexpected BTS message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
|
|
testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var PacketDlAssign dl_tbf_ass;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t poll_fn;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
timer T := 5.0;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Only 1 TRX with 8 PDCH */
|
|
f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF, this way the PCU can send DL Assignment
|
|
through PDCH (no multiblock assignment possible through PCH) */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
|
|
nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
|
|
var MultislotCap_GPRS_BSSGP mscap_gprs := {
|
|
gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
|
|
gprsextendeddynalloccap := '0'B
|
|
};
|
|
var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
|
|
dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
|
|
setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
|
|
var MultislotCap_GPRS mscap_gprs := {
|
|
gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
|
|
gprsextendeddynalloccap := '0'B
|
|
};
|
|
var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
|
|
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Only 1 TRX with 8 PDCH */
|
|
f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
|
|
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
|
|
setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
|
|
var MultislotCap_GPRS mscap_gprs := {
|
|
gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
|
|
gprsextendeddynalloccap := '0'B
|
|
};
|
|
var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
|
|
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Only 1 TRX with 8 PDCH */
|
|
f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
|
|
|
|
if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
|
|
setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test scenario where MS wants to request a new TBF once the current one is
|
|
* ending, by means of sending a Packet Resource Request on ul slot provided by
|
|
* last Pkt Ul ACK's RRBP.
|
|
* See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
|
|
testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var template RlcmacDlBlock acknack_tmpl;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send one UL block (with TLLI since we are in One-Phase Access
|
|
contention resoultion) and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
|
|
tr_UlAckNackGprs(ms.tlli,
|
|
tr_AckNackDescription(final_ack := '1'B),
|
|
tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
|
|
|
|
/* TODO: verify TBF_EST and FinalACK are both '1' above */
|
|
|
|
/* Send PACKET RESOURCE REQUEST to request a new UL TBF */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
|
|
f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* Send one UL block (without TLLI since we are in Second-Phase Access)
|
|
and make sure it is ACKED fine */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
|
|
/* ACK the ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test CS paging over the BTS<->PCU socket.
|
|
* When a (class B or C, not A) MS has an active TBF (or is on the PDCH), the MS can not react on CS paging over CCCH.
|
|
* Paging should be send on the PACCH.
|
|
*
|
|
* 1. Send a Paging Request over PCU socket.
|
|
* 2. Send a Ready-To-Send message over PCU socket
|
|
* 3. Expect a Paging Frame
|
|
*/
|
|
testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var MobileIdentityLV mi;
|
|
var octetstring mi_enc_lv;
|
|
var hexstring imsi := f_gen_imsi(42);
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* build mobile Identity */
|
|
mi := valueof(ts_MI_IMSI_LV(imsi));
|
|
mi_enc_lv := enc_MobileIdentityLV(mi);
|
|
/* Send paging request */
|
|
BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
|
|
sapi :=PCU_IF_SAPI_PDTCH));
|
|
|
|
/* Receive it on BTS side towards MS */
|
|
f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
|
|
|
|
/* Make sure that Packet Paging Request contains the same IMSI */
|
|
var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
|
|
if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
|
|
setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
|
|
*/
|
|
private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
|
|
runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var hexstring imsi := f_gen_imsi(42);
|
|
var GsmTmsi tmsi;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send paging request with or without TMSI */
|
|
if (use_ptmsi) {
|
|
tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
|
|
} else {
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
|
|
}
|
|
|
|
/* Receive it on BTS side towards MS */
|
|
f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
|
|
|
|
/* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
|
|
var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
|
|
if (use_ptmsi) {
|
|
if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
|
|
setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
|
|
}
|
|
} else {
|
|
if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
|
|
setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_cs_from_sgsn(0, true);
|
|
}
|
|
|
|
testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_cs_from_sgsn(0);
|
|
}
|
|
|
|
testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
|
|
}
|
|
|
|
/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
|
|
*/
|
|
private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
|
|
runs on RAW_PCU_Test_CT {
|
|
var integer imsi_suff_tx := 423;
|
|
var hexstring imsi := f_gen_imsi(imsi_suff_tx);
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
|
|
* Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
|
|
if (use_ptmsi) {
|
|
var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
|
|
BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
|
|
f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
|
|
} else {
|
|
BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
|
|
f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_ps_from_sgsn(0, true);
|
|
}
|
|
|
|
testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_ps_from_sgsn(0);
|
|
}
|
|
|
|
testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
|
|
f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
|
|
}
|
|
|
|
/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
|
|
testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
f_statsd_reset();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
/* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
|
|
f_sleep(X2002);
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
|
|
/* ACK the DL block */
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
var StatsDExpects expect := {
|
|
{ name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
|
|
{ name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
|
|
{ name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
|
|
};
|
|
f_statsd_expect(expect);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
|
|
testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var uint32_t sched_fn;
|
|
var uint32_t dl_fn;
|
|
var GprsMS ms;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
|
|
f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
|
|
/* UL block should be received in SGSN */
|
|
BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
/* Now SGSN sends some DL data with an invalid IMSI */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
|
|
|
|
BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
|
|
|
|
/* TODO: make sure no data is sent over PCU -> MS */
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
|
|
var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
|
|
var octetstring data := f_rnd_octstring(6);
|
|
var RlcmacDlBlock dl_block;
|
|
var GprsMS ms;
|
|
var uint32_t fn;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
/* Wait timer X2002 and DL block is available after CCCH IMM ASS */
|
|
f_sleep(X2002);
|
|
|
|
/* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
|
|
|
|
if (ischosen(dl_block.data_egprs)) {
|
|
if (lengthof(dl_block.data_egprs.blocks) != 2) {
|
|
setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
|
|
setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
if (not match(dl_block.data_egprs.blocks[1].payload,
|
|
f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
|
|
setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
} else if (lengthof(dl_block.data.blocks) > 1) {
|
|
setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
|
|
* containing llc data. See OS#4849 */
|
|
testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
|
|
f_tc_dl_data_no_llc_ui_dummy(omit);
|
|
}
|
|
|
|
/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
|
|
* containing llc data. See OS#4849 */
|
|
testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
|
|
f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
|
|
}
|
|
|
|
private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
|
|
template GsmRrMessage t_imm_ass := ?,
|
|
PCUIF_BurstType bt := BURST_TYPE_1)
|
|
runs on RAW_PCU_Test_CT {
|
|
var GsmRrMessage rr_msg;
|
|
var uint16_t ra11;
|
|
|
|
ra11 := enc_EGPRSPktChRequest2uint(req);
|
|
log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
|
|
|
|
rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
|
|
if (not match(rr_msg, t_imm_ass)) {
|
|
setverdict(fail, "Immediate Assignment does not match");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
setverdict(pass);
|
|
}
|
|
|
|
testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
|
|
var template GsmRrMessage imm_ass;
|
|
var template IaRestOctets rest;
|
|
var template EgprsUlAss ul_ass;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
var EGPRSPktChRequest req := {
|
|
/* NOTE: other fields are set in the loop */
|
|
signalling := { tag := '110011'B }
|
|
};
|
|
|
|
for (var integer i := 0; i < 6; i := i + 1) {
|
|
var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
|
|
req.signalling.random_bits := ext_ra;
|
|
|
|
/* For signalling, do we expect Multiblock UL TBF Assignment? */
|
|
ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
|
|
rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
|
|
imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
|
|
|
|
f_TC_egprs_pkt_chan_req(req, imm_ass);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
|
|
var template GsmRrMessage imm_ass;
|
|
var template IaRestOctets rest;
|
|
var template EgprsUlAss ul_ass;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
var EGPRSPktChRequest req := {
|
|
/* NOTE: other fields are set in the loop */
|
|
one_phase := { tag := '0'B }
|
|
};
|
|
|
|
for (var integer i := 0; i < 6; i := i + 1) {
|
|
var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
|
|
var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
|
|
var BIT2 priority := substr(ext_ra, 0, 2);
|
|
var BIT3 rand := substr(ext_ra, 2, 3);
|
|
|
|
req.one_phase.multislot_class := mslot_class;
|
|
req.one_phase.priority := priority;
|
|
req.one_phase.random_bits := rand;
|
|
|
|
/* For one phase access, do we expect Dynamic UL TBF Assignment? */
|
|
ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
|
|
rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
|
|
imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
|
|
|
|
f_TC_egprs_pkt_chan_req(req, imm_ass);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
|
|
var template GsmRrMessage imm_ass;
|
|
var template IaRestOctets rest;
|
|
var template EgprsUlAss ul_ass;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
var EGPRSPktChRequest req := {
|
|
/* NOTE: other fields are set in the loop */
|
|
two_phase := { tag := '110000'B }
|
|
};
|
|
|
|
for (var integer i := 0; i < 6; i := i + 1) {
|
|
var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
|
|
var BIT2 priority := substr(ext_ra, 0, 2);
|
|
var BIT3 rand := substr(ext_ra, 2, 3);
|
|
|
|
req.two_phase.priority := priority;
|
|
req.two_phase.random_bits := rand;
|
|
|
|
/* For two phase access, do we expect Multiblock UL TBF Assignment? */
|
|
ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
|
|
rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
|
|
imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
|
|
|
|
f_TC_egprs_pkt_chan_req(req, imm_ass);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
|
|
template IARRestOctets rest := ?,
|
|
PCUIF_BurstType bt := BURST_TYPE_1,
|
|
template WaitIndication wi := ?)
|
|
runs on RAW_PCU_Test_CT {
|
|
var template ReqRefWaitInd tr_ref;
|
|
var GsmRrMessage rr_msg;
|
|
|
|
/* Send RACH.ind with malformed EGPRS Packet Channel Request */
|
|
BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
|
|
ra := bit2int(ra11), is_11bit := 1,
|
|
burst_type := bt, fn := fn,
|
|
arfcn := 871));
|
|
|
|
/* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
|
|
rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
|
|
|
|
/* Just to have a short-name reference to the actual message */
|
|
var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
|
|
|
|
/* Make sure that Request Reference list contains at least one entry
|
|
* with our TDMA frame number, and RA is set to 'reserved' value 127. */
|
|
tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
|
|
if (not match(iar.payload, { *, tr_ref, * })) {
|
|
setverdict(fail, "Request Reference list does not match");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Match Feature Indicator (must indicate PS domain) */
|
|
if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
|
|
setverdict(fail, "Feature Indicator does not match");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* Match IAR Rest Octets */
|
|
if (not match(iar.rest_octets, rest)) {
|
|
setverdict(fail, "IAR Rest Octets does not match: ",
|
|
iar.rest_octets, " vs expected ", rest);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
setverdict(pass);
|
|
}
|
|
|
|
/* Verify the contents of RR Immediate Assignment Reject message and its
|
|
* Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
|
|
testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
|
|
var template IARRestOctets rest;
|
|
var BIT5 ext_ra;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
for (var integer i := 0; i < 6; i := i + 1) {
|
|
ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
|
|
rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
|
|
|
|
/* Intentionally incorrect message (see table 11.2.5a.2) */
|
|
f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* At the moment, the IUT does not support any emergency services. Make sure
|
|
* that EGPRS Packet Channel Request for an emergency call is properly rejected. */
|
|
testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
|
|
var template IARRestOctets rest;
|
|
var BIT5 ext_ra;
|
|
var BIT11 ra11;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
var EGPRSPktChRequest req := {
|
|
/* NOTE: other fields are set in the loop */
|
|
emergency := { tag := '110111'B }
|
|
};
|
|
|
|
for (var integer i := 0; i < 6; i := i + 1) {
|
|
ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
|
|
rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
|
|
|
|
req.emergency.random_bits := ext_ra;
|
|
ra11 := enc_EGPRSPktChRequest2bits(req);
|
|
|
|
/* Intentionally incorrect message (see table 11.2.5a.2) */
|
|
f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
|
|
testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var template IARRestOctets rest;
|
|
var BIT11 ra11;
|
|
|
|
info_ind := valueof(ts_PCUIF_INFO_default);
|
|
info_ind.t3142 := 3;
|
|
|
|
/* Only the first TRX is enabled. */
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
var EGPRSPktChRequest req := {
|
|
one_phase := {
|
|
tag := '0'B,
|
|
multislot_class := '10101'B,
|
|
priority := '01'B,
|
|
random_bits := '101'B
|
|
}
|
|
};
|
|
|
|
/* We send 7 requests, the IUT gives us all available USFs (0..6).
|
|
* TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
|
|
for (var integer i := 0; i < 7; i := i + 1) {
|
|
req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
|
|
f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
|
|
}
|
|
|
|
ra11 := enc_EGPRSPktChRequest2bits(req);
|
|
rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
|
|
|
|
/* At this point, the IUT should run out of free USFs */
|
|
f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Randomly generate a set of hopping parameters for one timeslot */
|
|
private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
|
|
return template (value) PCUIF_InfoTrxTs {
|
|
/* Pick a random MA length in range 2 .. max_ma_len */
|
|
var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
|
|
|
|
return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
|
|
hsn := f_rnd_int(63),
|
|
maio := f_rnd_int(63),
|
|
ma := f_rnd_bitstring(ma_len));
|
|
}
|
|
|
|
private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
|
|
in GsmRrMessage rr_msg)
|
|
{
|
|
var ImmediateAssignment ia := rr_msg.payload.imm_ass;
|
|
var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
|
|
|
|
var template PacketChannelDescription tr_pkt_chan_desc := {
|
|
channel_Type_spare := ?,
|
|
tn := ?,
|
|
tsc := ts.tsc,
|
|
presence := '1'B,
|
|
zero := omit,
|
|
one := {
|
|
maio := ts.maio,
|
|
hsn := ts.hsn
|
|
}
|
|
};
|
|
|
|
if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
|
|
setverdict(fail, "Packet Channel Description does not match: ",
|
|
ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
|
|
}
|
|
|
|
/* Mobile Allocation is expected to be octet-aligned */
|
|
var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
|
|
var template MobileAllocationLV tr_ma := {
|
|
len := ma_oct_len, /* in bytes */
|
|
ma := substr(ts.ma, 0, ma_oct_len * 8)
|
|
};
|
|
|
|
if (not match(ia.mobile_allocation, tr_ma)) {
|
|
setverdict(fail, "Mobile Allocation does not match: ",
|
|
ia.mobile_allocation, " vs ", tr_ma);
|
|
}
|
|
|
|
setverdict(pass);
|
|
}
|
|
|
|
/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
|
|
testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
|
|
/* Enable frequency hopping on TRX0/TS7 */
|
|
info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* EGPRS Packet Channel Request (cause=Signalling) */
|
|
f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
|
|
|
|
/* Establish an Uplink EGPRS TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
|
|
testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
|
|
/* Enable frequency hopping on TRX0/TS7 */
|
|
info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
|
|
testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
|
|
/* Enable frequency hopping on TRX0/TS7 */
|
|
info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* SGSN sends some DL data, PCU will page on CCCH (PCH) */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
|
|
f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
|
|
|
|
f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
|
|
in FrequencyParameters fp)
|
|
{
|
|
/* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
|
|
var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
|
|
|
|
/* Table 12.8.1: Frequency Parameters information elements */
|
|
var template FrequencyParameters tr_fp := {
|
|
tsc := ts.tsc,
|
|
presence := '10'B, /* Direct encoding 1 */
|
|
arfcn := omit,
|
|
indirect := omit,
|
|
direct1 := {
|
|
maio := ts.maio,
|
|
/* Table 12.10a.1: GPRS Mobile Allocation information elements */
|
|
mobile_allocation := {
|
|
hsn := ts.hsn,
|
|
rfl_number_list_present := '0'B,
|
|
rfl_number_list := omit,
|
|
ma_present := '0'B, /* inverted logic */
|
|
ma_length := ts.ma_bit_len,
|
|
ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
|
|
}
|
|
},
|
|
direct2 := omit
|
|
};
|
|
|
|
if (not match(fp, tr_fp)) {
|
|
setverdict(fail, "Frequency Parameters IE does not match: ",
|
|
fp, " vs ", tr_fp);
|
|
}
|
|
|
|
setverdict(pass);
|
|
}
|
|
|
|
/* Make sure that Packet Uplink Assignment contains hopping parameters */
|
|
testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
var uint32_t poll_fn;
|
|
|
|
/* Enable frequency hopping on TRX0/TS7 */
|
|
info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Single block (two phase) packet access */
|
|
var uint16_t ra := bit2int(chan_req_sb);
|
|
f_ms_use_ra(ms, ra, ra_is_11bit := 0);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send Packet Resource Request, so the network will allocate an Uplink resource */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
|
|
fn := ms.ul_tbf.start_time_fn);
|
|
|
|
/* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
|
|
f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
|
|
var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
|
|
|
|
/* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
|
|
var template (omit) FrequencyParameters fp;
|
|
if (ua.is_egprs == '1'B) {
|
|
fp := ua.egprs.freq_par;
|
|
} else {
|
|
fp := ua.gprs.freq_par;
|
|
}
|
|
|
|
/* This is an optional IE, so it's worth to check its presence */
|
|
if (istemplatekind(fp, "omit")) {
|
|
setverdict(fail, "Frequency Parameters IE is not present");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Make sure that Packet Downlink Assignment contains hopping parameters */
|
|
testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var GprsMS ms := valueof(t_GprsMS_def);
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t poll_fn;
|
|
|
|
/* Enable frequency hopping on TRX0/TS7 */
|
|
info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Establish an Uplink TBF */
|
|
f_ms_establish_ul_tbf(ms);
|
|
|
|
/* Send an Uplink block, so this TBF becomes "active" */
|
|
f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
|
|
|
|
/* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
|
|
|
|
/* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
|
|
/* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
|
|
f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
|
|
|
|
/* This is an optional IE, so it's worth to check its presence */
|
|
if (not ispresent(da.freq_par)) {
|
|
setverdict(fail, "Frequency Parameters IE is not present");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Check if the IUT handles subsequent INFO.ind messages */
|
|
testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
|
|
var BTS_PDTCH_Block data_msg;
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
|
|
for (var integer i := 0; i < 16; i := i + 1) {
|
|
BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
|
|
f_pcuif_rx_data_req_pdtch(data_msg);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
|
|
testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
var integer i;
|
|
const integer num_ms := 8;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms(num_ms);
|
|
|
|
info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
|
|
/* Only the 3 first TRX are enabled. The enabled ones all have same
|
|
amount of resources, hence same amount of initial resources. */
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
|
|
f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_multi_ms_bssgp_register();
|
|
|
|
/* Establish an Uplink TBF for each GprsMS instance */
|
|
f_multi_ms_establish_tbf(do_activate := false);
|
|
|
|
/* Check if all TBFs are allocated on different TRX in an uniform way */
|
|
for (i := 0; i < num_ms; i := i + 1) {
|
|
if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
|
|
setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
|
|
" vs exp ", info_ind.trx[i mod 3].arfcn);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
|
|
* downgraded to CS1-4 so that GPRS can read the USF).
|
|
* See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
|
|
*/
|
|
testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind;
|
|
const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn, dl_fn, ack_fn;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
var RlcmacDlBlock dl_block;
|
|
var integer tx_data_remain := 5;
|
|
var integer tgt_ms, usf_ms;
|
|
var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
|
|
var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms(num_ms);
|
|
|
|
info_ind := valueof(ts_PCUIF_INFO_default);
|
|
/* Only use 1 PDCH to make sure both end up in the same slot: */
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
|
|
f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Set Initial MCS > 4 and maintain it non-variable to simplify test */
|
|
g_mcs_initial_dl := 5;
|
|
g_mcs_max_dl := 5;
|
|
f_pcuvty_set_allowed_cs_mcs();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_multi_ms_bssgp_register();
|
|
|
|
/* Establish UL TBF for MS0 (GPRS-only) */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[0], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[0].tlli, ms_racap_gprs_def));
|
|
if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
|
|
setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Establish UL TBF for MS1 (EGPRS) */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[1], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[1].tlli, ms_racap_egprs_def));
|
|
if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
|
|
setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
|
|
f_sleep(0.1);
|
|
f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
/* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
|
|
/* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
|
|
/* ACK the DL block */
|
|
f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
|
|
f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
/* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
|
|
f_sleep(0.1);
|
|
f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
/* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
|
|
/* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
|
|
/* ACK the DL block */
|
|
f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
|
|
f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
|
|
data := f_rnd_octstring(1400);
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
|
|
|
|
for (var integer i := 0; i < 800; i := i + 1) {
|
|
f_rx_rlcmac_dl_block(dl_block, dl_fn);
|
|
|
|
if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
|
|
/* No more data to receive, done */
|
|
break;
|
|
}
|
|
|
|
usf_ms := -1;
|
|
|
|
if (ischosen(dl_block.ctrl)) {
|
|
setverdict(fail, "Unexpected DL CTRL block ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
} else if (ischosen(dl_block.data_egprs)) {
|
|
if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
|
|
setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
tgt_ms := 1;
|
|
if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
|
|
if (dl_block.data_egprs.mcs > MCS_4) {
|
|
setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
usf_ms := 0;
|
|
ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
|
|
} else {
|
|
if (dl_block.data_egprs.mcs <= MCS_4) {
|
|
setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
|
|
usf_ms := 1;
|
|
ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
|
|
}
|
|
}
|
|
} else {
|
|
if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
|
|
setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
tgt_ms := 0;
|
|
if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
|
|
usf_ms := 0;
|
|
ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
|
|
} else if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
|
|
usf_ms := 1;
|
|
ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
|
|
}
|
|
}
|
|
|
|
/* Keep Ack/Nack description updated */
|
|
f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
|
|
|
|
/* TDMA frame number on which we are supposed to send the ACK */
|
|
if (f_dl_block_rrbp_valid(dl_block)) {
|
|
ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
|
|
f_ms_tx_ul_block(g_ms[tgt_ms], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[tgt_ms].dl_tbf, ischosen(dl_block.data_egprs)), ack_fn);
|
|
if (tx_data_remain != 0) {
|
|
/* Submit more data from time to time to keep the TBF ongoing */
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
|
|
tx_data_remain := tx_data_remain - 1;
|
|
}
|
|
} else if (tx_data_remain != 0) {
|
|
/* keep sending UL blocks when requested by USF to avoid
|
|
* UL TBF timeout and hence stop receival of USFs */
|
|
if (usf_ms != -1) {
|
|
f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
|
|
}
|
|
}
|
|
}
|
|
|
|
log("results: ms_gprs_usf_count=", ms_gprs_usf_count, " / ms_egprs_usf_count=", ms_egprs_usf_count);
|
|
/* He we check that DL blocks scheduled at GPRS can still request UL
|
|
* blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
|
|
* condition also ensures the downgrade to <=MCS4 condition is tested
|
|
* above */
|
|
if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
|
|
setverdict(fail, "USF exchange thresholds not met!");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* Here check for some level of fairness between them (at least ~40%): */
|
|
var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
|
|
var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
|
|
var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
|
|
if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
|
|
setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
|
|
setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
|
|
private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
|
|
boolean exp_imsi, boolean exp_tmsi)
|
|
runs on RAW_PCU_Test_CT {
|
|
var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
|
|
var integer pending := lengthof(g_ms);
|
|
var RlcmacDlBlock dl_block;
|
|
var boolean f1, f2;
|
|
|
|
while (pending > 0) {
|
|
var uint32_t poll_fn;
|
|
|
|
/* Obtain a Downlink block and make sure it is a paging request */
|
|
f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
|
|
if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
break;
|
|
}
|
|
|
|
/* This should not happen in general, but who knows... */
|
|
var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
|
|
if (not ispresent(req.repeated_pageinfo)) {
|
|
setverdict(fail, "Repeated Page Info IE is absent?!?");
|
|
break;
|
|
}
|
|
|
|
/* A single message may contain several MIs depending on their type */
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
|
|
ps_domain := false);
|
|
f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
|
|
ps_domain := false);
|
|
if (not f1 and not f2)
|
|
{ continue; }
|
|
|
|
/* Detect duplicate MIs */
|
|
if (mask[i] == '1'B) {
|
|
setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
|
|
continue;
|
|
}
|
|
|
|
mask[i] := '1'B;
|
|
}
|
|
|
|
pending := pending - lengthof(req.repeated_pageinfo);
|
|
}
|
|
|
|
for (var integer i := 0; i < lengthof(mask); i := i + 1) {
|
|
if (mask[i] != '1'B) {
|
|
setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
|
|
log("===== mask := ", mask);
|
|
}
|
|
}
|
|
|
|
/* All messages must have been received by now, expect a dummy block */
|
|
f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
|
|
}
|
|
|
|
private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
|
|
runs on RAW_PCU_Test_CT {
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Explicitly set the given PDCH slot-mask to all transceivers */
|
|
f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
|
|
|
|
/* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
|
|
f_init_gprs_ms(7 * 8);
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_multi_ms_bssgp_register();
|
|
|
|
/* Establish an Uplink TBF for each GprsMS instance */
|
|
f_multi_ms_establish_tbf(do_activate := true);
|
|
}
|
|
|
|
testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
|
|
const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
|
|
|
|
/* Common part: send INFO.ind, establish TBFs... */
|
|
f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
|
|
|
|
/* Enqueue multiple CS PAGING requests at a time (IMSI only) */
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
|
|
}
|
|
|
|
/* FIXME: work around a race condition between PCUIF and BSSGP */
|
|
f_sleep(0.2); /* i.e. give the IUT some time to process everything */
|
|
|
|
/* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
|
|
* The IUT is expected to page on all PDCH slots of all transceivers. */
|
|
for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
|
|
var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
|
|
f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
|
|
const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
|
|
|
|
/* Common part: send INFO.ind, establish TBFs... */
|
|
f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
|
|
|
|
/* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
|
|
}
|
|
|
|
/* FIXME: work around a race condition between PCUIF and BSSGP */
|
|
f_sleep(0.2); /* i.e. give the IUT some time to process everything */
|
|
|
|
/* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
|
|
* The IUT is expected to page on all PDCH slots of all transceivers. */
|
|
for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
|
|
var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
|
|
f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
|
|
const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
|
|
|
|
/* Common part: send INFO.ind, establish TBFs... */
|
|
f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
|
|
|
|
/* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
|
|
for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
|
|
var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
|
|
if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
|
|
} else {
|
|
BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
|
|
}
|
|
}
|
|
|
|
/* FIXME: work around a race condition between PCUIF and BSSGP */
|
|
f_sleep(0.2); /* i.e. give the IUT some time to process everything */
|
|
|
|
/* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
|
|
* The IUT is expected to page on all PDCH slots of all transceivers. */
|
|
for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
|
|
var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
|
|
f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
|
|
runs on RAW_PCU_Test_CT return RlcmacDlBlock {
|
|
var RlcmacDlBlock dl_block;
|
|
var integer i := 0;
|
|
while (true) {
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
|
|
break;
|
|
}
|
|
if (max_num_iter > 0 and i > max_num_iter) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
i := i + 1;
|
|
}
|
|
return dl_block;
|
|
}
|
|
|
|
private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
|
|
runs on RAW_PCU_Test_CT {
|
|
var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1),
|
|
info_ind.lac),
|
|
info_ind.rac),
|
|
info_ind.cell_id));
|
|
var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
|
|
423),
|
|
2),
|
|
5));
|
|
var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
|
|
var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
|
|
var template (value) RAN_Information_RIM_Container res_cont :=
|
|
ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
|
|
ts_RIM_Sequence_Number(2),
|
|
ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
|
|
ts_RIM_Protocol_Version_Number(1),
|
|
tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
|
|
omit);
|
|
RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
|
|
res_cont));
|
|
}
|
|
|
|
altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
|
|
runs on RAW_PCU_Test_CT {
|
|
/* RIM procedure: */
|
|
var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1),
|
|
info_ind.lac),
|
|
info_ind.rac),
|
|
info_ind.cell_id));
|
|
var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
|
|
423),
|
|
2),
|
|
5));
|
|
var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
|
|
var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
|
|
[] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
|
|
tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
tr_RAN_Information_Request_RIM_Container)) {
|
|
if (do_answer) {
|
|
f_outbound_nacc_rim_tx_resp(info_ind);
|
|
}
|
|
if (do_repeat) {
|
|
repeat;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Start NACC from MS side */
|
|
private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
|
|
boolean exp_rac_ci_query := true, boolean exp_si_query := true,
|
|
boolean skip_final_ctrl_ack := false)
|
|
runs on RAW_PCU_Test_CT {
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
if (exp_rac_ci_query == true) {
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
}
|
|
|
|
if (exp_si_query == true) {
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
}
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
|
|
testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
f_outbound_nacc_success(ms, info_ind);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
|
|
testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side, avoid sending final CTRL ACK */
|
|
f_outbound_nacc_success(ms, info_ind, skip_final_ctrl_ack := true);
|
|
|
|
/* Wait until we receive something non-dummy */
|
|
dl_block := f_skip_dummy(0, sched_fn);
|
|
/* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
|
|
testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
/* Set timeout values for caches so that entries will be in cache during second try */
|
|
f_pcuvty_set_neigh_caches(10, 10);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
f_outbound_nacc_success(ms, info_ind);
|
|
|
|
/* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
|
|
f_outbound_nacc_success(ms, info_ind, false, false);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
|
|
* TS 44.060 sec 8.8) twice, the second time after caches timed out
|
|
*/
|
|
testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
/* Set timeout values for caches so that entries will be erased before the second try */
|
|
f_pcuvty_set_neigh_caches(1, 1);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
f_outbound_nacc_success(ms, info_ind);
|
|
|
|
/* CTRL client should have disconnected from us */
|
|
f_ipa_ctrl_wait_link_down();
|
|
/* wait for cache entries to time out */
|
|
f_sleep(2.0);
|
|
/* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
|
|
f_outbound_nacc_success(ms, info_ind);
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
|
|
testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* In here we explicitly avoid starting osmo-bsc emulation neighbor
|
|
* resolution CTRL port, to trigger Conn Refused by socket:
|
|
* f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
*/
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* Wait until we receive something non-dummy */
|
|
dl_block := f_skip_dummy(0, sched_fn);
|
|
/* Make sure it is a Pkt Cell Chg Continue */
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
|
|
testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
/* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
|
|
|
|
/* Wait until we receive something non-dummy */
|
|
dl_block := f_skip_dummy(0, sched_fn);
|
|
/* Make sure it is a Pkt Cell Chg Continue */
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
|
|
testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
/* we receive RAC+CI resolution request and we send incorrectlt formated response */
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
|
|
|
|
/* Wait until we receive something non-dummy */
|
|
dl_block := f_skip_dummy(0, sched_fn);
|
|
/* Make sure it is a Pkt Cell Chg Continue */
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
|
|
testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
|
|
var RlcmacDlBlock dl_block;
|
|
var PollFnCtx pollctx;
|
|
var uint32_t sched_fn;
|
|
var GprsMS ms;
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1), /* '262F42'H */
|
|
info_ind.lac),
|
|
info_ind.rac),
|
|
info_ind.cell_id));
|
|
var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
|
|
423),
|
|
2),
|
|
5));
|
|
var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
|
|
var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
|
|
/* RIM procedure: */
|
|
RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
|
|
tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
tr_RAN_Information_Request_RIM_Container));
|
|
/* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
|
|
|
|
/* Wait until we receive something non-dummy */
|
|
dl_block := f_skip_dummy(0, sched_fn);
|
|
/* Make sure it is a Pkt Cell Chg Continue */
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
|
|
/* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
|
|
IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
|
|
timer T := 2.0;
|
|
T.start;
|
|
alt {
|
|
[] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
|
|
[] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
|
|
setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(pass);
|
|
}
|
|
}
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
|
|
/* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
|
|
f_outbound_nacc_rim_tx_resp(info_ind);
|
|
timer T := 1.0;
|
|
T.start;
|
|
alt {
|
|
[] RIM.receive {
|
|
setverdict(fail, "Received unexpected RIM message");
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
[] T.timeout {
|
|
setverdict(pass);
|
|
}
|
|
}
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* It should be ignored, let's continue fetching Pkt Neigh Data Change */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* trigger a dup Pkt Cell Change Notif, it should be ignored: */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* trigger a dup Pkt Cell Change Notif, it should be ignored: */
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
|
|
* while waiting for CTRL resolution */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
|
|
/* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
|
|
IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
|
|
/* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
|
|
ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn + 1) & "." &
|
|
int2str(req_bsic + 1);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
|
|
/* And finally everything continues as usual with RIN procedure */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
|
|
* while waiting for SI resolution */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
|
|
/* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
|
|
f_outbound_nacc_rim_tx_resp(info_ind);
|
|
|
|
/* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
|
|
ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn + 1) & "." &
|
|
int2str(req_bsic + 1);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
|
|
/* And finally everything continues as usual with RIN procedure */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
|
|
* while sending Pkt Neigh Data Change */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* It should trigger RAC_CI resolution to start again: */
|
|
ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn + 1) & "." &
|
|
int2str(req_bsic + 1);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
/* Transmit SI back to MS */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* trigger a Pkt Cell Change Notif with different tgt cell */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* PCU TBF NACC state changed, so we should next receive a dummy block: */
|
|
f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* It should trigger RAC_CI resolution to start again: */
|
|
ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn + 1) & "." &
|
|
int2str(req_bsic + 1);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
/* Transmit SI back to MS */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
/* Announce SI back to MS, continue NACC procedure */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
|
|
/* trigger a Pkt Cell Change Notif with different tgt cell */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
/* PCU TBF NACC state changed, so we should next receive a dummy block: */
|
|
f_rx_rlcmac_dl_block_exp_dummy(dl_block);
|
|
|
|
/* It should trigger RAC_CI resolution to start again: */
|
|
ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn + 1) & "." &
|
|
int2str(req_bsic + 1);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
/* Transmit SI back to MS */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
}
|
|
|
|
/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
|
|
testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
|
|
var PollFnCtx pollctx;
|
|
var GprsMS ms;
|
|
var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
|
|
var template (value) RlcmacUlCtrlMsg cell_chf_notif;
|
|
var RlcmacDlBlock dl_block;
|
|
var uint32_t sched_fn, dl_fn;
|
|
var CtrlMessage rx_ctrl;
|
|
var GsmArfcn req_arfcn := 862;
|
|
var uint6_t req_bsic := 43;
|
|
var octetstring data := f_rnd_octstring(10);
|
|
|
|
/* Initialize osmo-bsc emulation neighbor resolution CTRL port */
|
|
f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
/* Initialize GPRS MS side */
|
|
f_init_gprs_ms();
|
|
ms := g_ms[0]; /* We only use first MS in this test */
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Make sure we are not affected by full cache from previous tests */
|
|
f_pcuvty_flush_neigh_caches();
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
|
|
|
|
/* Send PACKET RESOURCE REQUEST */
|
|
pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
|
|
/* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
|
|
|
|
/* Start NACC from MS side */
|
|
cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
|
|
f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
|
|
|
|
/* osmo-pcu should now ask for resolution: */
|
|
f_ipa_ctrl_wait_link_up();
|
|
var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
|
|
int2str(info_ind.lac) & "." &
|
|
int2str(info_ind.cell_id) & "." &
|
|
int2str(req_arfcn) & "." &
|
|
int2str(req_bsic);
|
|
f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
|
|
/* RIM procedure: */
|
|
as_outbound_nacc_rim_resolve(info_ind);
|
|
|
|
BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
|
|
/* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
|
|
f_sleep(0.1);
|
|
/* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
|
|
f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
|
|
|
|
/* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
|
|
/* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
|
|
* Data with unassigned DL TBF in line above): */
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
/* Continue receiving Pkt Cell Neighbor Data */
|
|
f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
|
|
|
|
/* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
|
|
f_rx_rlcmac_dl_block(dl_block, sched_fn);
|
|
if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
|
|
setverdict(fail, "Rx unexpected DL block: ", dl_block);
|
|
f_shutdown(__BFILE__, __LINE__);
|
|
}
|
|
/* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
|
|
if (dl_block.ctrl.mac_hdr.rrbp_valid) {
|
|
sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
|
|
}
|
|
|
|
/* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
|
|
f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
|
|
f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
|
|
f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
|
|
f_dl_block_ack_fn(dl_block, dl_fn));
|
|
}
|
|
|
|
|
|
function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
|
|
runs on RAW_PCU_Test_CT
|
|
{
|
|
var template (value) RAN_Information_Request_RIM_Container req_cont;
|
|
var template (value) PDU_BSSGP bssgp_rim_pdu;
|
|
var template PDU_BSSGP bssgp_rim_pdu_expect;
|
|
var template RAN_Information_RIM_Container rim_cont_expect;
|
|
var RIM_Routing_Address bts_addr;
|
|
|
|
/* Send sysinfo to the PCU */
|
|
var template PCUIF_Message si1_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '5506'O & si1_default, 0, 0, 0, 0, 32767);
|
|
BTS.send(si1_data_ind);
|
|
var template PCUIF_Message si3_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '4906'O & si3_default, 0, 0, 0, 0, 32767);
|
|
BTS.send(si3_data_ind);
|
|
var template PCUIF_Message si13_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '0106'O & si13_default, 0, 0, 0, 0, 32767);
|
|
BTS.send(si13_data_ind);
|
|
f_sleep(1.0);
|
|
|
|
bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
|
|
ts_RIM_Sequence_Number(1),
|
|
ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
|
|
ts_RIM_Protocol_Version_Number(1),
|
|
tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
|
|
omit);
|
|
bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
|
|
tx_src_addr, req_cont);
|
|
|
|
rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
|
|
tr_RIM_Sequence_Number(1),
|
|
tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
|
|
tr_RIM_Protocol_Version_Number(1),
|
|
tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 3, si_default)),
|
|
omit);
|
|
|
|
bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
|
|
tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
|
|
rim_cont_expect);
|
|
RIM.send(bssgp_rim_pdu);
|
|
timer T := 2.0;
|
|
T.start;
|
|
alt {
|
|
[] RIM.receive(bssgp_rim_pdu_expect) { }
|
|
[] RIM.receive {
|
|
setverdict(fail, "Unexpected BSSGP RIM PDU received");
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "No BSSGP RIM PDU received");
|
|
mtc.stop;
|
|
}
|
|
}
|
|
}
|
|
/* Send a RIM RAN info request to the PCU and verify the response, we expect
|
|
* getting the system information back which we have transfered to the PCU via
|
|
* PCUIF on startup. */
|
|
testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
|
|
var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
|
|
var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
|
|
|
|
f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
|
|
* Routing information, to verify PCU handles that kind of address just fine
|
|
*/
|
|
testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename());
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
|
|
var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
|
|
var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
|
|
|
|
f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
|
|
tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
/* Same as above, but in this case we simulate the rare case in which the PCU
|
|
* has no system information available. We expect getting a response back but
|
|
* with no system information inside. */
|
|
testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
|
|
var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
|
|
var PCUIF_Message pcu_msg;
|
|
timer T := 2.0;
|
|
|
|
/* Initialize NS/BSSGP side */
|
|
f_init_bssgp();
|
|
|
|
/* Initialize the PCU interface abstraction */
|
|
f_init_raw(testcasename(), info_ind);
|
|
|
|
/* Establish BSSGP connection to the PCU */
|
|
f_bssgp_establish();
|
|
|
|
/* Clear sysinfo from the PCU */
|
|
var template PCUIF_Message si1_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '01'O, 0, 0, 0, 0, 32767);
|
|
BTS.send(si1_data_ind);
|
|
var template PCUIF_Message si3_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '03'O, 0, 0, 0, 0, 32767);
|
|
BTS.send(si3_data_ind);
|
|
var template PCUIF_Message si16_data_ind := ts_PCUIF_DATA_IND(0, 0, 0, 0, PCU_IF_SAPI_BCCH, '0b'O, 0, 0, 0, 0, 32767);
|
|
BTS.send(si16_data_ind);
|
|
f_sleep(1.0);
|
|
|
|
var RIM_Routing_Address dst_addr;
|
|
var RIM_Routing_Address src_addr;
|
|
var template (value) RAN_Information_Request_RIM_Container req_cont;
|
|
var template (value) PDU_BSSGP bssgp_rim_pdu;
|
|
var template PDU_BSSGP bssgp_rim_pdu_expect;
|
|
var template RAN_Information_RIM_Container rim_cont_expect;
|
|
|
|
var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
|
|
src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
|
|
dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
|
|
|
|
req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
|
|
ts_RIM_Sequence_Number(1),
|
|
ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
|
|
ts_RIM_Protocol_Version_Number(1),
|
|
tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
|
|
omit);
|
|
bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
|
|
ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
req_cont);
|
|
|
|
|
|
rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
|
|
tr_RIM_Sequence_Number(1),
|
|
tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
|
|
tr_RIM_Protocol_Version_Number(1),
|
|
tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
|
|
omit);
|
|
|
|
bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
|
|
tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
|
|
rim_cont_expect);
|
|
RIM.send(bssgp_rim_pdu);
|
|
T.start;
|
|
alt {
|
|
[] RIM.receive(bssgp_rim_pdu_expect) { }
|
|
[] RIM.receive {
|
|
setverdict(fail, "Unexpected BSSGP RIM PDU received");
|
|
}
|
|
[] T.timeout {
|
|
setverdict(fail, "No BSSGP RIM PDU received");
|
|
mtc.stop;
|
|
}
|
|
}
|
|
|
|
f_shutdown(__BFILE__, __LINE__, final := true);
|
|
}
|
|
|
|
control {
|
|
execute( TC_pcuif_suspend() );
|
|
execute( TC_pcuif_suspend_active_tbf() );
|
|
execute( TC_ta_ptcch_idle() );
|
|
execute( TC_ta_rach_imm_ass() );
|
|
execute( TC_ta_idle_dl_tbf_ass() );
|
|
execute( TC_ta_ptcch_ul_multi_tbf() );
|
|
execute( TC_cs_lqual_ul_tbf() );
|
|
execute( TC_cs_initial_ul() );
|
|
execute( TC_cs_max_ul() );
|
|
execute( TC_cs_initial_dl() );
|
|
execute( TC_cs_max_dl() );
|
|
execute( TC_dl_cs1_to_cs4() );
|
|
execute( TC_mcs_initial_ul() );
|
|
execute( TC_mcs_max_ul() );
|
|
execute( TC_mcs_initial_dl() );
|
|
execute( TC_mcs_max_dl() );
|
|
execute( TC_t3141() );
|
|
execute( TC_n3101_max_t3169() );
|
|
execute( TC_n3103_max_t3169() );
|
|
execute( TC_x2031_t3191() );
|
|
execute( TC_zero_x2031_t3191() );
|
|
execute( TC_t3193() );
|
|
execute( TC_n3105_max_t3195() );
|
|
execute( TC_countdown_procedure() );
|
|
execute( TC_ul_all_sizes() );
|
|
execute( TC_ul_data_toolong_fills_padding() );
|
|
execute( TC_mo_ping_pong() );
|
|
execute( TC_mo_ping_pong_with_ul_racap() );
|
|
execute( TC_force_two_phase_access() );
|
|
execute( TC_mt_ping_pong() );
|
|
execute( TC_mt_ping_pong_with_dl_racap() );
|
|
execute( TC_ul_intermediate_retrans() );
|
|
execute( TC_imm_ass_dl_block_retrans() );
|
|
execute( TC_dl_flow_more_blocks() );
|
|
execute( TC_ul_flow_multiple_llc_blocks() );
|
|
execute( TC_dl_no_ack_retrans_imm_ass() );
|
|
execute( TC_paging_cs_from_bts() );
|
|
execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
|
|
execute( TC_paging_cs_from_sgsn_sign() );
|
|
execute( TC_paging_cs_from_sgsn_ptp() );
|
|
execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
|
|
execute( TC_paging_ps_from_sgsn_sign() );
|
|
execute( TC_paging_ps_from_sgsn_ptp() );
|
|
execute( TC_paging_cs_multi_ms_imsi_tmsi() );
|
|
execute( TC_paging_cs_multi_ms_imsi() );
|
|
execute( TC_paging_cs_multi_ms_tmsi() );
|
|
execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
|
|
execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
|
|
execute( TC_dl_gprs_data_no_llc_ui_dummy() );
|
|
execute( TC_dl_egprs_data_no_llc_ui_dummy() );
|
|
|
|
/* EGPRS specific test cases */
|
|
execute( TC_egprs_pkt_chan_req_signalling() );
|
|
execute( TC_egprs_pkt_chan_req_one_phase() );
|
|
execute( TC_egprs_pkt_chan_req_two_phase() );
|
|
execute( TC_egprs_pkt_chan_req_reject_content() );
|
|
execute( TC_egprs_pkt_chan_req_reject_emergency() );
|
|
execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
|
|
|
|
execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
|
|
|
|
/* Immediate Assignment on AGCH/PCH */
|
|
execute( TC_pcuif_fh_imm_ass_ul_egprs() );
|
|
execute( TC_pcuif_fh_imm_ass_ul() );
|
|
execute( TC_pcuif_fh_imm_ass_dl() );
|
|
/* Packet Uplink/Downlink Assignment on PACCH */
|
|
execute( TC_pcuif_fh_pkt_ass_ul() );
|
|
execute( TC_pcuif_fh_pkt_ass_dl() );
|
|
execute( TC_multitrx_multims_alloc() );
|
|
execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
|
|
execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
|
|
execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
|
|
|
|
execute( TC_multiplex_dl_gprs_egprs() );
|
|
|
|
execute( TC_pcuif_info_ind_subsequent() );
|
|
execute( TC_nacc_outbound_success() );
|
|
execute( TC_nacc_outbound_success_no_ctrl_ack() );
|
|
execute( TC_nacc_outbound_success_twice() );
|
|
execute( TC_nacc_outbound_success_twice_nocache() );
|
|
execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
|
|
execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
|
|
execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
|
|
execute( TC_nacc_outbound_si_resolve_timeout() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
|
|
execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
|
|
|
|
execute( TC_rim_ran_info_req_single_rep() );
|
|
execute( TC_rim_ran_info_req_single_rep_eutran() );
|
|
execute( TC_rim_ran_info_req_single_rep_no_si() );
|
|
}
|
|
|
|
}
|