blob: 01113abc09f43c4cb3ddf1913885b8fb5251c480 [file] [log] [blame]
Harald Weltea0895f92018-03-08 11:51:23 +01001module PCU_Tests {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002
3/* "RAW" PCU tests: Talk directly to the PCU socket of OsmoPCU on the one hand side (emulating
4 the BTS/BSC side PCU socket server) and the Gb interface on the other hand side. No NS/BSSGP
5 Emulation is used; rather, we simply use the NS_CodecPort to implement both standard and non-
6 standard procedures on the NS and BSSGP level. The goal of these tests is to test exactly
7 those NS and BSSGP implementations on the BSS (PCU) side. */
8
9/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +070010 * (C) 2019-2020 Vadim Yanitskiy <axilirator@gmail.com>
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020011 * All rights reserved.
12 *
13 * Released under the terms of GNU General Public License, Version 2 or
14 * (at your option) any later version.
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18
19friend module PCU_Tests_NS;
20
21import from General_Types all;
22import from Osmocom_Types all;
23import from GSM_Types all;
24import from GSM_RR_Types all;
25
26import from Osmocom_VTY_Functions all;
27import from TELNETasp_PortType all;
28
29import from MobileL3_GMM_SM_Types all;
30import from RLCMAC_CSN1_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020031import from RLCMAC_CSN1_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020032import from RLCMAC_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020033import from RLCMAC_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020034
35import from MobileL3_CommonIE_Types all;
36import from L3_Templates all;
37
38import from NS_Types all;
39import from BSSGP_Types all;
40import from Osmocom_Gb_Types all;
41
42import from BSSGP_Emulation all; /* BssgpConfig */
43import from NS_Emulation all; /* NSConfiguration */
44
45import from UD_Types all;
46import from PCUIF_Types all;
47import from PCUIF_CodecPort all;
48import from PCUIF_Components all;
49import from IPL4asp_Types all;
50import from Native_Functions all;
51import from SGSN_Components all;
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +020052import from GPRS_Components all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020053
Daniel Willmann535aea62020-09-21 13:27:08 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010059import from IPA_Emulation all;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +010060import from Osmocom_CTRL_Types all;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010061import from Osmocom_CTRL_Adapter all;
62import from Osmocom_CTRL_Functions all;
63
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020064modulepar {
65 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
66
67 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Daniel Willmann535aea62020-09-21 13:27:08 +020068
69 charstring mp_pcu_statsd_ip := "127.0.0.1";
70 integer mp_pcu_statsd_port := 8125;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010071
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +020072 charstring mp_ctrl_neigh_ip := ""; /* Use new PCUIF over IPA multiplex for Neigh Addr Resolution */
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010073 integer mp_ctrl_neigh_port := 4248;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020074}
75
76
77/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010078friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
79:= {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070080 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010081 flags := flags,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +010082 trx := ts_PCUIF_InfoTrxs_def(GPRS_Components.mp_base_arfcn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020083 bsic := 7,
84 mcc := 262,
85 mnc := 42,
86 mnc_3_digits := 0,
87 lac := 13135,
88 rac := 0,
89 nsei := mp_nsconfig.nsei,
90 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
91 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
92 cell_id := 20960,
93 repeat_time := 5 * 50,
94 repeat_count := 3,
Harald Welte5339b2e2020-10-04 22:52:56 +020095 bvci := mp_gb_cfg.bvc[0].bvci,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020096 t3142 := 20,
97 t3169 := 5,
98 t3191 := 5,
99 t3193_10ms := 160,
100 t3195 := 5,
Pau Espin Pedrol76de1662021-03-01 17:40:58 +0100101 n3101 := 10,
102 n3103 := 4,
103 n3105 := 8,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200104 cv_countdown := 15,
105 dl_tbf_ext := 250 * 10, /* ms */
106 ul_tbf_ext := 250 * 10, /* ms */
107 initial_cs := 2,
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100108 initial_mcs := 1,
Harald Welte90f19742020-11-06 19:34:40 +0100109 nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
110 local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
111 remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +0100112 remote_addr := f_PCUIF_RemoteAddr(
Harald Welte90f19742020-11-06 19:34:40 +0100113 f_PCUIF_AF2addr_type(mp_nsconfig.nsvc[0].provider.ip.address_family), mp_nsconfig.nsvc[0].provider.ip.local_ip)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200114}
115
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100116/* Passed in RAN-INFO message from emulated neighbor using RIM */
117const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
118const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
119const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
120const octetstring si_default := si1_default & si3_default & si13_default;
121
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +0100122const MultislotCap_GPRS mscap_gprs_def := {
123 gprsmultislotclass := '00011'B,
124 gprsextendeddynalloccap := '0'B
125};
126const MultislotCap_EGPRS mscap_egprs_def := {
127 egprsmultislotclass := '00011'B,
128 egprsextendeddynalloccap := '0'B
129};
130template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
131template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
132
133const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
134 gprsmultislotclass := '00011'B,
135 gprsextendeddynalloccap := '0'B
136};
137const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
138 egprsmultislotclass := '00011'B,
139 egprsextendeddynalloccap := '0'B
140};
141template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
142template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
143
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200144type record lqual_range {
145 /* component reference to the IPA_Client component used for RSL */
146 uint8_t low,
147 uint8_t high
148}
149
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100150type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700151 /* PCU interface abstraction component */
152 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700153
Daniel Willmann535aea62020-09-21 13:27:08 +0200154 /* StatsD */
155 var StatsD_Checker_CT vc_STATSD;
156
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200157 /* Connection to the PCUIF component */
158 port RAW_PCU_MSG_PT PCUIF;
159 /* VTY connection to the PCU */
160 port TELNETasp_PT PCUVTY;
161
162 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
163 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
164 {low := 5, high := 8},
165 {low := 7, high := 13},
166 {low := 12,high := 35}};
167 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
168 {low := 5, high := 8},
169 {low := 7, high := 13},
170 {low := 12,high := 15},
171 {low := 14, high := 17},
172 {low := 16, high := 18},
173 {low := 17,high := 20},
174 {low := 19, high := 24},
175 {low := 23,high := 35}};
176 var uint8_t g_cs_initial_dl := 1;
177 var uint8_t g_cs_initial_ul := 1;
178 var uint8_t g_mcs_initial_dl := 1;
179 var uint8_t g_mcs_initial_ul := 1;
180 var uint8_t g_cs_max_dl := 4;
181 var uint8_t g_cs_max_ul := 4;
182 var uint8_t g_mcs_max_dl := 9;
183 var uint8_t g_mcs_max_ul := 9;
184
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200185 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200186
187 /* Guard timeout */
188 timer g_T_guard := 60.0;
189};
190
191private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
192 [] g_T_guard.timeout {
193 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700194 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200195 }
196}
197
198private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
199 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
200 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
201
202 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
203 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
204}
205
206private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
207 var charstring cmd;
208
209 cmd := "cs link-quality-ranges" &
210 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
211 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
212 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
213 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
214 f_vty_config2(PCUVTY, {"pcu"}, cmd);
215
216 cmd := "mcs link-quality-ranges" &
217 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
218 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
219 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
220 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
221 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
222 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
223 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
224 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
225 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
226 f_vty_config2(PCUVTY, {"pcu"}, cmd);
227}
228
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100229private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
230 f_pcuvty_set_neigh_caches(0, 0);
231}
232
233private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
234runs on RAW_PCU_Test_CT {
235 if (neigh_cache_secs == -1) {
236 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
237 } else {
238 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
239 }
240 if (si_cache_secs == -1) {
241 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
242 } else {
243 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
244 }
245}
246
Pau Espin Pedrole8a94442021-11-15 17:05:46 +0100247private function f_pcuvty_set_timer(integer t, integer val)
248runs on RAW_PCU_Test_CT {
249 if (t >= 0) {
250 f_vty_config2(PCUVTY, {"pcu"}, "timer T" & int2str(t) & " " & int2str(val));
251 } else {
252 f_vty_config2(PCUVTY, {"pcu"}, "timer X" & int2str(t * -1) & " " & int2str(val));
253 }
254}
255
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100256private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200257 map(self:PCUVTY, system:PCUVTY);
258 f_vty_set_prompts(PCUVTY);
259 f_vty_transceive(PCUVTY, "enable");
260
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100261 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
262 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200263 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
264 } else {
265 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
266 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200267
268 if (g_force_two_phase_access) {
269 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
270 } else {
271 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
272 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200273}
274
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200275function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200276runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200277 /* Start the guard timer */
278 g_T_guard.start;
279 activate(as_Tguard_RAW());
280
281 /* Init PCU interface component */
Harald Welte5339b2e2020-10-04 22:52:56 +0200282 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200283 connect(vc_PCUIF:MTC, self:PCUIF);
284 map(vc_PCUIF:PCU, system:PCU);
285
286 /* Create one BTS component (we may want more some day) */
Harald Welte5339b2e2020-10-04 22:52:56 +0200287 vc_BTS := RAW_PCU_BTS_CT.create("BTS");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200288 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
289 connect(vc_BTS:TC, self:BTS);
290
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100291 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200292
Daniel Willmann535aea62020-09-21 13:27:08 +0200293 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
294 /* This is normally done in the ConnHdlr component, but here
295 * the Test_CT doubles as ConnHdlr */
296 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
297
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200298 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100299 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200300
301 /* Wait until the BTS is ready (SI13 negotiated) */
302 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
303}
304
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700305/* Register TLLI of each allocated GprsMS instance */
306private function f_multi_ms_bssgp_register()
307runs on RAW_PCU_Test_CT {
308 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
309 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
310 }
311}
312
313/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
314private function f_multi_ms_establish_tbf(boolean do_activate := false)
315runs on RAW_PCU_Test_CT {
316 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
317 /* Establish an Uplink TBF */
318 f_ms_establish_ul_tbf(g_ms[i]);
319
320 /* Send a random block, so this TBF becomes "active" */
321 if (do_activate) {
322 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100323 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700324 var octetstring dummy := f_rnd_octstring(12);
325 var RlcmacDlBlock dl_block;
326 var uint32_t poll_fn;
327
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200328 f_ms_tx_ul_data_block(g_ms[i], dummy, with_tlli := true, fn := g_ms[i].ul_tbf.start_time_fn, nr := nr);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700329 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
330 }
331 }
332}
333
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100334private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
335 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
336runs on RAW_PCU_Test_CT return PollFnCtx {
337 var PollFnCtx pollctx;
338
339 /* Single block (two phase) packet access */
340 var uint16_t ra := bit2int(chan_req_sb);
341 if (g_force_two_phase_access) {
342 /* If 2phase access is enforced by the network, then let's
343 * request a One phase packet access, we'll receive a single block
344 * anyway
345 */
346 ra := bit2int(chan_req_def);
347 }
348
349 /* Establish an Uplink TBF */
350 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
351 f_ms_establish_ul_tbf(ms);
352
353 /* Make sure we've got an Uplink TBF assignment */
354 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
355 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
356 f_shutdown(__BFILE__, __LINE__);
357 }
358
359 /* Send PACKET RESOURCE REQUEST
360 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
361 */
362 if (istemplatekind(pkt_res_req, "omit")) {
363 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
364 }
365
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200366 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));
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100367 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100368 * overwrite the TS allocation on MS with info from new UL TBF:
369 */
370 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
371 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
372 return pollctx;
373}
374
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200375testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200376 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100377 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200378 timer T;
379
380 /* Initialize NS/BSSGP side */
381 f_init_bssgp();
382
383 /* Initialize the PCU interface abstraction */
384 f_init_raw(testcasename());
385
386 /* Establish BSSGP connection to the PCU */
387 f_bssgp_establish();
388
389 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
390
391 T.start(2.0);
392 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100393 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200394 setverdict(pass);
395 }
396 [] T.timeout {
397 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
398 }
399 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700400
401 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200402}
403
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100404/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
405testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
406 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200407 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100408 var RlcmacDlBlock dl_block;
409 var octetstring data := f_rnd_octstring(10);
410 var uint32_t sched_fn;
411 var uint32_t dl_fn;
412 var GprsMS ms;
413 timer T;
414
415 /* Initialize NS/BSSGP side */
416 f_init_bssgp();
417 /* Initialize GPRS MS side */
418 f_init_gprs_ms();
419 ms := g_ms[0]; /* We only use first MS in this test */
420
421 /* Initialize the PCU interface abstraction */
422 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
423
424 /* Establish BSSGP connection to the PCU */
425 f_bssgp_establish();
426 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
427
428 /* Establish an Uplink TBF */
429 f_ms_establish_ul_tbf(ms);
430
431 /* Send one UL block (with TLLI since we are in One-Phase Access
432 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200433 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100434 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
435 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
436 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
437
438 /* UL block should be received in SGSN */
439 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
440
441 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
442 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
443 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
444
445 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
446 f_sleep(X2002);
447 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
448
449 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
450 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
451
452 T.start(2.0);
453 alt {
454 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
455 setverdict(pass);
456 }
457 [] T.timeout {
458 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
459 f_shutdown(__BFILE__, __LINE__);
460 }
461 }
462
463 /* Make sure we don't receive data for that TBF since it was released
464 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200465 f_pcuif_rx_data_req_pdtch(data_msg);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100466 if (data_msg.dl_block == omit) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200467 /* IDLE block, expected on new PCU versions */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200468 } else {
469 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100470 f_shutdown(__BFILE__, __LINE__);
471 }
472
473 /* New data arrives, PCU should page the MS since no TBF active exists: */
474 /* Send some more data, it will never reach the MS */
475 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
476 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
477
478 f_shutdown(__BFILE__, __LINE__, final := true);
479}
480
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200481/* Test of correct Timing Advance at the time of TBF establishment
482 * (derived from timing offset of the Access Burst). */
483testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200484 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200485
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200486 /* Initialize GPRS MS side */
487 f_init_gprs_ms();
488 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200489 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100490 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200491
492 /* We cannot send too many TBF requests in a short time because
493 * at some point the PCU will fail to allocate a new TBF. */
494 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
495 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200496 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700497 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200498
499 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200500 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700501 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200502 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700503 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700504 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200505 }
506 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700507
508 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200509}
510
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200511/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
512 * sent in response to the first Uplink block after resource allocation. */
513testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
514 var GprsMS ms := valueof(t_GprsMS_def);
515 var PacketUlAckNack ul_ack_nack;
516 var PacketTimingAdvance pkt_ta;
517 var RlcmacDlBlock dl_block;
518 var uint32_t sched_fn;
519
520 /* Initialize NS/BSSGP side */
521 f_init_bssgp();
522
523 /* Initialize the PCU interface abstraction */
524 f_init_raw(testcasename());
525
526 /* Establish BSSGP connection to the PCU */
527 f_bssgp_establish();
528 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
529
530 /* Establish an Uplink TBF */
531 f_ms_establish_ul_tbf(ms);
532
533 /* In a busy network, there can be a significant delay between resource
534 * allocation (Packet Uplink Assignment above) and the actual time when
535 * the MS is allowed to transmit the first Uplink data block. */
536
537 /* Simulate a delay > 0 */
538 ms.ta := 2;
539
540 /* We're in One-Phase Access contention resoultion, include TLLI */
541 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
542 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
543
544 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
545 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
546 pkt_ta := ul_ack_nack.gprs.pkt_ta;
547 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
548 pkt_ta := ul_ack_nack.egprs.pkt_ta;
549 } else {
550 setverdict(fail, "PacketTimingAdvance IE is not present");
551 f_shutdown(__BFILE__, __LINE__);
552 }
553
554 if (not ispresent(pkt_ta.val)) {
555 setverdict(fail, "Timing Advance value is not present");
556 f_shutdown(__BFILE__, __LINE__);
557 } else if (pkt_ta.val != ms.ta) {
558 setverdict(fail, "Timing Advance mismatch: expected ",
559 ms.ta, ", but received ", pkt_ta.val);
560 f_shutdown(__BFILE__, __LINE__);
561 }
562}
563
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200564/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
565 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
566 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
567 * no active TBF exists at the moment of establishment (idle mode). */
568testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100569 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200570
571 /* Initialize NS/BSSGP side */
572 f_init_bssgp();
573
574 /* Initialize the PCU interface abstraction */
575 f_init_raw(testcasename());
576
577 /* Establish BSSGP connection to the PCU */
578 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100579 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200580
581 /* SGSN sends some DL data, PCU will initiate Packet Downlink
582 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100583 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
584 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200585
586 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
587 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
588 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100589 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700590 setverdict(fail, "Timing Advance value doesn't match");
591 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700592
593 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200594}
595
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200596/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200597 * while neither Uplink nor Downlink TBF is established. */
598testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100599 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200600 timer T;
601
602 /* Initialize the PCU interface abstraction */
603 f_init_raw(testcasename());
604
605 /* Sent an RTS.req for PTCCH/D */
606 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
607 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
608 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100609
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200610 T.start(5.0);
611 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200612 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
613 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
614 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200615 }
616 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100617 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
618 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200619 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200620 [] BTS.receive(PCUIF_Message:?) { repeat; }
621 [] T.timeout {
622 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700623 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200624 }
625 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100626 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700627
628 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200629}
630
631/* Test of correct Timing Advance during an active Uplink TBF.
632 *
633 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
634 * are not continuous and there can be long time gaps between them. This happens
635 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
636 * significantly change between such rare Uplink transmissions, so GPRS introduces
637 * additional mechanisms to control Timing Advance, and thus reduce interference
638 * between neighboring TDMA time-slots.
639 *
640 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
641 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
642 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
643 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
644 * among with the initial Timing Advance value. And here PTCCH comes to play.
645 *
646 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
647 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
648 * continuously. To ensure continuous measurements of the signal propagation
649 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
650 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
651 *
652 * The purpose of this test case is to verify the assignment of Timing Advance
653 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
654 * first establishes several Uplink TBFs, but does not transmit any Uplink
655 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
656 * indications to the PCU, checking the correctness of two received PTCCH/D
657 * messages (period of PTCCH/D is two multi-frames).
658 */
659
660/* List of ToA values for Access Bursts to be sent on PTCCH/U,
661 * each ToA (Timing of Arrival) value is in units of 1/4 of
662 * a symbol (i.e. 1 symbol is 4 QTA units). */
663type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
664const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
665 0, 0, 0, 0,
666 0, 0, 0, 0,
667 0, 0, 0, 0,
668 0, 0, 0, 0
669};
670
671private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
672 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
673runs on RAW_PCU_Test_CT {
674 var RAW_PCU_Event event;
675 var integer ss;
676
677 /* Send Access Bursts on PTCCH/U for every TA Index */
678 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
679 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700680 if (ss < 0) { /* Shall not happen */
681 f_shutdown(__BFILE__, __LINE__);
682 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200683
684 log("Sending an Access Burst on PTCCH/U",
685 ", sub-slot=", ss, " (TAI)",
686 ", fn=", event.data.tdma_fn,
687 ", ToA=", toa_map[ss], " (QTA)");
688 /* TODO: do we care about RA and burst format? */
689 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
690 ra := oct2int('3A'O),
691 is_11bit := 0,
692 burst_type := BURST_TYPE_0,
693 fn := event.data.tdma_fn,
694 arfcn := 871,
695 qta := toa_map[ss],
696 sapi := PCU_IF_SAPI_PTCCH));
697 repeat;
698 }
699}
700
701private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
702 template PTCCHDownlinkMsg t_ta_msg)
703runs on RAW_PCU_Test_CT {
704 var PTCCHDownlinkMsg ta_msg;
705 var PCUIF_Message pcu_msg;
706 timer T;
707
708 /* First, send an RTS.req for the upcoming PTCCH/D block */
709 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
710 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
711 arfcn := 871, block_nr := 0));
712 T.start(2.0);
713 alt {
714 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
715 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
716 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
717 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
718 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
719 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
720 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
721 log("Rx PTCCH/D message: ", ta_msg);
722
723 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700724 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200725 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
726 }
727 }
728 [] BTS.receive { repeat; }
729 [] T.timeout {
730 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200731 }
732 }
733}
734
735testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
736 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200737 var GprsMS ms;
738
739 /* Initialize GPRS MS side */
740 f_init_gprs_ms();
741 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200742
743 /* Initialize the PCU interface abstraction */
744 f_init_raw(testcasename());
745
746 /* Enable forwarding of PTCCH/U TDMA events to us */
747 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
748
749 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
750 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200751 /* Establish an Uplink TBF */
752 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200753
754 /* We expect incremental TFI/USF assignment (dynamic allocation) */
755 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200756 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200757 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700758 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200759 }
760
761 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200762 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200763 setverdict(fail, "Failed to match Timing Advance Index for #", i);
764 /* Keep going, the current OsmoPCU does not assign TA Index */
765 }
766 }
767
768 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
769 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
770 for (var integer i := 0; i < 7; i := i + 1) {
771 /* ToA in units of 1/4 of a symbol */
772 toa_map[i] := (i + 1) * 7 * 4;
773 }
774
775 /* Now we have all 7 TBFs established in one-phase access mode,
776 * however we will not be sending any data on them. Instead, we
777 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
778 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
779 *
780 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
781 * time-slots, so at the moment of scheduling a PTCCH/D block
782 * the PCU has odd number of PTCCH/U Access Bursts received. */
783 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
784 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
785 /* Other values are not known (yet) */
786 tai3_ta := ?));
787 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
788 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
789 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
790 /* Other values are out of our interest */
791 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700792
793 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200794}
795
796/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
797 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
798 *
799 * NOTE: the ranges are intentionally overlapping because OsmoPCU
800 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
801private template integer CS1_lqual_dB_range := (-infinity .. 6);
802private template integer CS2_lqual_dB_range := (5 .. 8);
803private template integer CS3_lqual_dB_range := (7 .. 13);
804private template integer CS4_lqual_dB_range := (12 .. infinity);
805
806testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200807 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200808 var GprsMS ms;
809 var uint32_t unused_fn, sched_fn;
810 var uint4_t cv;
811
812 /* Initialize GPRS MS side */
813 f_init_gprs_ms();
814 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200815
816 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100817 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200818
819 f_pcuvty_set_allowed_cs_mcs();
820 f_pcuvty_set_link_quality_ranges();
821
822 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200823 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200824
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200825
826 /* The actual / old link quality values. We need to keep track of the old
827 * (basically previous) link quality value, because OsmoPCU actually
828 * changes the coding scheme if not only the actual, but also the old
829 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200831 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200832
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200833 /* Send one UL block (with TLLI since we are in One-Phase Access
834 contention resoultion) and make sure it is ACKED fine. */
835 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
836 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200837 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200838 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
839 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
840 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200841
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200842 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
843 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200844 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 lqual_old := ms.lqual_cb;
846 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200847
848 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200849 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
850 if (i > g_bs_cv_max) {
851 cv := 15;
852 } else {
853 cv := i;
854 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200855
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200856 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
857
858 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
859 f_rx_rlcmac_dl_block(dl_block, unused_fn);
860 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
861 continue;
862 }
863 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
864 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
865 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
866 f_shutdown(__BFILE__, __LINE__);
867 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200868
869 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
870 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
871
872 /* Match the received Channel Coding Command. Since we are increasing
873 * the link quality value on each iteration and not decreasing, there
874 * is no need to check the both old and current link quality values. */
875 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200876 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200877 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
878 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
879 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
880 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
881 }
882
883 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
884 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200885 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200886 }
887 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700888
889 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200890}
891
892/* Test the max UL CS set by VTY works fine */
893testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200894 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200895 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200896 var uint32_t unused_fn, sched_fn;
897 var GprsMS ms;
898
899 /* Initialize GPRS MS side */
900 f_init_gprs_ms();
901 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200902
903 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100904 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200905
906 /* Set initial UL CS to 3 */
907 g_cs_initial_ul := 3;
908 f_pcuvty_set_allowed_cs_mcs();
909 f_pcuvty_set_link_quality_ranges();
910
911 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200912 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200913
914 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200915 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200916
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200917 /* Send one UL block (with TLLI since we are in One-Phase Access
918 contention resoultion) and make sure it is ACKED fine. */
919 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
920 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200921 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200922 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
923 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
924 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200925
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200926 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
927 while (true) {
928 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
929 f_rx_rlcmac_dl_block(dl_block, unused_fn);
930 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
931 continue;
932 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200933
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200934 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
935 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
936 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
937 f_shutdown(__BFILE__, __LINE__);
938 break;
939 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200940
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200941 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200942 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200943 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200944 if (last_ch_coding != CH_CODING_CS3) {
945 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200946 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200947 }
948
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200949 /* Remaining UL blocks are used to make sure regardless of initial
950 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200951 /* 0 dB, make sure we downgrade CS */
952 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200953 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200954 f_ms_tx_ul_data_block_multi(ms, 5);
955 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
956 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
957 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200958
959 if (last_ch_coding != CH_CODING_CS1) {
960 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200961 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200962 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700963
964 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200965}
966
967/* Test the max UL CS set by VTY works fine */
968testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200969 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200970 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200971 var uint32_t unused_fn, sched_fn;
972 var GprsMS ms;
973
974 /* Initialize GPRS MS side */
975 f_init_gprs_ms();
976 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200977
978 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100979 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200980
981 /* Set maximum allowed UL CS to 3 */
982 g_cs_max_ul := 3;
983 f_pcuvty_set_allowed_cs_mcs();
984 f_pcuvty_set_link_quality_ranges();
985
986 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200987 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200988
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200989 /* Send one UL block (with TLLI since we are in One-Phase Access
990 contention resoultion) and make sure it is ACKED fine. */
991 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
992 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200993 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200994 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
995 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
996 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200997
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200998 ms.lqual_cb := 40*10; /* 40 dB */
999 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001000
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001001 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1002 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001003
1004 if (last_ch_coding != CH_CODING_CS3) {
1005 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001006 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001007 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001008
1009 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001010}
1011
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001012/* Test the initial DL CS set by VTY works fine */
1013testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1014 var octetstring data := f_rnd_octstring(10);
1015 var CodingScheme exp_dl_cs_mcs;
1016 var RlcmacDlBlock dl_block;
1017 var uint32_t poll_fn;
1018 var GprsMS ms;
1019
1020 /* Initialize NS/BSSGP side */
1021 f_init_bssgp();
1022 /* Initialize GPRS MS side */
1023 f_init_gprs_ms();
1024 ms := g_ms[0]; /* We only use first MS in this test */
1025
1026 /* Initialize the PCU interface abstraction */
1027 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1028
1029 /* Set initial allowed DL CS to 3 */
1030 g_cs_initial_dl := 3;
1031 exp_dl_cs_mcs := CS_3;
1032 /* Set maximum allowed UL CS to 4 */
1033 g_cs_max_dl := 4;
1034 f_pcuvty_set_allowed_cs_mcs();
1035 f_pcuvty_set_link_quality_ranges();
1036
1037 /* Establish BSSGP connection to the PCU */
1038 f_bssgp_establish();
1039 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1040
1041 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1042 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1043 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1044
1045 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1046 f_sleep(X2002);
1047 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1048
1049 /* ACK the DL block */
1050 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1051 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1052 f_dl_block_ack_fn(dl_block, poll_fn));
1053
1054 f_shutdown(__BFILE__, __LINE__, final := true);
1055}
1056
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001057/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001058function f_dl_data_exp_cs(template (present) CodingScheme exp_final_cs := ?, template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001059 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001060 var RlcmacDlBlock prev_dl_block, dl_block;
1061 var uint32_t ack_fn;
1062 var uint32_t fn;
1063 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001064 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001065 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001066 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1067 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001068 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001069
1070 if (using_egprs) {
1071 exp_tmp_csmcs := mcs_egprs_any;
1072 bsn_mod := 2048;
1073 } else {
1074 exp_tmp_csmcs := cs_gprs_any;
1075 bsn_mod := 128;
1076 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001077
1078 /* Establish BSSGP connection to the PCU */
1079 f_bssgp_establish();
1080
1081 ms := g_ms[0]; /* We only use first MS in this test */
1082 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1083
1084 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001085 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001086 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1087
1088 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1089 f_sleep(X2002);
1090
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001091 for (var integer i := 0; i < 800; i := i + 1) {
1092 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001093 f_rx_rlcmac_dl_block(dl_block, fn);
1094
1095 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
1096 /* No more data to receive, done */
1097 break;
1098 }
1099
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001100 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001101
1102 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001103 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001104
1105 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001106 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001107 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001108 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, using_egprs), ack_fn);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001109 if (tx_data_remain != 0) {
1110 /* Submit more data from time to time to keep the TBF ongoing */
1111 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1112 tx_data_remain := tx_data_remain - 1;
1113 }
1114 }
1115 prev_dl_block := dl_block;
1116 }
1117
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001118 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1119 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001120
1121
1122 f_shutdown(__BFILE__, __LINE__, final := true);
1123}
1124
1125/* Verify DL CS above "cs max" set by VTY is never used */
1126testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1127 /* Initialize NS/BSSGP side */
1128 f_init_bssgp();
1129 /* Initialize GPRS MS side */
1130 f_init_gprs_ms();
1131
1132 /* Initialize the PCU interface abstraction */
1133 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1134
1135 /* Set maximum allowed DL CS to 3 */
1136 g_cs_initial_dl := 1;
1137 g_cs_max_dl := 3;
1138 f_pcuvty_set_allowed_cs_mcs();
1139 f_pcuvty_set_link_quality_ranges();
1140
1141 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1142}
1143
1144/* Check DL CS4 is used in good link conditions if allowed by config */
1145testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1146 /* Initialize NS/BSSGP side */
1147 f_init_bssgp();
1148 /* Initialize GPRS MS side */
1149 f_init_gprs_ms();
1150
1151 /* Initialize the PCU interface abstraction */
1152 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1153
1154 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1155 g_cs_initial_dl := 1;
1156 g_cs_max_dl := 4;
1157 f_pcuvty_set_allowed_cs_mcs();
1158 f_pcuvty_set_link_quality_ranges();
1159
1160 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1161}
1162
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001163/* Test the initial UL MCS set by VTY works fine */
1164testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1165 var RlcmacDlBlock dl_block;
1166 var PollFnCtx pollctx;
1167 var EgprsChCodingCommand last_ch_coding;
1168 var uint32_t unused_fn, sched_fn;
1169 var GprsMS ms;
1170 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001171
1172 /* Initialize GPRS MS side */
1173 f_init_gprs_ms();
1174 ms := g_ms[0]; /* We only use first MS in this test */
1175
1176 /* Initialize the PCU interface abstraction */
1177 f_init_raw(testcasename());
1178
1179 /* Set initial UL MCS to 3 */
1180 g_mcs_initial_ul := 3;
1181 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1182 f_pcuvty_set_allowed_cs_mcs();
1183 f_pcuvty_set_link_quality_ranges();
1184
1185 /* Take lqual (dB->cB) so that we stay in that MCS */
1186 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1187
1188 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001189 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_egprs_def));
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001190
1191 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1192 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1193 f_shutdown(__BFILE__, __LINE__);
1194 }
1195
1196 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1197 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1198
1199 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1200 while (true) {
1201 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1202 f_rx_rlcmac_dl_block(dl_block, unused_fn);
1203 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1204 continue;
1205 }
1206
1207 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1208 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1209 f_shutdown(__BFILE__, __LINE__);
1210 break;
1211 }
1212
1213 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1214 break;
1215 }
1216 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1217 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1218 f_shutdown(__BFILE__, __LINE__);
1219 }
1220
1221 /* Remaining UL blocks are used to make sure regardless of initial
1222 * lqual, we can go lower at any time
1223 * 0 dB, make sure we downgrade MCS */
1224 ms.lqual_cb := 0;
1225 /* 5 UL blocks, check we are in same initial MCS: */
1226 f_ms_tx_ul_data_block_multi(ms, 5);
1227 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1228 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1229 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1230
1231 if (last_ch_coding != CH_CODING_MCS1) {
1232 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1233 f_shutdown(__BFILE__, __LINE__);
1234 }
1235
1236 f_shutdown(__BFILE__, __LINE__, final := true);
1237}
1238
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001239/* Test the maximum UL MCS set by VTY works fine */
1240testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1241 var RlcmacDlBlock dl_block;
1242 var EgprsChCodingCommand last_ch_coding;
1243 var PollFnCtx pollctx;
1244 var uint32_t unused_fn, sched_fn;
1245 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001246
1247 /* Initialize GPRS MS side */
1248 f_init_gprs_ms();
1249 ms := g_ms[0]; /* We only use first MS in this test */
1250
1251 /* Initialize the PCU interface abstraction */
1252 f_init_raw(testcasename());
1253
1254 /* Set maximum allowed UL MCS to 5 */
1255 g_mcs_max_ul := 5;
1256 f_pcuvty_set_allowed_cs_mcs();
1257 f_pcuvty_set_link_quality_ranges();
1258
1259 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001260 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_egprs_def));
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001261 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1262 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1263
1264 ms.lqual_cb := 40*10; /* 40 dB */
1265 f_ms_tx_ul_data_block_multi(ms, 16);
1266
1267 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1268 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1269
1270 if (last_ch_coding != CH_CODING_MCS5) {
1271 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1272 f_shutdown(__BFILE__, __LINE__);
1273 }
1274
1275 f_shutdown(__BFILE__, __LINE__, final := true);
1276}
1277
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001278/* Test the initial DL CS set by VTY works fine */
1279testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1280 var octetstring data := f_rnd_octstring(10);
1281 var CodingScheme exp_dl_cs_mcs;
1282 var RlcmacDlBlock dl_block;
1283 var uint32_t poll_fn;
1284 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001285
1286 /* Initialize NS/BSSGP side */
1287 f_init_bssgp();
1288 /* Initialize GPRS MS side */
1289 f_init_gprs_ms();
1290 ms := g_ms[0]; /* We only use first MS in this test */
1291
1292 /* Initialize the PCU interface abstraction */
1293 f_init_raw(testcasename());
1294
1295 /* Set initial allowed DL MCS to 3 */
1296 g_mcs_initial_dl := 3;
1297 exp_dl_cs_mcs := MCS_3;
1298 /* Set maximum allowed DL MCS to 4 */
1299 g_mcs_max_dl := 4;
1300 f_pcuvty_set_allowed_cs_mcs();
1301 f_pcuvty_set_link_quality_ranges();
1302
1303 /* Establish BSSGP connection to the PCU */
1304 f_bssgp_establish();
1305 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1306
1307 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001308 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001309 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1310
1311 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1312 f_sleep(X2002);
1313 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1314
1315 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001316 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1317 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs)),
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001318 f_dl_block_ack_fn(dl_block, poll_fn));
1319
1320 f_shutdown(__BFILE__, __LINE__, final := true);
1321}
1322
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001323/* Verify DL MCS above "mcs max" set by VTY is never used */
1324testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1325 /* Initialize NS/BSSGP side */
1326 f_init_bssgp();
1327 /* Initialize GPRS MS side */
1328 f_init_gprs_ms();
1329
1330 /* Initialize the PCU interface abstraction */
1331 f_init_raw(testcasename());
1332
1333 /* Set maximum allowed DL CS to 3 */
1334 g_mcs_initial_dl := 1;
1335 g_mcs_max_dl := 3;
1336 f_pcuvty_set_allowed_cs_mcs();
1337 f_pcuvty_set_link_quality_ranges();
1338
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001339 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_mcs_max_dl, true), bssgp_ms_racap_egprs_def);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001340}
1341
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001342/* Verify PCU drops TBF after some time of inactivity. */
1343testcase TC_t3141() runs on RAW_PCU_Test_CT {
1344 var PCUIF_info_ind info_ind;
1345 var template (value) TsTrxBtsNum nr;
1346 var BTS_PDTCH_Block data_msg;
1347 var GprsMS ms;
1348 var uint3_t rx_usf;
1349 timer T_3141 := 1.0;
1350 var boolean ul_tbf_usf_req := false;
1351
1352 /* Initialize NS/BSSGP side */
1353 f_init_bssgp();
1354 /* Initialize GPRS MS side */
1355 f_init_gprs_ms();
1356 ms := g_ms[0]; /* We only use first MS in this test */
1357
1358 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1359 /* Only use 1 PDCH to simplify test: */
1360 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1361 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1362 /* Initialize the PCU interface abstraction */
1363 f_init_raw(testcasename(), info_ind);
1364
1365 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1366
1367 /* Establish BSSGP connection to the PCU */
1368 f_bssgp_establish();
1369 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1370
1371 /* Establish a one-phase access Uplink TBF */
1372 f_ms_establish_ul_tbf(ms);
1373
1374 T_3141.start;
1375
1376 /* Now we wait for PCU to transmit our USF */
1377 nr := ts_TsTrxBtsNum;
1378 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1379 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1380 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1381 block_nr := nr.blk_nr));
1382
1383 alt {
1384 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1385 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1386 ?)) -> value data_msg {
1387 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1388 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1389 f_shutdown(__BFILE__, __LINE__);
1390 }
1391
1392 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1393 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1394 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1395 ul_tbf_usf_req := true;
1396 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))
1397 } else if (rx_usf == USF_UNUSED) {
1398 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1399 if (ul_tbf_usf_req) {
1400 /* TBF was dropped by T3141, success */
1401 setverdict(pass);
1402 break;
1403 } else {
1404 log("PCU never requested USF, unexpected");
1405 f_shutdown(__BFILE__, __LINE__);
1406 }
1407 } /* else: Keep waiting for TBF to be active by network */
1408 } else {
1409 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1410 f_shutdown(__BFILE__, __LINE__);
1411 }
1412
1413 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1414 if (match(data_msg.dl_block,
1415 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1416 tr_UlAckNackGprs(tlli := ?,
1417 acknack_desc := ?,
1418 rel99 := *))))
1419 {
1420 log("Received UL ACK/NACK with TLLI set");
1421 f_shutdown(__BFILE__, __LINE__);
1422 }
1423
1424 nr := ts_TsTrxBtsNum;
1425 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1426 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1427 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1428 block_nr := nr.blk_nr));
1429 repeat;
1430 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001431 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1432 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1433 omit)) {
1434 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1435 our last RTS.req because there's no longer any MS listening on
1436 the TS. */
1437 setverdict(pass);
1438 break;
1439 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001440 [] T_3141.timeout {
1441 log("T_3141 expired but TBF is still active, unexpected");
1442 f_shutdown(__BFILE__, __LINE__);
1443 }
1444 [] BTS.receive {
1445 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1446 * because we never sent the TLLI to the PCU */
1447 setverdict(fail, "Unexpected BTS message");
1448 f_shutdown(__BFILE__, __LINE__);
1449 }
1450 }
1451
1452 f_shutdown(__BFILE__, __LINE__, final := true);
1453}
1454
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001455/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1456 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1457 * T3169. See OS#5033 */
1458testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1459 var PCUIF_info_ind info_ind;
1460 var template (value) TsTrxBtsNum nr;
1461 var BTS_PDTCH_Block data_msg;
1462 var GprsMS ms;
1463 var uint3_t rx_usf;
1464 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1465 var integer n3101 := 0;
1466 timer T_3169 := 1.0;
1467
1468 /* Initialize NS/BSSGP side */
1469 f_init_bssgp();
1470 /* Initialize GPRS MS side */
1471 f_init_gprs_ms();
1472 ms := g_ms[0]; /* We only use first MS in this test */
1473
1474 /* Initialize the PCU interface abstraction */
1475 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1476 info_ind.n3101 := N3101_MAX;
1477 info_ind.t3169 := 1;
1478 f_init_raw(testcasename(), info_ind);
1479
1480 /* Establish BSSGP connection to the PCU */
1481 f_bssgp_establish();
1482 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1483
1484 /* Establish UL TBF */
1485 f_ms_establish_ul_tbf(ms);
1486
1487 /* Now we wait for PCU to transmit our USF */
1488 nr := ts_TsTrxBtsNum;
1489 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1490 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1491 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1492 block_nr := nr.blk_nr));
1493
1494 alt {
1495 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1496 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1497 ?)) -> value data_msg {
1498 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1499 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1500 f_shutdown(__BFILE__, __LINE__);
1501 }
1502
1503 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1504 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1505 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1506 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001507 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1508 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001509 f_shutdown(__BFILE__, __LINE__);
1510 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001511 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001512 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1513 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1514 if (not T_3169.running) {
1515 log("T3169 started");
1516 T_3169.start;
1517 }
1518 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1519 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1520 f_shutdown(__BFILE__, __LINE__);
1521 } else {
1522 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1523 }
1524 nr := ts_TsTrxBtsNum;
1525 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1526 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1527 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1528 block_nr := nr.blk_nr));
1529 repeat;
1530 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001531 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1532 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001533 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001534 [] T_3169.timeout {
1535 log("T_3169 expired");
1536 /* Done in alt */
1537 }
1538 [] BTS.receive {
1539 setverdict(fail, "Unexpected BTS message");
1540 f_shutdown(__BFILE__, __LINE__);
1541 }
1542 }
1543
1544 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1545 /* USFs as per previous TBF since they were freed at expiration time: */
1546 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1547 var uint5_t old_tfi := ms.ul_tbf.tfi;
1548 f_ms_establish_ul_tbf(ms);
1549 if (old_tfi != ms.ul_tbf.tfi) {
1550 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1551 f_shutdown(__BFILE__, __LINE__);
1552 }
1553 for (var integer i := 0; i < 8; i := i +1) {
1554 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1555 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1556 f_shutdown(__BFILE__, __LINE__);
1557 }
1558 }
1559
1560 f_shutdown(__BFILE__, __LINE__, final := true);
1561}
1562
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001563
1564/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1565 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1566 the final UL ACK sent at us. */
1567testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1568 var PCUIF_info_ind info_ind;
1569 var BTS_PDTCH_Block data_msg;
1570 var RlcmacDlBlock dl_block;
1571 var uint32_t sched_fn;
1572 var template (value) TsTrxBtsNum nr;
1573 var template RlcmacDlBlock exp_ul_ack;
1574 var template UlAckNackGprs exp_ul_ack_sub;
1575 var GprsMS ms;
1576 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1577 var integer N3103 := 0;
1578 timer T_3169 := 1.0;
1579
1580 /* Initialize GPRS MS side */
1581 f_init_gprs_ms();
1582 ms := g_ms[0]; /* We only use first MS in this test */
1583
1584 /* Initialize the PCU interface abstraction */
1585 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1586 info_ind.n3103 := N3103_MAX;
1587 info_ind.t3169 := 1;
1588 f_init_raw(testcasename(), info_ind);
1589
1590 /* Establish an Uplink TBF */
1591 f_ms_establish_ul_tbf(ms);
1592
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001593 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001594 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1595 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1596
1597 nr := ts_TsTrxBtsNum;
1598 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1599 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1600 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1601 block_nr := nr.blk_nr));
1602 alt {
1603 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1604 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1605 exp_ul_ack)) -> value data_msg {
1606 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1607 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1608 f_shutdown(__BFILE__, __LINE__);
1609 }
1610
1611 nr := ts_TsTrxBtsNum;
1612 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1613 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1614 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1615 block_nr := nr.blk_nr));
1616 N3103 := N3103 + 1;
1617 if (N3103 == N3103_MAX) {
1618 /* At this point in time (N3103_MAX reached), PCU is
1619 * moving the TBF to RELEASE state so no data/ctrl for
1620 * it is tx'ed, hence the dummy blocks: */
1621 T_3169.start;
1622 }
1623 repeat;
1624 }
1625 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1626 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1627 exp_ul_ack)) -> value data_msg {
1628 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1629 f_shutdown(__BFILE__, __LINE__);
1630 }
1631 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001632 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001633 [T_3169.running] T_3169.timeout {
1634 log("T_3169 timeout");
1635 /* Done in alt, wait for pending RTS initiated previously in
1636 * above case before continuing (expect /* Dummy block): */
1637 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1638 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1639 tr_RLCMAC_DUMMY_CTRL));
1640 }
1641 [] BTS.receive {
1642 setverdict(fail, "Unexpected BTS message");
1643 f_shutdown(__BFILE__, __LINE__);
1644 }
1645 }
1646
1647 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1648 * USFs as per previous TBF since they were freed at expiration time: */
1649 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1650 var uint5_t old_tfi := ms.ul_tbf.tfi;
1651 f_ms_establish_ul_tbf(ms);
1652 if (old_tfi != ms.ul_tbf.tfi) {
1653 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1654 f_shutdown(__BFILE__, __LINE__);
1655 }
1656 for (var integer i := 0; i < 8; i := i +1) {
1657 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1658 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1659 f_shutdown(__BFILE__, __LINE__);
1660 }
1661 }
1662
1663 f_shutdown(__BFILE__, __LINE__, final := true);
1664}
1665
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001666/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1667 * point the TBF is no longer available. In order to get to start of T3191, we
1668 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1669 * until TBF release procedure starts after draining DL queue. */
1670testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1671 var PCUIF_info_ind info_ind;
1672 var RlcmacDlBlock dl_block;
1673 var octetstring data1 := f_rnd_octstring(200);
1674 var octetstring data2 := f_rnd_octstring(10);
1675 var uint32_t dl_fn;
1676 var template (value) TsTrxBtsNum nr;
1677 var BTS_PDTCH_Block data_msg;
1678 var GprsMS ms;
1679
1680 /* Initialize NS/BSSGP side */
1681 f_init_bssgp();
1682 /* Initialize GPRS MS side */
1683 f_init_gprs_ms();
1684 ms := g_ms[0]; /* We only use first MS in this test */
1685
1686 /* Initialize the PCU interface abstraction */
1687 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1688 /* Set timer to 1 sec (default 5) to speedup test: */
1689 info_ind.t3191 := 1;
1690 f_init_raw(testcasename(), info_ind);
1691
1692 /* Establish BSSGP connection to the PCU */
1693 f_bssgp_establish();
1694 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1695
1696 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1697 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1698 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1699
1700 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1701 f_sleep(X2002);
1702
1703 while (true) {
1704 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1705
1706 /* Keep Ack/Nack description updated (except for last BSN) */
1707 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1708
1709 if (f_dl_block_rrbp_valid(dl_block)) {
1710 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1711 f_dl_block_ack_fn(dl_block, dl_fn));
1712 break;
1713 }
1714 }
1715
1716 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1717 nr := ts_TsTrxBtsNum;
1718 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1719 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1720 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1721 block_nr := nr.blk_nr));
1722 alt {
1723 [] as_ms_rx_ignore_dummy(ms, nr);
1724 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1725 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1726 ?)) -> value data_msg {
1727 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1728 log("Received FINAL_ACK");
1729 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1730 break;
1731 }
1732 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1733 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1734 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1735 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1736 }
1737 nr := ts_TsTrxBtsNum;
1738 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1739 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1740 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1741 block_nr := nr.blk_nr));
1742 repeat;
1743 }
1744 [] BTS.receive {
1745 setverdict(fail, "Unexpected BTS message");
1746 f_shutdown(__BFILE__, __LINE__);
1747 }
1748 }
1749
1750 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1751 to time out. We simply sleep instead of requesting blocks because
1752 otherwise retransmissions would keep restarting the timer. */
1753 f_sleep(int2float(info_ind.t3191));
1754
1755 /* The TBF should be freed now, so new data should trigger an Assignment: */
1756 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1757 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1758
1759 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1760 f_sleep(X2002);
1761 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1762 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1763 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1764 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1765 f_dl_block_ack_fn(dl_block, dl_fn));
1766
1767 f_shutdown(__BFILE__, __LINE__, final := true);
1768}
1769
1770/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1771testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1772 var PCUIF_info_ind info_ind;
1773 var RlcmacDlBlock dl_block;
1774 var octetstring data1 := f_rnd_octstring(1400);
1775 var octetstring data2 := f_rnd_octstring(10);
1776 var uint32_t dl_fn;
1777 var GprsMS ms;
1778
1779 /* Initialize NS/BSSGP side */
1780 f_init_bssgp();
1781 /* Initialize GPRS MS side */
1782 f_init_gprs_ms();
1783 ms := g_ms[0]; /* We only use first MS in this test */
1784
1785 /* Initialize the PCU interface abstraction */
1786 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1787 /* Set timer to 1 sec (default 5) to speedup test: */
1788 info_ind.t3191 := 1;
1789 f_init_raw(testcasename(), info_ind);
1790
1791 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1792
1793 /* Establish BSSGP connection to the PCU */
1794 f_bssgp_establish();
1795 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1796
1797 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1798 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1799 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1800
1801 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1802 f_sleep(X2002);
1803
1804 /* Send enough DL data to at least be able to DL ACK once (excl the
1805 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1806 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1807 while (true) {
1808 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1809
1810 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1811 log("Received FINAL_ACK");
1812 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1813 break;
1814 }
1815
1816 /* Keep Ack/Nack description updated (except for last BSN) */
1817 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1818
1819 if (f_dl_block_rrbp_valid(dl_block)) {
1820 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1821 f_dl_block_ack_fn(dl_block, dl_fn));
1822 }
1823 }
1824
1825 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1826 to time out. We simply sleep instead of requesting blocks because
1827 otherwise retransmissions would keep restarting the timer. */
1828 f_sleep(int2float(info_ind.t3191));
1829
1830 /* The TBF should be freed now, so new data should trigger an Assignment: */
1831 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1832 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1833
1834 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1835 f_sleep(X2002);
1836 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1837 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1838 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1839 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1840 f_dl_block_ack_fn(dl_block, dl_fn));
1841
1842 f_shutdown(__BFILE__, __LINE__, final := true);
1843}
1844
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001845/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1846 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1847 * T3193) after DL TBF release */
1848testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001849 var RlcmacDlBlock dl_block;
1850 var octetstring data := f_rnd_octstring(10);
1851 var boolean ok;
1852 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001853 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001854 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001855 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1856
1857 /* Initialize NS/BSSGP side */
1858 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001859 /* Initialize GPRS MS side */
1860 f_init_gprs_ms();
1861 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001862
1863 /* Initialize the PCU interface abstraction */
1864 f_init_raw(testcasename());
1865
1866 /* Establish BSSGP connection to the PCU */
1867 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001868 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001869
1870 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001871 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1872 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001873
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001874 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1875 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001876 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001877
1878 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001879 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1880 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1881 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001882
1883 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001884 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001885 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001886 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001887 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001888
1889 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001890
1891 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001892 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001893 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1894 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1895 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001896
1897 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001898}
1899
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001900/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1901 freed and no longer available. Trigger it by sending DL blocks and never DL
1902 ACKing the data (which are requested through RRBP) */
1903testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1904 var PCUIF_info_ind info_ind;
1905 var RlcmacDlBlock dl_block;
1906 var octetstring data1 := f_rnd_octstring(1000);
1907 var octetstring data2 := f_rnd_octstring(10);
1908 var uint32_t dl_fn;
1909 var template (value) TsTrxBtsNum nr;
1910 var BTS_PDTCH_Block data_msg;
1911 var GprsMS ms;
1912 const integer N3105_MAX := 2;
1913 var integer N3105 := 0;
1914 timer T_3195 := 1.0;
1915 var integer num_poll_recv := 0;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001916 var template RlcmacDlBlock dl_block_exp;
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001917
1918 /* Initialize NS/BSSGP side */
1919 f_init_bssgp();
1920 /* Initialize GPRS MS side */
1921 f_init_gprs_ms();
1922 ms := g_ms[0]; /* We only use first MS in this test */
1923
1924 /* Initialize the PCU interface abstraction */
1925 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1926 /* Speedup test: */
1927 info_ind.n3105 := N3105_MAX;
1928 info_ind.t3195 := 1;
1929 f_init_raw(testcasename(), info_ind);
1930
1931 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1932 * MS and retransmitted after the TBF is released and later on created
1933 * (because the MS is reused) */
1934 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1935
1936 /* Establish BSSGP connection to the PCU */
1937 f_bssgp_establish();
1938 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1939
1940 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1941 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1942 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1943
1944 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1945 f_sleep(X2002);
1946
1947 /* Now we go on receiving DL data and not answering RRBP: */
1948 nr := ts_TsTrxBtsNum;
1949 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1950 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1951 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1952 block_nr := nr.blk_nr));
1953 alt {
1954 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1955 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1956 tr_RLCMAC_DATA)) -> value data_msg {
1957 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1958 if (num_poll_recv == 0) {
1959 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1960 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1961 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1962 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1963 } else {
1964 log("Ignoring RRBP ", num_poll_recv);
1965 N3105 := N3105 + 1;
1966 }
1967 num_poll_recv := num_poll_recv + 1;
1968 }
1969
1970 nr := ts_TsTrxBtsNum;
1971 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1972 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1973 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1974 block_nr := nr.blk_nr));
1975 repeat;
1976 }
1977 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001978 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001979 */
1980 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1981 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1982 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
1983 if (not T_3195.running) {
1984 T_3195.start;
1985 /* We even send some new data, nothing should be sent to MS */
1986 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1987 }
1988 nr := ts_TsTrxBtsNum;
1989 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1990 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1991 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1992 block_nr := nr.blk_nr));
1993 repeat;
1994 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01001995 /* We may already receive idle blocks before our own TTCN3 timer
1996 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001997 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02001998 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001999 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002000 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002001 * above case before continuing (expect empty block): */
2002 dl_block_exp := omit;
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002003 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2004 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002005 dl_block_exp));
2006 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002007 [] BTS.receive {
2008 setverdict(fail, "Unexpected BTS message");
2009 f_shutdown(__BFILE__, __LINE__);
2010 }
2011 }
2012
2013 /* after T_3195 timeout, TBF is released */
2014 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
2015 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2016
2017 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2018 f_sleep(X2002);
2019 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2020
2021 /* ACK the DL block */
2022 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2023 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2024 f_dl_block_ack_fn(dl_block, dl_fn));
2025
2026 f_shutdown(__BFILE__, __LINE__, final := true);
2027}
2028
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002029/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2030function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2031 var PCUIF_info_ind info_ind;
2032 var template IARRestOctets rest;
2033 var BIT11 ra11;
2034 var GprsMS ms;
2035 var octetstring data := f_rnd_octstring(10);
2036 var RlcmacDlBlock dl_block;
2037 var template RlcmacDlBlock rej_tmpl;
2038 var uint32_t dl_fn;
2039 var uint32_t sched_fn;
2040 var uint8_t wait_ind_val;
2041
2042 /* Initialize NS/BSSGP side */
2043 f_init_bssgp();
2044 /* Initialize GPRS MS side */
2045 f_init_gprs_ms();
2046 ms := g_ms[0]; /* We only use first MS in this test */
2047
2048 info_ind := valueof(ts_PCUIF_INFO_default);
2049
2050 /* Only the first TRX is enabled. */
2051 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2052 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2053
2054 /* Initialize the PCU interface abstraction */
2055 f_init_raw(testcasename(), info_ind);
2056
2057 f_pcuvty_set_timer(3172, t3172_ms);
2058
2059 /* Establish BSSGP connection to the PCU */
2060 f_bssgp_establish();
2061 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2062
2063 var EGPRSPktChRequest req := {
2064 one_phase := {
2065 tag := '0'B,
2066 multislot_class := '10101'B,
2067 priority := '01'B,
2068 random_bits := '101'B
2069 }
2070 };
2071
2072 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2073 for (var integer i := 0; i < 7; i := i + 1) {
2074 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2075 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2076 }
2077
2078 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2079 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2080 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2081
2082 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2083 f_sleep(X2002);
2084 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2085
2086 /* ACK the DL block */
2087 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2088 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2089 f_dl_block_ack_fn(dl_block, dl_fn));
2090
2091 /* Since all USF are taken, we should receive a Reject: */
2092
2093 if (wait_ind_size == '0'B) {
2094 wait_ind_val := t3172_ms / 1000;
2095 } else {
2096 wait_ind_val := t3172_ms / 20;
2097 }
2098 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2099 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2100 wait_ind_val,
2101 wait_ind_size)));
2102 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2103 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2104 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2105 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2106 block_nr := nr.blk_nr));
2107 alt {
2108 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2109 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2110 rej_tmpl));
2111 [] BTS.receive {
2112 setverdict(fail, "Unexpected BTS message");
2113 f_shutdown(__BFILE__, __LINE__);
2114 }
2115 }
2116 f_shutdown(__BFILE__, __LINE__, final := true);
2117}
2118testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2119 /* size=0 means value is provided in seconds. Due to value being 8
2120 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2121 * = 5100. Hence, values above it should use size=0 to be able to
2122 * provide values in range. Let's use 6 seconds, 6000ms
2123 */
2124 f_TC_t3172(6000, '0'B);
2125}
2126testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2127 f_TC_t3172(3000, '1'B);
2128}
2129
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002130/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2131testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002132 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002133 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002134 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002135 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002136
2137 /* Initialize NS/BSSGP side */
2138 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002139 /* Initialize GPRS MS side */
2140 f_init_gprs_ms();
2141 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002142
2143 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002144 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002145
2146 /* Establish BSSGP connection to the PCU */
2147 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002148 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002149
2150 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002151 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002152
2153 /* Send one UL block (with TLLI since we are in One-Phase Access
2154 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002155 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002156 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002157 f_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002158 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2159 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002160 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002161
2162 /* Send enough blocks to test whole procedure: Until Nth block
2163 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2164 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002165 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002166 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2167 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002168 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002169
2170 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002171 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002172
2173 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002174}
2175
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002176/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2177testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2178 var RlcmacDlBlock dl_block;
2179 var uint32_t dl_fn, sched_fn;
2180 var octetstring payload;
2181 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002182 var template (value) LlcBlockHdr blk_hdr;
2183 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002184 var integer blk_len;
2185 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002186 var GprsMS ms;
2187
2188 /* Initialize NS/BSSGP side */
2189 f_init_bssgp();
2190 /* Initialize GPRS MS side */
2191 f_init_gprs_ms();
2192 ms := g_ms[0]; /* We only use first MS in this test */
2193
2194 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002195 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002196
2197 /* Establish BSSGP connection to the PCU */
2198 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002199 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002200
2201 /* Establish an Uplink TBF */
2202 f_ms_establish_ul_tbf(ms);
2203
2204 /* Send one UL block (with TLLI since we are in One-Phase Access
2205 contention resoultion) and make sure it is ACKED fine. */
2206 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002207 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2208 more := false, e := true);
2209 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002210 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002211 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2212 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002213 cv := 15,
2214 bsn := ms.ul_tbf.bsn,
2215 blocks := blocks,
2216 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002217 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002218 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002219
2220 /* ACK and check it was received fine */
2221 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2222 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2223 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2224 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002225 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002226
2227 /* Test sending LLC PDUS of incrementing size */
2228 var integer max_size := 49;
2229 for (var integer i := 1; i <= max_size; i := i + 1) {
2230 var integer cv;
2231 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2232 log("Sending DATA.ind with LLC payload size ", i);
2233 if (i < max_size - g_bs_cv_max) {
2234 cv := 15;
2235 } else {
2236 cv := max_size - i;
2237 }
2238
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002239 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2240 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002241 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002242 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2243 more := false, e := true);
2244 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002245 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002246 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2247 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002248 cv := cv,
2249 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002250 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002251 f_ultbf_inc_bsn(ms.ul_tbf);
2252 f_ms_tx_ul_block(ms, ul_data);
2253
2254 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002255 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, payload));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002256
2257 /* we will receive UL ACK/NACK from time to time, handle it. */
2258 f_rx_rlcmac_dl_block(dl_block, dl_fn);
2259 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
2260 continue;
2261 }
2262 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2263 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2264 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2265 f_shutdown(__BFILE__, __LINE__);
2266 }
2267
2268 log("Rx Packet Uplink ACK / NACK");
2269 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2270 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2271 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2272 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002273
2274 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002275}
2276
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002277function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2278 var octetstring payload;
2279 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002280 var template (value) LlcBlockHdr blk_hdr;
2281 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002282 var integer block_len, max_valid_data_len;
2283 timer T;
2284
2285 block_len := f_rlcmac_cs_mcs2block_len(cs);
2286 /* We need to send with TLLI since we are in One-Phase Access Contenion
2287 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
2288 * indicator, -1 for spare bits octet at the end */
2289 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2290 payload := f_rnd_octstring(max_valid_data_len + 1); /* +1 to write LLC data on last padding octet */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002291 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2292 more := false, e := true);
2293 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002294 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2295 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002296 cv := cv,
2297 bsn := ms.ul_tbf.bsn,
2298 blocks := blocks,
2299 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002300 f_ultbf_inc_bsn(ms.ul_tbf);
2301 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2302
2303 T.start(0.5);
2304 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002305 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002306 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2307 f_shutdown(__BFILE__, __LINE__);
2308 }
2309 [] T.timeout {
2310 setverdict(pass);
2311 }
2312 }
2313}
2314/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2315 blocks intentionally contain last byte of data placed in last byte of RLC
2316 containing padding/spare bits, which is incorrect. Spare bits exist and are
2317 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2318 discounting padding in octet" */
2319testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2320 var GprsMS ms;
2321 var integer block_len, max_valid_data_len;
2322
2323 /* Initialize NS/BSSGP side */
2324 f_init_bssgp();
2325 /* Initialize GPRS MS side */
2326 f_init_gprs_ms();
2327 ms := g_ms[0]; /* We only use first MS in this test */
2328
2329 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002330 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002331
2332 /* Establish BSSGP connection to the PCU */
2333 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002334 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002335
2336 /* Establish an Uplink TBF */
2337 f_ms_establish_ul_tbf(ms);
2338
2339 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2340 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2341 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2342
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002343 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002344}
2345
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002346/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2347 * answered, so TBFs for uplink and later for downlink are created.
2348 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002349private function f_TC_mo_ping_pong_1phase_access(template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002350 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002351 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002352 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002353 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002354 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002355
2356 /* Initialize NS/BSSGP side */
2357 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002358 /* Initialize GPRS MS side */
2359 f_init_gprs_ms();
2360 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002361
2362 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002363 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002364
2365 /* Establish BSSGP connection to the PCU */
2366 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002367 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002368
2369 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002370 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002371
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002372 /* Send one UL block (with TLLI since we are in One-Phase Access
2373 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002374 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002375 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2376 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002377 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002378
2379 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002380 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002381
2382 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002383 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2384 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002385
2386 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2387 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002388 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002389
2390 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002391 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2392 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2393 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002394
2395 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002396}
2397
2398/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2399 * answered, so TBFs for uplink and later for downlink are created.
2400 */
2401testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002402 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002403 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002404}
2405
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002406/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2407 * answered, so TBFs for uplink and later for downlink are created.
2408 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002409private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2410 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002411 template (present) CodingScheme exp_ul_cs_mcs := ?,
2412 template (present) CodingScheme exp_dl_cs_mcs := ?)
2413runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002414 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002415 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002416 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002417 var uint32_t sched_fn;
2418 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002419 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002420 var GprsMS ms;
2421
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002422 /* Initialize NS/BSSGP side */
2423 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002424 /* Initialize GPRS MS side */
2425 f_init_gprs_ms();
2426 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002427
2428 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002429 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002430
2431 /* Establish BSSGP connection to the PCU */
2432 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002433 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002434
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002435 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2436 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002437
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002438 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2439 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_cs_mcs);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002440 f_shutdown(__BFILE__, __LINE__);
2441 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002442
2443 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2444 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002445 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002446
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002447 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002448 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002449
2450 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002451 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002452
2453 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002454 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002455 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2456 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002457 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002458 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002459 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002460
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002461 /* PCU acks the UL data after having received CV=0) */
2462 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2463
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002464 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002465 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_dl_cs_mcs);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002466
2467 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002468 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2469 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs)),
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002470 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002471
2472 f_shutdown(__BFILE__, __LINE__, final := true);
2473}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002474
2475testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002476 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2477 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002478
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002479 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01002480
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002481 var StatsDExpects expect := {
2482 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2483 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2484 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2485 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2486 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2487 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2488 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2489 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2490 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2491 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2492 };
2493 f_statsd_expect(expect);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002494}
2495
2496testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002497 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2498 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002499
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002500 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_default, ms_racap_egprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002501
2502 var StatsDExpects expect := {
2503 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2504 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2505 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2506 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2507 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2508 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2509 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2510 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2511 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2512 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2513 };
2514 f_statsd_expect(expect);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002515}
2516
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002517testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2518 /* Configure PCU to force two phase access */
2519 g_force_two_phase_access := true;
2520
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002521 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002522 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002523
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002524 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01002525
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002526 var StatsDExpects expect := {
2527 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2528 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2529 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2530 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2531 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2532 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2533 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2534 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2535 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2536 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2537 };
2538 f_statsd_expect(expect);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002539}
2540
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002541/* Test scenario where SGSN wants to send some data against MS and it is
2542 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2543 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002544private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2545 template (present) CodingScheme exp_cs_mcs := ?)
2546runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002547 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002548 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002549 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002550 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002551 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002552
2553 /* Initialize NS/BSSGP side */
2554 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002555 /* Initialize GPRS MS side */
2556 f_init_gprs_ms();
2557 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002558
2559 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002560 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002561
2562 /* Establish BSSGP connection to the PCU */
2563 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002564 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002565
2566 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002567 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2568 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002569
2570 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2571 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002572 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002573
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002574 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002575 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2576 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, ischosen(dl_block.data_egprs), c_ChReqDesc_default),
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002577 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002578
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002579 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002580 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002581
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002582 /* Send one UL block (with TLLI since we are in One-Phase Access
2583 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002584 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002585 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2586 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002587 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002588
2589 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002590 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002591
2592 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002593}
2594
2595testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002596 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002597 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2598}
2599
2600/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2601/* information about the MS */
2602testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002603 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002604 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002605}
2606
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002607/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2608 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2609 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2610 * be transferred).
2611 */
2612testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002613 var RlcmacDlBlock dl_block;
2614 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002615 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002616 var octetstring total_payload;
2617 var octetstring payload;
2618 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002619 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002620 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002621 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002622
2623 /* Initialize NS/BSSGP side */
2624 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002625 /* Initialize GPRS MS side */
2626 f_init_gprs_ms();
2627 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002628
2629 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002630 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002631
2632 /* Establish BSSGP connection to the PCU */
2633 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002634 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002635
2636 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002637 f_ms_establish_ul_tbf(ms);
2638 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002639
2640 /* Send one UL block (with TLLI since we are in One-Phase Access
2641 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002642 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true)); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002643 f_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002644
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002645 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2646 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002647 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002648 total_payload := payload;
2649
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002650 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2651
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002652 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002653 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002654 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002655 total_payload := total_payload & payload;
2656
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002657 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002658 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002659 total_payload := total_payload & payload;
2660
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002661 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002662 ms.ul_tbf.bsn := ms.ul_tbf.bsn + 1; /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002663 total_payload := total_payload & lost_payload;
2664
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002665 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002666 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002667 total_payload := total_payload & payload;
2668
2669 /* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002670 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002671
2672 /* On CV=0, we'll receive a UL ACK asking about missing block */
2673 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2674 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002675 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2676 tfi := tfi,
2677 cv := 15,
2678 bsn := 3,
2679 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002680 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002681
2682 /* Now final ack is recieved */
2683 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2684 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002685 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002686
2687 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002688 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, total_payload));
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002689
2690 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002691}
2692
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002693/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2694 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2695 * timeout occurs (specified by sent RRBP on DL block). */
2696testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002697 var RlcmacDlBlock dl_block;
2698 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002699 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002700 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002701
2702 /* Initialize NS/BSSGP side */
2703 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002704 /* Initialize GPRS MS side */
2705 f_init_gprs_ms();
2706 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002707
2708 /* Initialize the PCU interface abstraction */
2709 f_init_raw(testcasename());
2710
2711 /* Establish BSSGP connection to the PCU */
2712 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002713 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002714
2715 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002716 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2717 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002718
2719 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2720 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002721 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002722
2723 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2724 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2725 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002726 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002727
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002728 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2729 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002730 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002731
2732 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002733 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2734 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2735 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002736
2737 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002738}
2739
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002740/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2741testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2742 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2743 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002744 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002745 var RlcmacDlBlock dl_block;
2746 var uint32_t ack_fn;
2747 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002748 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002749 timer T := 5.0;
2750
2751 /* Initialize NS/BSSGP side */
2752 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002753 /* Initialize GPRS MS side */
2754 f_init_gprs_ms();
2755 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002756
2757 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002758 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002759
Daniel Willmann535aea62020-09-21 13:27:08 +02002760 f_statsd_reset();
2761
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002762 /* Establish BSSGP connection to the PCU */
2763 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002764 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002765
2766 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002767 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2768 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002769
2770 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2771 f_sleep(X2002);
2772
2773 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2774 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002775 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002776
2777 /* TDMA frame number on which we are supposed to send the ACK */
2778 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2779
2780 /* SGSN sends more blocks during the indicated RRBP */
2781 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2782 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002783 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002784
2785 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2786
2787 /* Make sure this block has the same TFI as was assigned
2788 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002789 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002790 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2791 dl_block.data.mac_hdr.hdr_ext.tfi);
2792 f_shutdown(__BFILE__, __LINE__);
2793 }
2794
2795 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002796 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002797
2798 /* Break if this is the end of RRBP */
2799 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002800 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002801 break;
2802 }
2803 }
2804
2805 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002806 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc), fn := fn);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002807
2808 /* Make sure that the next block (after the Ack) is dummy */
2809 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2810
Daniel Willmann535aea62020-09-21 13:27:08 +02002811 var StatsDExpects expect := {
2812 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2813 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2814 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2815 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2816 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002817 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002818 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2819 };
2820 f_statsd_expect(expect);
2821
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002822 f_shutdown(__BFILE__, __LINE__, final := true);
2823}
2824
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002825/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2826 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2827 * Check "3GPP TS 44.060" Annex B. */
2828testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2829 var RlcmacDlBlock dl_block;
2830 var octetstring dataA := f_rnd_octstring(20);
2831 var octetstring dataB := f_rnd_octstring(13);
2832 var octetstring dataC := f_rnd_octstring(3);
2833 var octetstring dataD := f_rnd_octstring(12);
2834 var uint32_t sched_fn;
2835 var GprsMS ms;
2836 var template (value) RlcmacUlBlock ul_data;
2837
2838 /* Initialize NS/BSSGP side */
2839 f_init_bssgp();
2840 /* Initialize GPRS MS side */
2841 f_init_gprs_ms();
2842 ms := g_ms[0]; /* We only use first MS in this test */
2843
2844 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002845 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002846
2847 /* Establish BSSGP connection to the PCU */
2848 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002849 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002850
2851 /* Establish an Uplink TBF */
2852 f_ms_establish_ul_tbf(ms);
2853
2854 /* Summary of what's transmitted:
2855 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2856 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2857 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2858 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2859 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2860 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2861 */
2862
2863 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002864 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2865 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002866 cv := 3,
2867 bsn := ms.ul_tbf.bsn,
2868 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2869 tlli := ms.tlli);
2870 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2871 * RLCMAC block being sent. */
2872 ul_data.data.mac_hdr.e := true;
2873 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002874 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002875
2876 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002877 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2878 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002879 cv := 2,
2880 bsn := ms.ul_tbf.bsn,
2881 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2882 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2883 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2884 },
2885 tlli := ms.tlli);
2886 f_ultbf_inc_bsn(ms.ul_tbf);
2887 f_ms_tx_ul_block(ms, ul_data);
2888
2889 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002890 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataA));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002891
2892 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002893 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2894 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002895 cv := 1,
2896 bsn := ms.ul_tbf.bsn,
2897 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2898 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2899 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2900 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2901 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2902 },
2903 tlli := ms.tlli);
2904 f_ultbf_inc_bsn(ms.ul_tbf);
2905 f_ms_tx_ul_block(ms, ul_data);
2906
2907 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002908 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2909 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataC));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002910
2911 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002912 ul_data := t_RLCMAC_UL_DATA_TLLI(
2913 cs := CS_1,
2914 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002915 cv := 0,
2916 bsn := ms.ul_tbf.bsn,
2917 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2918 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2919 },
2920 tlli := ms.tlli);
2921 f_ultbf_inc_bsn(ms.ul_tbf);
2922 f_ms_tx_ul_block(ms, ul_data);
2923
2924 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002925 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataD));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002926
2927 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2928 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2929 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2930
2931 f_shutdown(__BFILE__, __LINE__, final := true);
2932}
2933
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002934/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2935 * ACK/NACK is not answered */
2936testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2937 var RlcmacDlBlock dl_block;
2938 var octetstring data1 := f_rnd_octstring(200);
2939 var octetstring data2 := f_rnd_octstring(10);
2940 var uint32_t dl_fn;
2941 var GprsMS ms;
2942 var template (value) TsTrxBtsNum nr;
2943 var BTS_PDTCH_Block data_msg;
2944
2945 /* Initialize NS/BSSGP side */
2946 f_init_bssgp();
2947 /* Initialize GPRS MS side */
2948 f_init_gprs_ms();
2949 ms := g_ms[0]; /* We only use first MS in this test */
2950
2951 /* Initialize the PCU interface abstraction */
2952 f_init_raw(testcasename())
2953
2954 /* Establish BSSGP connection to the PCU */
2955 f_bssgp_establish();
2956 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2957
2958 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2959 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2960 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2961
2962 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2963 f_sleep(X2002);
2964
2965 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2966 while (true) {
2967 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2968
2969 /* Keep Ack/Nack description updated (except for last BSN) */
2970 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2971
2972 if (f_dl_block_rrbp_valid(dl_block)) {
2973 /* Don't transmit DL ACK here on purpose ignore it */
2974 break;
2975 }
2976 }
2977
2978 /* PCU starts whole process again */
2979 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2980
2981 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2982 f_sleep(X2002);
2983
2984 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
2985 /* DL data), after that we receive only DUMMY blocks so we are done */
2986 var boolean data_received := false;
2987 nr := ts_TsTrxBtsNum;
2988 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2989 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2990 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2991 block_nr := nr.blk_nr));
2992 alt {
2993 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2994 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2995 tr_RLCMAC_DUMMY_CTRL)) { /* done */ }
2996 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2997 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2998 tr_RLCMAC_DATA)) -> value data_msg {
2999 data_received := true;
3000 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3001 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3002 log("Received FINAL_ACK");
3003 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3004 }
3005 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3006 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3007 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3008 }
3009 nr := ts_TsTrxBtsNum;
3010 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3011 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3012 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3013 block_nr := nr.blk_nr));
3014 repeat;
3015 }
3016 [] BTS.receive {
3017 setverdict(fail, "Unexpected BTS message");
3018 f_shutdown(__BFILE__, __LINE__);
3019 }
3020 }
3021
3022 f_shutdown(__BFILE__, __LINE__, final := true);
3023}
3024
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003025/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3026testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003027 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003028 var octetstring data := f_rnd_octstring(10);
3029 var PacketDlAssign dl_tbf_ass;
3030 var RlcmacDlBlock dl_block;
3031 var uint32_t poll_fn;
3032 var uint32_t sched_fn;
3033 var GprsMS ms;
3034 timer T := 5.0;
3035
3036 /* Initialize NS/BSSGP side */
3037 f_init_bssgp();
3038 /* Initialize GPRS MS side */
3039 f_init_gprs_ms();
3040 ms := g_ms[0]; /* We only use first MS in this test */
3041
3042 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003043 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3044 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003045
3046 /* Initialize the PCU interface abstraction */
3047 f_init_raw(testcasename(), info_ind);
3048
3049 /* Establish BSSGP connection to the PCU */
3050 f_bssgp_establish();
3051 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3052
3053 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3054 through PDCH (no multiblock assignment possible through PCH) */
3055 f_ms_establish_ul_tbf(ms);
3056
3057 /* Send one UL block (with TLLI since we are in One-Phase Access
3058 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003059 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
3060 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003061 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3062 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3063
3064 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3065 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3066 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3067 gprsextendeddynalloccap := '0'B
3068 };
3069 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3070 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3071 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3072 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3073 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3074 f_shutdown(__BFILE__, __LINE__);
3075 }
3076 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3077
3078 f_shutdown(__BFILE__, __LINE__, final := true);
3079}
3080
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003081testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003082 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003083 var RlcmacDlBlock dl_block;
3084 var octetstring data := f_rnd_octstring(10);
3085 var PollFnCtx pollctx;
3086 var uint32_t sched_fn;
3087 var GprsMS ms;
3088
3089 var MultislotCap_GPRS mscap_gprs := {
3090 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3091 gprsextendeddynalloccap := '0'B
3092 };
3093 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3094
3095
3096 /* Initialize NS/BSSGP side */
3097 f_init_bssgp();
3098 /* Initialize GPRS MS side */
3099 f_init_gprs_ms();
3100 ms := g_ms[0]; /* We only use first MS in this test */
3101
3102 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003103 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3104 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003105
3106 /* Initialize the PCU interface abstraction */
3107 f_init_raw(testcasename(), info_ind);
3108
3109 /* Establish BSSGP connection to the PCU */
3110 f_bssgp_establish();
3111 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3112
3113 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3114 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3115
3116 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3117 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3118
3119 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3120 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3121 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3122 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3123 f_shutdown(__BFILE__, __LINE__);
3124 }
3125 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3126
3127 f_shutdown(__BFILE__, __LINE__, final := true);
3128}
3129
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003130testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3131 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3132 var RlcmacDlBlock dl_block;
3133 var octetstring data := f_rnd_octstring(10);
3134 var PollFnCtx pollctx;
3135 var uint32_t sched_fn;
3136 var GprsMS ms;
3137
3138 var MultislotCap_GPRS mscap_gprs := {
3139 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3140 gprsextendeddynalloccap := '0'B
3141 };
3142 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3143
3144
3145 /* Initialize NS/BSSGP side */
3146 f_init_bssgp();
3147 /* Initialize GPRS MS side */
3148 f_init_gprs_ms();
3149 ms := g_ms[0]; /* We only use first MS in this test */
3150
3151 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003152 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3153 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003154
3155 /* Initialize the PCU interface abstraction */
3156 f_init_raw(testcasename(), info_ind);
3157
3158 /* Establish BSSGP connection to the PCU */
3159 f_bssgp_establish();
3160 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3161
3162 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3163 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3164
3165 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3166 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3167 f_shutdown(__BFILE__, __LINE__);
3168 }
3169
3170 f_shutdown(__BFILE__, __LINE__, final := true);
3171}
3172
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003173/* Test scenario where MS wants to request a new TBF once the current one is
3174 * ending, by means of sending a Packet Resource Request on ul slot provided by
3175 * last Pkt Ul ACK's RRBP.
3176 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3177testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003178 var RlcmacDlBlock dl_block;
3179 var octetstring data := f_rnd_octstring(10);
3180 var uint32_t sched_fn;
3181 var uint32_t dl_fn;
3182 var template RlcmacDlBlock acknack_tmpl;
3183 var GprsMS ms;
3184
3185 /* Initialize NS/BSSGP side */
3186 f_init_bssgp();
3187 /* Initialize GPRS MS side */
3188 f_init_gprs_ms();
3189 ms := g_ms[0]; /* We only use first MS in this test */
3190
3191 /* Initialize the PCU interface abstraction */
3192 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003193 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003194
3195 /* Establish BSSGP connection to the PCU */
3196 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003197 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003198
3199 /* Establish an Uplink TBF */
3200 f_ms_establish_ul_tbf(ms);
3201
3202 /* Send one UL block (with TLLI since we are in One-Phase Access
3203 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003204 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003205
3206 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003207 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003208
3209 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3210 tr_UlAckNackGprs(ms.tlli,
3211 tr_AckNackDescription(final_ack := '1'B),
3212 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3213 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3214
3215 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3216
3217 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003218 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07003219 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003220 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3221 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3222
3223 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3224 and make sure it is ACKED fine */
3225 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3226
3227 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003228 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003229
3230 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3231 /* ACK the ACK */
3232 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3233
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003234 var StatsDExpects expect := {
3235 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3236 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3237 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3238 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3239 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3240 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3241 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3242 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3243 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3244 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3245 };
3246 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003247
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003248 f_shutdown(__BFILE__, __LINE__, final := true);
3249}
3250
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003251/* Test scenario where MS wants to request a new TBF once the current one is
3252 * ending, by means of sending a Packet Resource Request on ul slot provided by
3253 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3254 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3255testcase TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() runs on RAW_PCU_Test_CT {
3256 var PCUIF_info_ind info_ind;
3257 var RlcmacDlBlock dl_block;
3258 var octetstring data := f_rnd_octstring(10);
3259 var uint32_t sched_fn;
3260 var uint32_t dl_fn;
3261 var template (value) TsTrxBtsNum nr;
3262 var BTS_PDTCH_Block data_msg;
3263 var template RlcmacDlBlock acknack_tmpl;
3264 var GprsMS ms;
3265 const integer N3105_MAX := 2;
3266 var integer N3105 := 0;
3267 timer T_3195 := 1.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
3268
3269 /* Initialize NS/BSSGP side */
3270 f_init_bssgp();
3271 /* Initialize GPRS MS side */
3272 f_init_gprs_ms();
3273 ms := g_ms[0]; /* We only use first MS in this test */
3274
3275 /* Initialize the PCU interface abstraction */
3276 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3277 /* Speedup test: */
3278 info_ind.n3105 := N3105_MAX;
3279 info_ind.t3195 := 1;
3280 f_init_raw(testcasename(), info_ind);
3281
3282 /* Establish BSSGP connection to the PCU */
3283 f_bssgp_establish();
3284 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3285
3286 /* Establish an Uplink TBF */
3287 f_ms_establish_ul_tbf(ms);
3288
3289 /* Send one UL block (with TLLI since we are in One-Phase Access
3290 contention resoultion) and make sure it is ACKED fine */
3291 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3292
3293 /* UL block should be received in SGSN */
3294 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3295
3296 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3297 tr_UlAckNackGprs(ms.tlli,
3298 tr_AckNackDescription(final_ack := '1'B),
3299 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3300 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3301
3302 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3303
3304 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
3305 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3306
3307 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3308 /* Now we go on receiving DL data and not answering RRBP: */
3309 nr := ts_TsTrxBtsNum;
3310 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3311 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3312 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3313 block_nr := nr.blk_nr));
3314 alt {
3315 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3316 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3317 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
3318 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3319 log("Ignoring RRBP N3105 ", N3105);
3320 N3105 := N3105 + 1;
3321 }
3322 nr := ts_TsTrxBtsNum;
3323 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3324 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3325 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3326 block_nr := nr.blk_nr));
3327 repeat;
3328 }
3329 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
3330 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
3331 */
3332 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3333 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3334 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3335 if (not T_3195.running) {
3336 T_3195.start;
3337 }
3338 nr := ts_TsTrxBtsNum;
3339 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3340 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3341 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3342 block_nr := nr.blk_nr));
3343 repeat;
3344 }
3345 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3346 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3347 omit)) -> value data_msg {
3348 /* We may already receive idle blocks before our own TTCN3 timer
3349 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
3350 nr := ts_TsTrxBtsNum;
3351 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3352 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3353 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3354 block_nr := nr.blk_nr));
3355 repeat;
3356 }
3357 /* We receive Dummy blocks in between Pkt Ul Ass while PCU waits for us to ack it */
3358 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3359 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3360 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3361 log("Ignoring Dummy block FN ", data_msg.raw.fn);
3362 nr := ts_TsTrxBtsNum;
3363 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3364 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3365 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3366 block_nr := nr.blk_nr));
3367 repeat;
3368 }
3369 [T_3195.running] T_3195.timeout {
3370 log("T_3195 timeout");
3371 /* Done in alt, wait for pending RTS initiated previously in
3372 * above case before continuing (expect nothing to be sent since there's no active TBF): */
3373 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3374 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3375 omit));
3376 }
3377 [] BTS.receive {
3378 setverdict(fail, "Unexpected BTS message");
3379 f_shutdown(__BFILE__, __LINE__);
3380 }
3381 }
3382
3383 f_shutdown(__BFILE__, __LINE__, final := true);
3384}
3385
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003386/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3387 * transmitted on ul slot provided by its DL TBF.
3388 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3389function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3390 var GprsMS ms;
3391 var octetstring data := f_rnd_octstring(10);
3392 var RlcmacDlBlock dl_block;
3393 var template RlcmacDlBlock rej_tmpl;
3394 var uint32_t dl_fn;
3395 var uint32_t sched_fn;
3396 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3397
3398 if (use_egprs == true) {
3399 racap_tmpl := bssgp_ms_racap_egprs_def;
3400 } else {
3401 racap_tmpl := bssgp_ms_racap_gprs_def;
3402 }
3403
3404 /* Initialize NS/BSSGP side */
3405 f_init_bssgp();
3406 /* Initialize GPRS MS side */
3407 f_init_gprs_ms();
3408 ms := g_ms[0]; /* We only use first MS in this test */
3409 /* Initialize the PCU interface abstraction */
3410 f_init_raw(testcasename());
3411
3412 /* Establish BSSGP connection to the PCU */
3413 f_bssgp_establish();
3414 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3415
3416 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3417 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3418 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3419
3420 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3421 f_sleep(X2002);
3422 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3423
3424 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3425 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3426 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3427 f_dl_block_ack_fn(dl_block, dl_fn));
3428
3429 /* We should receive a Pkt Ul ASS */
3430 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3431 f_shutdown(__BFILE__, __LINE__, final := true);
3432}
3433testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3434 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3435}
3436testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3437 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3438}
3439
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003440/* Test CS paging over the BTS<->PCU socket.
3441 * 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.
3442 * Paging should be send on the PACCH.
3443 *
3444 * 1. Send a Paging Request over PCU socket.
3445 * 2. Send a Ready-To-Send message over PCU socket
3446 * 3. Expect a Paging Frame
3447 */
3448testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003449 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003450 var MobileIdentityLV mi;
3451 var octetstring mi_enc_lv;
3452 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003453 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003454
3455 /* Initialize NS/BSSGP side */
3456 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003457 /* Initialize GPRS MS side */
3458 f_init_gprs_ms();
3459 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003460
3461 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003462 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003463
3464 /* Establish BSSGP connection to the PCU */
3465 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003466 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003467
3468 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003469 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003470
3471 /* build mobile Identity */
3472 mi := valueof(ts_MI_IMSI_LV(imsi));
3473 mi_enc_lv := enc_MobileIdentityLV(mi);
3474 /* Send paging request */
3475 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3476 sapi :=PCU_IF_SAPI_PDTCH));
3477
3478 /* Receive it on BTS side towards MS */
3479 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3480
3481 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003482 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3483 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3484 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3485 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003486
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003487 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003488}
3489
3490/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3491 */
3492private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3493runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003494 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003495 var hexstring imsi := f_gen_imsi(42);
3496 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003497 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003498
3499 /* Initialize NS/BSSGP side */
3500 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003501 /* Initialize GPRS MS side */
3502 f_init_gprs_ms();
3503 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003504
3505 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003506 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003507
3508 /* Establish BSSGP connection to the PCU */
3509 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003510 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003511
3512 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003513 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003514
3515 /* Send paging request with or without TMSI */
3516 if (use_ptmsi) {
3517 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3518 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3519 } else {
3520 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3521 }
3522
3523 /* Receive it on BTS side towards MS */
3524 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3525
3526 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003527 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003528 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003529 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3530 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3531 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003532 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003533 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3534 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3535 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003536 }
3537
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003538 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003539}
3540
3541testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3542 f_tc_paging_cs_from_sgsn(0, true);
3543}
3544
3545testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3546 f_tc_paging_cs_from_sgsn(0);
3547}
3548
3549testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003550 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003551}
3552
3553/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3554 */
3555private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3556runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003557 var integer imsi_suff_tx := 423;
3558 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003559 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003560
3561 /* Initialize NS/BSSGP side */
3562 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003563 /* Initialize GPRS MS side */
3564 f_init_gprs_ms();
3565 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003566
Oliver Smith61b4e732021-07-22 08:14:29 +02003567 f_statsd_reset();
3568
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003569 /* Establish BSSGP connection to the PCU */
3570 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003571 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003572
3573 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3574 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3575 if (use_ptmsi) {
3576 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3577 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3578 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3579 } else {
3580 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3581 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3582 }
3583
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003584 var StatsDExpects expect := {
3585 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3586 /* After the PCU receives the paging request from SGSN,
3587 * and it doesn't have any errors, PCU sends it to the
3588 * BTS to do paging over PCH. */
3589 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3590 };
3591 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003592}
3593
3594testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3595 /* Initialize the PCU interface abstraction */
3596 f_init_raw(testcasename());
3597
3598 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003599
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003600 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003601}
3602
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003603testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003604 /* Initialize the PCU interface abstraction */
3605 f_init_raw(testcasename());
3606
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003607 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003608
3609 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003610}
3611
3612testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003613 /* Initialize the PCU interface abstraction */
3614 f_init_raw(testcasename());
3615
Harald Welte5339b2e2020-10-04 22:52:56 +02003616 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003617
3618 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003619}
3620
Oliver Smithe1a77c42021-07-28 13:36:09 +02003621testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3622 /* Initialize the PCU interface abstraction */
3623 f_init_raw(testcasename());
3624
3625 /* Set T3113 to 1s to shorten the test duration */
3626 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3627
3628 /* Reset stats and send paging PS request */
3629 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3630
3631 /* Verify that counter increases when T3113 times out (MS did not start
3632 * TBF to respond to paging). */
3633 f_sleep(1.2);
3634 var StatsDExpects expect := {
3635 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3636 };
3637 f_statsd_expect(expect);
3638
3639 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3640 f_shutdown(__BFILE__, __LINE__, final := true);
3641}
3642
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003643/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3644testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3645 var RlcmacDlBlock dl_block;
3646 var octetstring data := f_rnd_octstring(10);
3647 var uint32_t sched_fn;
3648 var uint32_t dl_fn;
3649 var GprsMS ms;
3650
3651 /* Initialize NS/BSSGP side */
3652 f_init_bssgp();
3653 /* Initialize GPRS MS side */
3654 f_init_gprs_ms();
3655 ms := g_ms[0]; /* We only use first MS in this test */
3656
3657 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003658 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003659
Daniel Willmann535aea62020-09-21 13:27:08 +02003660 f_statsd_reset();
3661
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003662 /* Establish BSSGP connection to the PCU */
3663 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003664 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003665
3666 /* Establish an Uplink TBF */
3667 f_ms_establish_ul_tbf(ms);
3668
3669 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003670 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003671 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3672 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3673 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3674
3675 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003676 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003677
3678 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3679 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3680 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3681
3682 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3683 f_sleep(X2002);
3684 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3685
3686 /* ACK the DL block */
3687 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3688 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3689 f_dl_block_ack_fn(dl_block, dl_fn));
3690
Daniel Willmann535aea62020-09-21 13:27:08 +02003691 var StatsDExpects expect := {
3692 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3693 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3694 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3695 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003696 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003697 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003698 };
3699 f_statsd_expect(expect);
3700
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003701 f_shutdown(__BFILE__, __LINE__, final := true);
3702}
3703
3704/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3705testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3706 var RlcmacDlBlock dl_block;
3707 var octetstring data := f_rnd_octstring(10);
3708 var uint32_t sched_fn;
3709 var uint32_t dl_fn;
3710 var GprsMS ms;
3711
3712 /* Initialize NS/BSSGP side */
3713 f_init_bssgp();
3714 /* Initialize GPRS MS side */
3715 f_init_gprs_ms();
3716 ms := g_ms[0]; /* We only use first MS in this test */
3717
3718 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003719 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003720
3721 /* Establish BSSGP connection to the PCU */
3722 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003723 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003724
3725 /* Establish an Uplink TBF */
3726 f_ms_establish_ul_tbf(ms);
3727
3728 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003729 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003730 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3731 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3732 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3733
3734 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003735 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003736
3737 /* Now SGSN sends some DL data with an invalid IMSI */
3738 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3739
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003740 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003741
3742 /* TODO: make sure no data is sent over PCU -> MS */
3743
3744 f_shutdown(__BFILE__, __LINE__, final := true);
3745}
3746
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003747private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3748 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3749 var octetstring data := f_rnd_octstring(6);
3750 var RlcmacDlBlock dl_block;
3751 var GprsMS ms;
3752 var uint32_t fn;
3753
3754 /* Initialize NS/BSSGP side */
3755 f_init_bssgp();
3756 /* Initialize GPRS MS side */
3757 f_init_gprs_ms();
3758 ms := g_ms[0]; /* We only use first MS in this test */
3759
3760 /* Initialize the PCU interface abstraction */
3761 f_init_raw(testcasename());
3762
3763 /* Establish BSSGP connection to the PCU */
3764 f_bssgp_establish();
3765 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3766
3767 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3768 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3769 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3770
3771 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3772 f_sleep(X2002);
3773
3774 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3775 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3776
3777 if (ischosen(dl_block.data_egprs)) {
3778 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3779 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3780 f_shutdown(__BFILE__, __LINE__);
3781 }
3782 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3783 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3784 f_shutdown(__BFILE__, __LINE__);
3785 }
3786 if (not match(dl_block.data_egprs.blocks[1].payload,
3787 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3788 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3789 f_shutdown(__BFILE__, __LINE__);
3790 }
3791 } else if (lengthof(dl_block.data.blocks) > 1) {
3792 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3793 f_shutdown(__BFILE__, __LINE__);
3794 }
3795
3796 f_shutdown(__BFILE__, __LINE__, final := true);
3797}
3798
3799/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3800 * containing llc data. See OS#4849 */
3801testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3802 f_tc_dl_data_no_llc_ui_dummy(omit);
3803}
3804
3805/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3806 * containing llc data. See OS#4849 */
3807testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003808 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003809}
3810
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003811private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003812 template GsmRrMessage t_imm_ass := ?,
3813 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003814runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003815 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003816 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003817
3818 ra11 := enc_EGPRSPktChRequest2uint(req);
3819 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
3820
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07003821 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003822 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003823 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003824 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003825 }
3826
3827 setverdict(pass);
3828}
3829
3830testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
3831 var template GsmRrMessage imm_ass;
3832 var template IaRestOctets rest;
3833 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003834 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003835
3836 /* Initialize the PCU interface abstraction */
3837 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003838 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003839
3840 var EGPRSPktChRequest req := {
3841 /* NOTE: other fields are set in the loop */
3842 signalling := { tag := '110011'B }
3843 };
3844
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003845 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003846 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3847 req.signalling.random_bits := ext_ra;
3848
3849 /* For signalling, do we expect Multiblock UL TBF Assignment? */
3850 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3851 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3852 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3853
3854 f_TC_egprs_pkt_chan_req(req, imm_ass);
3855 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003856
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003857 var StatsDExpects expect := {
3858 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3859 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3860 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3861 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3862 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3863 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3864 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3865 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3866 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3867 };
3868 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003869
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003870 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003871}
3872
3873testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
3874 var template GsmRrMessage imm_ass;
3875 var template IaRestOctets rest;
3876 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003877 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003878
3879 /* Initialize the PCU interface abstraction */
3880 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003881 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003882
3883 var EGPRSPktChRequest req := {
3884 /* NOTE: other fields are set in the loop */
3885 one_phase := { tag := '0'B }
3886 };
3887
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003888 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003889 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3890 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
3891 var BIT2 priority := substr(ext_ra, 0, 2);
3892 var BIT3 rand := substr(ext_ra, 2, 3);
3893
3894 req.one_phase.multislot_class := mslot_class;
3895 req.one_phase.priority := priority;
3896 req.one_phase.random_bits := rand;
3897
3898 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
3899 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
3900 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3901 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3902
3903 f_TC_egprs_pkt_chan_req(req, imm_ass);
3904 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003905
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003906 var StatsDExpects expect := {
3907 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3908 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3909 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
3910 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3911 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3912 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
3913 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3914 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3915 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3916 };
3917 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003918
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003919 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003920}
3921
3922testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
3923 var template GsmRrMessage imm_ass;
3924 var template IaRestOctets rest;
3925 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003926 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003927
3928 /* Initialize the PCU interface abstraction */
3929 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003930 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003931
3932 var EGPRSPktChRequest req := {
3933 /* NOTE: other fields are set in the loop */
3934 two_phase := { tag := '110000'B }
3935 };
3936
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003937 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003938 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3939 var BIT2 priority := substr(ext_ra, 0, 2);
3940 var BIT3 rand := substr(ext_ra, 2, 3);
3941
3942 req.two_phase.priority := priority;
3943 req.two_phase.random_bits := rand;
3944
3945 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
3946 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3947 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3948 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3949
3950 f_TC_egprs_pkt_chan_req(req, imm_ass);
3951 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003952
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003953 var StatsDExpects expect := {
3954 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3955 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3956 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3957 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3958 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3959 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3960 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3961 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3962 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3963 };
3964 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003965
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003966 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003967}
3968
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003969private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
3970 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003971 PCUIF_BurstType bt := BURST_TYPE_1,
3972 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003973runs on RAW_PCU_Test_CT {
3974 var template ReqRefWaitInd tr_ref;
3975 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003976
3977 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
3978 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
3979 ra := bit2int(ra11), is_11bit := 1,
3980 burst_type := bt, fn := fn,
3981 arfcn := 871));
3982
3983 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07003984 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003985
3986 /* Just to have a short-name reference to the actual message */
3987 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
3988
3989 /* Make sure that Request Reference list contains at least one entry
3990 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003991 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003992 if (not match(iar.payload, { *, tr_ref, * })) {
3993 setverdict(fail, "Request Reference list does not match");
3994 f_shutdown(__BFILE__, __LINE__);
3995 }
3996
3997 /* Match Feature Indicator (must indicate PS domain) */
3998 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
3999 setverdict(fail, "Feature Indicator does not match");
4000 f_shutdown(__BFILE__, __LINE__);
4001 }
4002
4003 /* Match IAR Rest Octets */
4004 if (not match(iar.rest_octets, rest)) {
4005 setverdict(fail, "IAR Rest Octets does not match: ",
4006 iar.rest_octets, " vs expected ", rest);
4007 f_shutdown(__BFILE__, __LINE__);
4008 }
4009
4010 setverdict(pass);
4011}
4012
4013/* Verify the contents of RR Immediate Assignment Reject message and its
4014 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4015testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4016 var template IARRestOctets rest;
4017 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004018 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004019
4020 /* Initialize the PCU interface abstraction */
4021 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004022 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004023
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004024 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004025 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4026 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4027
4028 /* Intentionally incorrect message (see table 11.2.5a.2) */
4029 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4030 }
4031
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004032 var StatsDExpects expect := {
4033 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4034 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4035 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4036 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4037 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4038 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4039 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4040 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4041 };
4042 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004043
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004044 f_shutdown(__BFILE__, __LINE__, final := true);
4045}
4046
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004047/* At the moment, the IUT does not support any emergency services. Make sure
4048 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4049testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4050 var template IARRestOctets rest;
4051 var BIT5 ext_ra;
4052 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004053 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004054
4055 /* Initialize the PCU interface abstraction */
4056 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004057 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004058
4059 var EGPRSPktChRequest req := {
4060 /* NOTE: other fields are set in the loop */
4061 emergency := { tag := '110111'B }
4062 };
4063
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004064 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004065 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4066 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4067
4068 req.emergency.random_bits := ext_ra;
4069 ra11 := enc_EGPRSPktChRequest2bits(req);
4070
4071 /* Intentionally incorrect message (see table 11.2.5a.2) */
4072 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4073 }
4074
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004075 var StatsDExpects expect := {
4076 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4077 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4078 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4079 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4080 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4081 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4082 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4083 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4084 };
4085 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004086
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004087 f_shutdown(__BFILE__, __LINE__, final := true);
4088}
4089
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004090/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4091testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004092 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004093 var template IARRestOctets rest;
4094 var BIT11 ra11;
4095
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004096 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004097 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004098
4099 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004100 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4101 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004102
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004103 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004104 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004105 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004106
4107 var EGPRSPktChRequest req := {
4108 one_phase := {
4109 tag := '0'B,
4110 multislot_class := '10101'B,
4111 priority := '01'B,
4112 random_bits := '101'B
4113 }
4114 };
4115
4116 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4117 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4118 for (var integer i := 0; i < 7; i := i + 1) {
4119 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4120 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4121 }
4122
4123 ra11 := enc_EGPRSPktChRequest2bits(req);
4124 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4125
4126 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004127 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004128
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004129 var StatsDExpects expect := {
4130 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4131 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4132 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4133 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4134 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4135 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4136 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4137 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4138 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4139 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4140 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4141 };
4142 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004143
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004144 f_shutdown(__BFILE__, __LINE__, final := true);
4145}
4146
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004147/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004148private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004149return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004150 /* Pick a random MA length in range 2 .. max_ma_len */
4151 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4152
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004153 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4154 hsn := f_rnd_int(63),
4155 maio := f_rnd_int(63),
4156 ma := f_rnd_bitstring(ma_len));
4157}
4158
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004159private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4160 in GsmRrMessage rr_msg)
4161{
4162 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004163 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004164
4165 var template PacketChannelDescription tr_pkt_chan_desc := {
4166 channel_Type_spare := ?,
4167 tn := ?,
4168 tsc := ts.tsc,
4169 presence := '1'B,
4170 zero := omit,
4171 one := {
4172 maio := ts.maio,
4173 hsn := ts.hsn
4174 }
4175 };
4176
4177 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4178 setverdict(fail, "Packet Channel Description does not match: ",
4179 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4180 }
4181
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004182 /* Mobile Allocation is expected to be octet-aligned */
4183 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4184 var template MobileAllocationLV tr_ma := {
4185 len := ma_oct_len, /* in bytes */
4186 ma := substr(ts.ma, 0, ma_oct_len * 8)
4187 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004188
4189 if (not match(ia.mobile_allocation, tr_ma)) {
4190 setverdict(fail, "Mobile Allocation does not match: ",
4191 ia.mobile_allocation, " vs ", tr_ma);
4192 }
4193
4194 setverdict(pass);
4195}
4196
4197/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4198testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004199 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004200 var GprsMS ms := valueof(t_GprsMS_def);
4201
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004202 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004203 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004204
4205 /* Initialize the PCU interface abstraction */
4206 f_init_raw(testcasename(), info_ind);
4207
4208 /* EGPRS Packet Channel Request (cause=Signalling) */
4209 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4210
4211 /* Establish an Uplink EGPRS TBF */
4212 f_ms_establish_ul_tbf(ms);
4213
4214 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4215 f_shutdown(__BFILE__, __LINE__, final := true);
4216}
4217
4218/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4219testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004220 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004221 var GprsMS ms := valueof(t_GprsMS_def);
4222
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004223 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004224 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004225
4226 /* Initialize the PCU interface abstraction */
4227 f_init_raw(testcasename(), info_ind);
4228
4229 /* Establish an Uplink TBF */
4230 f_ms_establish_ul_tbf(ms);
4231
4232 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4233 f_shutdown(__BFILE__, __LINE__, final := true);
4234}
4235
4236/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4237testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004238 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004239 var GprsMS ms := valueof(t_GprsMS_def);
4240
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004241 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004242 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004243
4244 /* Initialize NS/BSSGP side */
4245 f_init_bssgp();
4246
4247 /* Initialize the PCU interface abstraction */
4248 f_init_raw(testcasename(), info_ind);
4249
4250 /* Establish BSSGP connection to the PCU */
4251 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004252 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004253
4254 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4255 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4256 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4257
4258 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4259 f_shutdown(__BFILE__, __LINE__, final := true);
4260}
4261
4262private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4263 in FrequencyParameters fp)
4264{
4265 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004266 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004267
4268 /* Table 12.8.1: Frequency Parameters information elements */
4269 var template FrequencyParameters tr_fp := {
4270 tsc := ts.tsc,
4271 presence := '10'B, /* Direct encoding 1 */
4272 arfcn := omit,
4273 indirect := omit,
4274 direct1 := {
4275 maio := ts.maio,
4276 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4277 mobile_allocation := {
4278 hsn := ts.hsn,
4279 rfl_number_list_present := '0'B,
4280 rfl_number_list := omit,
4281 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004282 ma_length := ts.ma_bit_len,
4283 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004284 }
4285 },
4286 direct2 := omit
4287 };
4288
4289 if (not match(fp, tr_fp)) {
4290 setverdict(fail, "Frequency Parameters IE does not match: ",
4291 fp, " vs ", tr_fp);
4292 }
4293
4294 setverdict(pass);
4295}
4296
4297/* Make sure that Packet Uplink Assignment contains hopping parameters */
4298testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004299 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004300 var GprsMS ms := valueof(t_GprsMS_def);
4301 var uint32_t poll_fn;
4302
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004303 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004304 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004305
4306 /* Initialize the PCU interface abstraction */
4307 f_init_raw(testcasename(), info_ind);
4308
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004309 /* Single block (two phase) packet access */
4310 var uint16_t ra := bit2int(chan_req_sb);
4311 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4312
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004313 /* Establish an Uplink TBF */
4314 f_ms_establish_ul_tbf(ms);
4315
4316 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004317 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4318 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004319
4320 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004321 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4322 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004323
4324 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4325 var template (omit) FrequencyParameters fp;
4326 if (ua.is_egprs == '1'B) {
4327 fp := ua.egprs.freq_par;
4328 } else {
4329 fp := ua.gprs.freq_par;
4330 }
4331
4332 /* This is an optional IE, so it's worth to check its presence */
4333 if (istemplatekind(fp, "omit")) {
4334 setverdict(fail, "Frequency Parameters IE is not present");
4335 f_shutdown(__BFILE__, __LINE__);
4336 }
4337
4338 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4339 f_shutdown(__BFILE__, __LINE__, final := true);
4340}
4341
4342/* Make sure that Packet Downlink Assignment contains hopping parameters */
4343testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004344 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004345 var octetstring data := f_rnd_octstring(10);
4346 var GprsMS ms := valueof(t_GprsMS_def);
4347 var RlcmacDlBlock dl_block;
4348 var uint32_t poll_fn;
4349
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004350 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004351 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004352
4353 /* Initialize NS/BSSGP side */
4354 f_init_bssgp();
4355
4356 /* Initialize the PCU interface abstraction */
4357 f_init_raw(testcasename(), info_ind);
4358
4359 /* Establish BSSGP connection to the PCU */
4360 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004361 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004362
4363 /* Establish an Uplink TBF */
4364 f_ms_establish_ul_tbf(ms);
4365
4366 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004367 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004368
4369 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4370 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4371 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4372
4373 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4374 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4375
4376 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004377 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4378 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004379
4380 /* This is an optional IE, so it's worth to check its presence */
4381 if (not ispresent(da.freq_par)) {
4382 setverdict(fail, "Frequency Parameters IE is not present");
4383 f_shutdown(__BFILE__, __LINE__);
4384 }
4385
4386 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4387 f_shutdown(__BFILE__, __LINE__, final := true);
4388}
4389
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004390/* Check if the IUT handles subsequent INFO.ind messages */
4391testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004392 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004393 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004394
4395 /* Initialize the PCU interface abstraction */
4396 f_init_raw(testcasename(), info_ind);
4397
4398 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4399 for (var integer i := 0; i < 16; i := i + 1) {
4400 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004401 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004402 }
4403
4404 f_shutdown(__BFILE__, __LINE__, final := true);
4405}
4406
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004407/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4408testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4409 var PCUIF_info_ind info_ind;
4410 var integer i;
4411 const integer num_ms := 8;
4412
4413 /* Initialize NS/BSSGP side */
4414 f_init_bssgp();
4415 /* Initialize GPRS MS side */
4416 f_init_gprs_ms(num_ms);
4417
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004418 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004419 /* Only the 3 first TRX are enabled. The enabled ones all have same
4420 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004421 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4422 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4423 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4424 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004425
4426 /* Initialize the PCU interface abstraction */
4427 f_init_raw(testcasename(), info_ind);
4428
4429 /* Establish BSSGP connection to the PCU */
4430 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004431 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004432
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004433 /* Establish an Uplink TBF for each GprsMS instance */
4434 f_multi_ms_establish_tbf(do_activate := false);
4435
4436 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004437 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004438 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004439 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004440 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004441 f_shutdown(__BFILE__, __LINE__);
4442 }
4443 }
4444
4445 f_shutdown(__BFILE__, __LINE__, final := true);
4446}
4447
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004448/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4449 * downgraded to CS1-4 so that GPRS can read the USF).
4450 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4451 */
4452testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4453 var PCUIF_info_ind info_ind;
4454 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4455 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004456 var uint32_t sched_fn, dl_fn, ack_fn;
4457 var octetstring data := f_rnd_octstring(10);
4458 var RlcmacDlBlock dl_block;
4459 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004460 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004461 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4462 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4463
4464 /* Initialize NS/BSSGP side */
4465 f_init_bssgp();
4466 /* Initialize GPRS MS side */
4467 f_init_gprs_ms(num_ms);
4468
4469 info_ind := valueof(ts_PCUIF_INFO_default);
4470 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004471 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4472 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004473
4474 /* Initialize the PCU interface abstraction */
4475 f_init_raw(testcasename(), info_ind);
4476
4477 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4478 g_mcs_initial_dl := 5;
4479 g_mcs_max_dl := 5;
4480 f_pcuvty_set_allowed_cs_mcs();
4481
4482 /* Establish BSSGP connection to the PCU */
4483 f_bssgp_establish();
4484 f_multi_ms_bssgp_register();
4485
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004486 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004487 pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[0], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[0].tlli, ms_racap_gprs_def));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004488 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4489 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4490 f_shutdown(__BFILE__, __LINE__);
4491 }
4492 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4493 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4494
4495 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004496 pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[1], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[1].tlli, ms_racap_egprs_def));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004497 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4498 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4499 f_shutdown(__BFILE__, __LINE__);
4500 }
4501 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4502 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4503
4504 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4505 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4506 f_sleep(0.1);
4507 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4508 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4509 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4510 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4511 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4512 /* ACK the DL block */
4513 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4514 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4515 f_dl_block_ack_fn(dl_block, dl_fn));
4516
4517 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4518 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4519 f_sleep(0.1);
4520 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4521 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4522 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4523 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4524 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4525 /* ACK the DL block */
4526 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4527 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4528 f_dl_block_ack_fn(dl_block, dl_fn));
4529
4530 data := f_rnd_octstring(1400);
4531 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4532 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4533
4534 for (var integer i := 0; i < 800; i := i + 1) {
4535 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4536
4537 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
4538 /* No more data to receive, done */
4539 break;
4540 }
4541
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004542 usf_ms := -1;
4543
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004544 if (ischosen(dl_block.ctrl)) {
4545 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4546 f_shutdown(__BFILE__, __LINE__);
4547 } else if (ischosen(dl_block.data_egprs)) {
4548 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4549 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4550 f_shutdown(__BFILE__, __LINE__);
4551 }
4552 tgt_ms := 1;
4553 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4554 if (dl_block.data_egprs.mcs > MCS_4) {
4555 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4556 f_shutdown(__BFILE__, __LINE__);
4557 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004558 usf_ms := 0;
4559 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004560 } else {
4561 if (dl_block.data_egprs.mcs <= MCS_4) {
4562 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4563 f_shutdown(__BFILE__, __LINE__);
4564 }
4565 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004566 usf_ms := 1;
4567 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004568 }
4569 }
4570 } else {
4571 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4572 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4573 f_shutdown(__BFILE__, __LINE__);
4574 }
4575 tgt_ms := 0;
4576 if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004577 usf_ms := 0;
4578 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004579 } else if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004580 usf_ms := 1;
4581 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004582 }
4583 }
4584
4585 /* Keep Ack/Nack description updated */
4586 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4587
4588 /* TDMA frame number on which we are supposed to send the ACK */
4589 if (f_dl_block_rrbp_valid(dl_block)) {
4590 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4591 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);
4592 if (tx_data_remain != 0) {
4593 /* Submit more data from time to time to keep the TBF ongoing */
4594 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4595 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4596 tx_data_remain := tx_data_remain - 1;
4597 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004598 } else if (tx_data_remain != 0) {
4599 /* keep sending UL blocks when requested by USF to avoid
4600 * UL TBF timeout and hence stop receival of USFs */
4601 if (usf_ms != -1) {
4602 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4603 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004604 }
4605 }
4606
4607 log("results: ms_gprs_usf_count=", ms_gprs_usf_count, " / ms_egprs_usf_count=", ms_egprs_usf_count);
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004608 /* He we check that DL blocks scheduled at GPRS can still request UL
4609 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4610 * condition also ensures the downgrade to <=MCS4 condition is tested
4611 * above */
4612 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4613 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004614 f_shutdown(__BFILE__, __LINE__);
4615 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004616 /* Here check for some level of fairness between them (at least ~40%): */
4617 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4618 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4619 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4620 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4621 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4622 f_shutdown(__BFILE__, __LINE__);
4623 }
4624 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4625 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4626 f_shutdown(__BFILE__, __LINE__);
4627 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004628
4629 f_shutdown(__BFILE__, __LINE__, final := true);
4630}
4631
4632
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004633private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4634 boolean exp_imsi, boolean exp_tmsi)
4635runs on RAW_PCU_Test_CT {
4636 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4637 var integer pending := lengthof(g_ms);
4638 var RlcmacDlBlock dl_block;
4639 var boolean f1, f2;
4640
4641 while (pending > 0) {
4642 var uint32_t poll_fn;
4643
4644 /* Obtain a Downlink block and make sure it is a paging request */
4645 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4646 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4647 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4648 break;
4649 }
4650
4651 /* This should not happen in general, but who knows... */
4652 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4653 if (not ispresent(req.repeated_pageinfo)) {
4654 setverdict(fail, "Repeated Page Info IE is absent?!?");
4655 break;
4656 }
4657
4658 /* A single message may contain several MIs depending on their type */
4659 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4660 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4661 ps_domain := false);
4662 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4663 ps_domain := false);
4664 if (not f1 and not f2)
4665 { continue; }
4666
4667 /* Detect duplicate MIs */
4668 if (mask[i] == '1'B) {
4669 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4670 continue;
4671 }
4672
4673 mask[i] := '1'B;
4674 }
4675
4676 pending := pending - lengthof(req.repeated_pageinfo);
4677 }
4678
4679 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4680 if (mask[i] != '1'B) {
4681 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
4682 log("===== mask := ", mask);
4683 }
4684 }
4685
4686 /* All messages must have been received by now, expect a dummy block */
4687 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
4688}
4689
4690private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
4691runs on RAW_PCU_Test_CT {
4692 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4693 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4694
4695 /* Initialize NS/BSSGP side */
4696 f_init_bssgp();
4697
4698 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004699 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004700
4701 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
4702 f_init_gprs_ms(7 * 8);
4703
4704 /* Initialize the PCU interface abstraction */
4705 f_init_raw(testcasename(), info_ind);
4706
4707 /* Establish BSSGP connection to the PCU */
4708 f_bssgp_establish();
4709 f_multi_ms_bssgp_register();
4710
4711 /* Establish an Uplink TBF for each GprsMS instance */
4712 f_multi_ms_establish_tbf(do_activate := true);
4713}
4714
4715testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
4716 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4717
4718 /* Common part: send INFO.ind, establish TBFs... */
4719 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4720
4721 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
4722 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4723 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4724 }
4725
4726 /* FIXME: work around a race condition between PCUIF and BSSGP */
4727 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4728
4729 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4730 * The IUT is expected to page on all PDCH slots of all transceivers. */
4731 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4732 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4733 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
4734 }
4735
4736 f_shutdown(__BFILE__, __LINE__, final := true);
4737}
4738
4739testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
4740 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4741
4742 /* Common part: send INFO.ind, establish TBFs... */
4743 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4744
4745 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
4746 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4747 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4748 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4749 }
4750
4751 /* FIXME: work around a race condition between PCUIF and BSSGP */
4752 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4753
4754 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4755 * The IUT is expected to page on all PDCH slots of all transceivers. */
4756 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4757 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4758 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
4759 }
4760
4761 f_shutdown(__BFILE__, __LINE__, final := true);
4762}
4763
4764testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
4765 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4766
4767 /* Common part: send INFO.ind, establish TBFs... */
4768 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4769
4770 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
4771 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4772 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4773 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
4774 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4775 } else {
4776 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4777 }
4778 }
4779
4780 /* FIXME: work around a race condition between PCUIF and BSSGP */
4781 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4782
4783 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4784 * The IUT is expected to page on all PDCH slots of all transceivers. */
4785 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4786 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4787 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
4788 }
4789
4790 f_shutdown(__BFILE__, __LINE__, final := true);
4791}
4792
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004793private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004794runs on RAW_PCU_Test_CT return RlcmacDlBlock {
4795 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004796 var integer i := 0;
4797 while (true) {
4798 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4799 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
4800 break;
4801 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004802 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004803 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4804 f_shutdown(__BFILE__, __LINE__);
4805 }
4806 i := i + 1;
4807 }
4808 return dl_block;
4809}
4810
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004811private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
4812runs on RAW_PCU_Test_CT {
4813 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),
4814 info_ind.lac),
4815 info_ind.rac),
4816 info_ind.cell_id));
4817 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4818 423),
4819 2),
4820 5));
4821 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4822 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4823 var template (value) RAN_Information_RIM_Container res_cont :=
4824 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
4825 ts_RIM_Sequence_Number(2),
4826 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
4827 ts_RIM_Protocol_Version_Number(1),
4828 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
4829 omit);
4830 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4831 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4832 res_cont));
4833}
4834
4835altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
4836runs on RAW_PCU_Test_CT {
4837 /* RIM procedure: */
4838 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),
4839 info_ind.lac),
4840 info_ind.rac),
4841 info_ind.cell_id));
4842 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4843 423),
4844 2),
4845 5));
4846 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4847 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4848 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4849 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4850 tr_RAN_Information_Request_RIM_Container)) {
4851 if (do_answer) {
4852 f_outbound_nacc_rim_tx_resp(info_ind);
4853 }
4854 if (do_repeat) {
4855 repeat;
4856 }
4857 }
4858}
4859
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004860private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
4861 boolean answer := true, boolean use_old_ctrl_iface := false)
4862runs on RAW_PCU_Test_CT {
4863 if (use_old_ctrl_iface == true) {
4864 f_ipa_ctrl_wait_link_up();
4865 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4866 int2str(info_ind.lac) & "." &
4867 int2str(info_ind.cell_id) & "." &
4868 int2str(req_arfcn) & "." &
4869 int2str(req_bsic);
4870 if (answer) {
4871 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4872 } else {
4873 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
4874 }
4875 } else {
4876 var PCUIF_Message pcu_msg;
4877 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
4878 if (answer) {
4879 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
4880 }
4881 }
4882}
4883
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004884/* Start NACC from MS side */
4885private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004886 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004887 boolean skip_final_ctrl_ack := false,
4888 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004889runs on RAW_PCU_Test_CT {
4890 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4891 var RlcmacDlBlock dl_block;
4892 var uint32_t sched_fn;
4893 var GsmArfcn req_arfcn := 862;
4894 var uint6_t req_bsic := 43;
4895
4896 /* Start NACC from MS side */
4897 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4898 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4899
4900 if (exp_rac_ci_query == true) {
4901 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004902 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004903 }
4904
4905 if (exp_si_query == true) {
4906 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004907 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004908 }
4909
4910 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004911 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004912
4913 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
4914 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4915 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4916 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4917 f_shutdown(__BFILE__, __LINE__);
4918 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004919 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004920 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004921 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4922 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4923 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004924}
4925
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004926/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
4927testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004928 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004929 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004930 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004931 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004932
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004933 if (use_old_ctrl_iface) {
4934 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4935 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4936 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004937
4938 /* Initialize NS/BSSGP side */
4939 f_init_bssgp();
4940 /* Initialize GPRS MS side */
4941 f_init_gprs_ms();
4942 ms := g_ms[0]; /* We only use first MS in this test */
4943
4944 /* Initialize the PCU interface abstraction */
4945 f_init_raw(testcasename(), info_ind);
4946
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004947 /* Make sure we are not affected by full cache from previous tests */
4948 f_pcuvty_flush_neigh_caches();
4949
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004950 /* Establish BSSGP connection to the PCU */
4951 f_bssgp_establish();
4952 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4953
4954 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004955 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004956 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4957 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4958
4959 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004960 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004961
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004962 f_shutdown(__BFILE__, __LINE__, final := true);
4963}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004964
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004965/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
4966testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
4967 var PollFnCtx pollctx;
4968 var GprsMS ms;
4969 var RlcmacDlBlock dl_block;
4970 var uint32_t sched_fn;
4971 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004972 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004973
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004974 if (use_old_ctrl_iface) {
4975 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4976 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4977 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004978
4979 /* Initialize NS/BSSGP side */
4980 f_init_bssgp();
4981 /* Initialize GPRS MS side */
4982 f_init_gprs_ms();
4983 ms := g_ms[0]; /* We only use first MS in this test */
4984
4985 /* Initialize the PCU interface abstraction */
4986 f_init_raw(testcasename(), info_ind);
4987
4988 /* Make sure we are not affected by full cache from previous tests */
4989 f_pcuvty_flush_neigh_caches();
4990
4991 /* Establish BSSGP connection to the PCU */
4992 f_bssgp_establish();
4993 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4994
4995 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004996 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004997 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4998 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4999
5000 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005001 f_outbound_nacc_success(ms, info_ind, skip_final_ctrl_ack := true, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005002
5003 /* Wait until we receive something non-dummy */
5004 dl_block := f_skip_dummy(0, sched_fn);
5005 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5006 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5007 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5008 }
5009 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5010 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5011 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5012 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5013 }
5014
5015 f_shutdown(__BFILE__, __LINE__, final := true);
5016}
5017
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005018/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5019testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5020 var PollFnCtx pollctx;
5021 var GprsMS ms;
5022 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005023 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005024 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005025
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005026 if (use_old_ctrl_iface) {
5027 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5028 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5029 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005030
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005031 /* Initialize NS/BSSGP side */
5032 f_init_bssgp();
5033 /* Initialize GPRS MS side */
5034 f_init_gprs_ms();
5035 ms := g_ms[0]; /* We only use first MS in this test */
5036
5037 /* Initialize the PCU interface abstraction */
5038 f_init_raw(testcasename(), info_ind);
5039
5040 /* Make sure we are not affected by full cache from previous tests */
5041 f_pcuvty_flush_neigh_caches();
5042 /* Set timeout values for caches so that entries will be in cache during second try */
5043 f_pcuvty_set_neigh_caches(10, 10);
5044
5045 /* Establish BSSGP connection to the PCU */
5046 f_bssgp_establish();
5047 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5048
5049 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005050 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005051 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5052 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5053
5054 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005055 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005056
5057 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005058 f_outbound_nacc_success(ms, info_ind, false, false, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005059
5060 f_shutdown(__BFILE__, __LINE__, final := true);
5061}
5062
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005063/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5064 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5065 */
5066testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5067 var PollFnCtx pollctx;
5068 var GprsMS ms;
5069 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005070 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005071 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005072
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005073 if (use_old_ctrl_iface) {
5074 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5075 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5076 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005077
5078 /* Initialize NS/BSSGP side */
5079 f_init_bssgp();
5080 /* Initialize GPRS MS side */
5081 f_init_gprs_ms();
5082 ms := g_ms[0]; /* We only use first MS in this test */
5083
5084 /* Initialize the PCU interface abstraction */
5085 f_init_raw(testcasename(), info_ind);
5086
5087 /* Make sure we are not affected by full cache from previous tests */
5088 f_pcuvty_flush_neigh_caches();
5089 /* Set timeout values for caches so that entries will be erased before the second try */
5090 f_pcuvty_set_neigh_caches(1, 1);
5091
5092 /* Establish BSSGP connection to the PCU */
5093 f_bssgp_establish();
5094 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5095
5096 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005097 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005098 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5099 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5100
5101 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005102 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005103
5104 /* CTRL client should have disconnected from us */
5105 f_ipa_ctrl_wait_link_down();
5106 /* wait for cache entries to time out */
5107 f_sleep(2.0);
5108 /* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005109 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005110
5111 f_shutdown(__BFILE__, __LINE__, final := true);
5112}
5113
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005114/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005115testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5116 var RlcmacDlBlock dl_block;
5117 var PollFnCtx pollctx;
5118 var uint32_t sched_fn;
5119 var GprsMS ms;
5120 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5121 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005122 var GsmArfcn req_arfcn := 862;
5123 var uint6_t req_bsic := 43;
5124
5125 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5126 * resolution CTRL port, to trigger Conn Refused by socket:
5127 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5128 */
5129
5130 /* Initialize NS/BSSGP side */
5131 f_init_bssgp();
5132 /* Initialize GPRS MS side */
5133 f_init_gprs_ms();
5134 ms := g_ms[0]; /* We only use first MS in this test */
5135
5136 /* Initialize the PCU interface abstraction */
5137 f_init_raw(testcasename(), info_ind);
5138
5139 /* Make sure we are not affected by full cache from previous tests */
5140 f_pcuvty_flush_neigh_caches();
5141
5142 /* Establish BSSGP connection to the PCU */
5143 f_bssgp_establish();
5144 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5145
5146 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005147 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005148 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5149 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5150
5151 /* Start NACC from MS side */
5152 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5153 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5154
5155 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005156 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005157 /* Make sure it is a Pkt Cell Chg Continue */
5158 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5159 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5160 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005161 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5162 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5163 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5164 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5165 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005166
5167 f_shutdown(__BFILE__, __LINE__, final := true);
5168}
5169
5170/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005171testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5172 var RlcmacDlBlock dl_block;
5173 var PollFnCtx pollctx;
5174 var uint32_t sched_fn;
5175 var GprsMS ms;
5176 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5177 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005178 var GsmArfcn req_arfcn := 862;
5179 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005180 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005181
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005182 if (use_old_ctrl_iface) {
5183 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5184 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5185 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005186
5187 /* Initialize NS/BSSGP side */
5188 f_init_bssgp();
5189 /* Initialize GPRS MS side */
5190 f_init_gprs_ms();
5191 ms := g_ms[0]; /* We only use first MS in this test */
5192
5193 /* Initialize the PCU interface abstraction */
5194 f_init_raw(testcasename(), info_ind);
5195
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005196 /* Make sure we are not affected by full cache from previous tests */
5197 f_pcuvty_flush_neigh_caches();
5198
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005199 /* Establish BSSGP connection to the PCU */
5200 f_bssgp_establish();
5201 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5202
5203 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005204 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005205 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5206 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5207
5208 /* Start NACC from MS side */
5209 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5210 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5211
5212 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005213 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005214 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, false, use_old_ctrl_iface);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005215
5216 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005217 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005218 /* Make sure it is a Pkt Cell Chg Continue */
5219 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5220 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5221 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005222 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5223 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5224 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5225 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5226 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005227
5228 f_shutdown(__BFILE__, __LINE__, final := true);
5229}
5230
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005231/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5232testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5233 var RlcmacDlBlock dl_block;
5234 var PollFnCtx pollctx;
5235 var uint32_t sched_fn;
5236 var GprsMS ms;
5237 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5238 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005239 var GsmArfcn req_arfcn := 862;
5240 var uint6_t req_bsic := 43;
5241
5242 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5243 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5244
5245 /* Initialize NS/BSSGP side */
5246 f_init_bssgp();
5247 /* Initialize GPRS MS side */
5248 f_init_gprs_ms();
5249 ms := g_ms[0]; /* We only use first MS in this test */
5250
5251 /* Initialize the PCU interface abstraction */
5252 f_init_raw(testcasename(), info_ind);
5253
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005254 /* Make sure we are not affected by full cache from previous tests */
5255 f_pcuvty_flush_neigh_caches();
5256
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005257 /* Establish BSSGP connection to the PCU */
5258 f_bssgp_establish();
5259 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5260
5261 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005262 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005263 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5264 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5265
5266 /* Start NACC from MS side */
5267 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5268 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5269
5270 /* osmo-pcu should now ask for resolution: */
5271 f_ipa_ctrl_wait_link_up();
5272 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5273 int2str(info_ind.lac) & "." &
5274 int2str(info_ind.cell_id) & "." &
5275 int2str(req_arfcn) & "." &
5276 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005277 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005278 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5279
5280 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005281 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005282 /* Make sure it is a Pkt Cell Chg Continue */
5283 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5284 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5285 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005286 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5287 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5288 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5289 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5290 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005291
5292 f_shutdown(__BFILE__, __LINE__, final := true);
5293}
5294
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005295/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5296testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5297 var RlcmacDlBlock dl_block;
5298 var PollFnCtx pollctx;
5299 var uint32_t sched_fn;
5300 var GprsMS ms;
5301 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5302 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005303 var GsmArfcn req_arfcn := 862;
5304 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005305 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005306 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 */
5307 info_ind.lac),
5308 info_ind.rac),
5309 info_ind.cell_id));
5310 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5311 423),
5312 2),
5313 5));
5314 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
5315 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
5316
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005317 if (use_old_ctrl_iface) {
5318 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5319 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5320 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005321
5322 /* Initialize NS/BSSGP side */
5323 f_init_bssgp();
5324 /* Initialize GPRS MS side */
5325 f_init_gprs_ms();
5326 ms := g_ms[0]; /* We only use first MS in this test */
5327
5328 /* Initialize the PCU interface abstraction */
5329 f_init_raw(testcasename(), info_ind);
5330
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005331 /* Make sure we are not affected by full cache from previous tests */
5332 f_pcuvty_flush_neigh_caches();
5333
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005334 /* Establish BSSGP connection to the PCU */
5335 f_bssgp_establish();
5336 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5337
5338 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005339 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005340 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5341 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5342
5343 /* Start NACC from MS side */
5344 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5345 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5346
5347 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005348 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005349
5350 /* RIM procedure: */
5351 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5352 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5353 tr_RAN_Information_Request_RIM_Container));
5354 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5355
5356 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005357 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005358 /* Make sure it is a Pkt Cell Chg Continue */
5359 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5360 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5361 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005362 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5363 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5364 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5365 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5366 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005367
5368 f_shutdown(__BFILE__, __LINE__, final := true);
5369}
5370
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005371/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5372testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5373 var PollFnCtx pollctx;
5374 var GprsMS ms;
5375 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5376 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5377 var RlcmacDlBlock dl_block;
5378 var uint32_t sched_fn;
5379 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005380 var charstring ctrl_var;
5381 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005382 var GsmArfcn req_arfcn := 862;
5383 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005384 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005385
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005386 if (use_old_ctrl_iface) {
5387 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5388 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5389 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005390
5391 /* Initialize NS/BSSGP side */
5392 f_init_bssgp();
5393 /* Initialize GPRS MS side */
5394 f_init_gprs_ms();
5395 ms := g_ms[0]; /* We only use first MS in this test */
5396
5397 /* Initialize the PCU interface abstraction */
5398 f_init_raw(testcasename(), info_ind);
5399
5400 /* Make sure we are not affected by full cache from previous tests */
5401 f_pcuvty_flush_neigh_caches();
5402
5403 /* Establish BSSGP connection to the PCU */
5404 f_bssgp_establish();
5405 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5406
5407 /* Send PACKET RESOURCE REQUEST */
5408 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5409 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5410 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5411
5412 /* Start NACC from MS side */
5413 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5414 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5415
5416 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005417 if (use_old_ctrl_iface) {
5418 f_ipa_ctrl_wait_link_up();
5419 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5420 int2str(info_ind.lac) & "." &
5421 int2str(info_ind.cell_id) & "." &
5422 int2str(req_arfcn) & "." &
5423 int2str(req_bsic);
5424 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5425 } else {
5426 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5427 }
5428
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005429 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5430 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5431 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005432
5433 if (use_old_ctrl_iface) {
5434 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5435 } else {
5436 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5437 }
5438
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005439 timer T := 2.0;
5440 T.start;
5441 alt {
5442 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005443 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005444 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5445 f_shutdown(__BFILE__, __LINE__);
5446 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005447 [not use_old_ctrl_iface] BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg {
5448 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5449 f_shutdown(__BFILE__, __LINE__);
5450 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005451 [] T.timeout {
5452 setverdict(pass);
5453 }
5454 }
5455
5456 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005457 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005458
5459 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5460 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5461 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5462 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5463 f_shutdown(__BFILE__, __LINE__);
5464 }
5465 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5466 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5467 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5468 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5469 }
5470
5471 f_shutdown(__BFILE__, __LINE__, final := true);
5472}
5473
5474/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5475testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5476 var PollFnCtx pollctx;
5477 var GprsMS ms;
5478 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5479 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5480 var RlcmacDlBlock dl_block;
5481 var uint32_t sched_fn;
5482 var CtrlMessage rx_ctrl;
5483 var GsmArfcn req_arfcn := 862;
5484 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005485 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005486
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005487 if (use_old_ctrl_iface) {
5488 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5489 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5490 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005491
5492 /* Initialize NS/BSSGP side */
5493 f_init_bssgp();
5494 /* Initialize GPRS MS side */
5495 f_init_gprs_ms();
5496 ms := g_ms[0]; /* We only use first MS in this test */
5497
5498 /* Initialize the PCU interface abstraction */
5499 f_init_raw(testcasename(), info_ind);
5500
5501 /* Make sure we are not affected by full cache from previous tests */
5502 f_pcuvty_flush_neigh_caches();
5503
5504 /* Establish BSSGP connection to the PCU */
5505 f_bssgp_establish();
5506 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5507
5508 /* Send PACKET RESOURCE REQUEST */
5509 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5510 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5511 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5512
5513 /* Start NACC from MS side */
5514 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5515 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5516
5517 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005518 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005519 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5520 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5521 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5522 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5523 f_outbound_nacc_rim_tx_resp(info_ind);
5524 timer T := 1.0;
5525 T.start;
5526 alt {
5527 [] RIM.receive {
5528 setverdict(fail, "Received unexpected RIM message");
5529 f_shutdown(__BFILE__, __LINE__);
5530 }
5531 [] T.timeout {
5532 setverdict(pass);
5533 }
5534 }
5535
5536 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005537 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005538
5539 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5540 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5541 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5542 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5543 f_shutdown(__BFILE__, __LINE__);
5544 }
5545 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5546 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5547 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5548 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5549 }
5550
5551 f_shutdown(__BFILE__, __LINE__, final := true);
5552}
5553
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005554/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5555testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5556 var PollFnCtx pollctx;
5557 var GprsMS ms;
5558 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5559 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5560 var RlcmacDlBlock dl_block;
5561 var uint32_t sched_fn;
5562 var CtrlMessage rx_ctrl;
5563 var GsmArfcn req_arfcn := 862;
5564 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005565 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005566
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005567 if (use_old_ctrl_iface) {
5568 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5569 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5570 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005571
5572 /* Initialize NS/BSSGP side */
5573 f_init_bssgp();
5574 /* Initialize GPRS MS side */
5575 f_init_gprs_ms();
5576 ms := g_ms[0]; /* We only use first MS in this test */
5577
5578 /* Initialize the PCU interface abstraction */
5579 f_init_raw(testcasename(), info_ind);
5580
5581 /* Make sure we are not affected by full cache from previous tests */
5582 f_pcuvty_flush_neigh_caches();
5583
5584 /* Establish BSSGP connection to the PCU */
5585 f_bssgp_establish();
5586 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5587
5588 /* Send PACKET RESOURCE REQUEST */
5589 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5590 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5591 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5592
5593 /* Start NACC from MS side */
5594 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5595 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5596
5597 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005598 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005599 /* RIM procedure: */
5600 as_outbound_nacc_rim_resolve(info_ind);
5601
5602 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5603 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5604 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5605
5606 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5607 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5608
5609 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5610 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5611 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5612 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5613 f_shutdown(__BFILE__, __LINE__);
5614 }
5615 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5616 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5617 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5618 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5619 }
5620}
5621
5622/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5623testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5624 var PollFnCtx pollctx;
5625 var GprsMS ms;
5626 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5627 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5628 var RlcmacDlBlock dl_block;
5629 var uint32_t sched_fn;
5630 var CtrlMessage rx_ctrl;
5631 var GsmArfcn req_arfcn := 862;
5632 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005633 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005634
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005635 if (use_old_ctrl_iface) {
5636 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5637 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5638 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005639
5640 /* Initialize NS/BSSGP side */
5641 f_init_bssgp();
5642 /* Initialize GPRS MS side */
5643 f_init_gprs_ms();
5644 ms := g_ms[0]; /* We only use first MS in this test */
5645
5646 /* Initialize the PCU interface abstraction */
5647 f_init_raw(testcasename(), info_ind);
5648
5649 /* Make sure we are not affected by full cache from previous tests */
5650 f_pcuvty_flush_neigh_caches();
5651
5652 /* Establish BSSGP connection to the PCU */
5653 f_bssgp_establish();
5654 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5655
5656 /* Send PACKET RESOURCE REQUEST */
5657 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5658 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5659 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5660
5661 /* Start NACC from MS side */
5662 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5663 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5664
5665 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005666 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005667 /* RIM procedure: */
5668 as_outbound_nacc_rim_resolve(info_ind);
5669
5670 /* Announce SI back to MS, continue NACC procedure */
5671 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5672
5673 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5674 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5675
5676 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5677 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5678 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5679 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5680 f_shutdown(__BFILE__, __LINE__);
5681 }
5682 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5683 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5684 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5685 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5686 }
5687}
5688
5689/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
5690testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
5691 var PollFnCtx pollctx;
5692 var GprsMS ms;
5693 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5694 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5695 var RlcmacDlBlock dl_block;
5696 var uint32_t sched_fn;
5697 var CtrlMessage rx_ctrl;
5698 var GsmArfcn req_arfcn := 862;
5699 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005700 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005701
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005702 if (use_old_ctrl_iface) {
5703 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5704 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5705 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005706
5707 /* Initialize NS/BSSGP side */
5708 f_init_bssgp();
5709 /* Initialize GPRS MS side */
5710 f_init_gprs_ms();
5711 ms := g_ms[0]; /* We only use first MS in this test */
5712
5713 /* Initialize the PCU interface abstraction */
5714 f_init_raw(testcasename(), info_ind);
5715
5716 /* Make sure we are not affected by full cache from previous tests */
5717 f_pcuvty_flush_neigh_caches();
5718
5719 /* Establish BSSGP connection to the PCU */
5720 f_bssgp_establish();
5721 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5722
5723 /* Send PACKET RESOURCE REQUEST */
5724 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5725 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5726 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5727
5728 /* Start NACC from MS side */
5729 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5730 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5731
5732 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005733 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005734 /* RIM procedure: */
5735 as_outbound_nacc_rim_resolve(info_ind);
5736
5737 /* Announce SI back to MS, continue NACC procedure */
5738 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5739
5740 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5741 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5742 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5743 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5744 f_shutdown(__BFILE__, __LINE__);
5745 }
5746 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5747 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5748
5749 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5750 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5751 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5752 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5753 }
5754}
5755
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005756/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5757 * while waiting for CTRL resolution */
5758testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
5759 var PollFnCtx pollctx;
5760 var GprsMS ms;
5761 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5762 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5763 var RlcmacDlBlock dl_block;
5764 var uint32_t sched_fn;
5765 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005766 var charstring ctrl_var;
5767 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005768 var GsmArfcn req_arfcn := 862;
5769 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005770 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005771
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005772 if (use_old_ctrl_iface) {
5773 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5774 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5775 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005776
5777 /* Initialize NS/BSSGP side */
5778 f_init_bssgp();
5779 /* Initialize GPRS MS side */
5780 f_init_gprs_ms();
5781 ms := g_ms[0]; /* We only use first MS in this test */
5782
5783 /* Initialize the PCU interface abstraction */
5784 f_init_raw(testcasename(), info_ind);
5785
5786 /* Make sure we are not affected by full cache from previous tests */
5787 f_pcuvty_flush_neigh_caches();
5788
5789 /* Establish BSSGP connection to the PCU */
5790 f_bssgp_establish();
5791 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5792
5793 /* Send PACKET RESOURCE REQUEST */
5794 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5795 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5796 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5797
5798 /* Start NACC from MS side */
5799 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5800 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5801
5802 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005803 if (use_old_ctrl_iface) {
5804 f_ipa_ctrl_wait_link_up();
5805 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5806 int2str(info_ind.lac) & "." &
5807 int2str(info_ind.cell_id) & "." &
5808 int2str(req_arfcn) & "." &
5809 int2str(req_bsic);
5810 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5811 } else {
5812 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5813 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005814 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
5815 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5816 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5817 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005818 if (use_old_ctrl_iface) {
5819 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5820 } else {
5821 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5822 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005823 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005824 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005825
5826 /* And finally everything continues as usual with RIN procedure */
5827 as_outbound_nacc_rim_resolve(info_ind);
5828
5829 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005830 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005831
5832 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5833 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5834 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5835 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5836 f_shutdown(__BFILE__, __LINE__);
5837 }
5838 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5839 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5840 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5841 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5842 }
5843
5844 f_shutdown(__BFILE__, __LINE__, final := true);
5845}
5846
5847/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5848 * while waiting for SI resolution */
5849testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
5850 var PollFnCtx pollctx;
5851 var GprsMS ms;
5852 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5853 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5854 var RlcmacDlBlock dl_block;
5855 var uint32_t sched_fn;
5856 var CtrlMessage rx_ctrl;
5857 var GsmArfcn req_arfcn := 862;
5858 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005859 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005860
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005861 if (use_old_ctrl_iface) {
5862 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5863 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5864 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005865
5866 /* Initialize NS/BSSGP side */
5867 f_init_bssgp();
5868 /* Initialize GPRS MS side */
5869 f_init_gprs_ms();
5870 ms := g_ms[0]; /* We only use first MS in this test */
5871
5872 /* Initialize the PCU interface abstraction */
5873 f_init_raw(testcasename(), info_ind);
5874
5875 /* Make sure we are not affected by full cache from previous tests */
5876 f_pcuvty_flush_neigh_caches();
5877
5878 /* Establish BSSGP connection to the PCU */
5879 f_bssgp_establish();
5880 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5881
5882 /* Send PACKET RESOURCE REQUEST */
5883 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5884 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5885 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5886
5887 /* Start NACC from MS side */
5888 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5889 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5890
5891 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005892 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005893 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5894 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
5895 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5896 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5897 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5898 f_outbound_nacc_rim_tx_resp(info_ind);
5899
5900 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005901 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005902
5903 /* And finally everything continues as usual with RIN procedure */
5904 as_outbound_nacc_rim_resolve(info_ind);
5905
5906 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005907 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005908
5909 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5910 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5911 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5912 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5913 f_shutdown(__BFILE__, __LINE__);
5914 }
5915 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5916 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5917 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5918 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5919 }
5920
5921 f_shutdown(__BFILE__, __LINE__, final := true);
5922}
5923
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005924/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5925 * while sending Pkt Neigh Data Change */
5926testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
5927 var PollFnCtx pollctx;
5928 var GprsMS ms;
5929 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5930 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5931 var RlcmacDlBlock dl_block;
5932 var uint32_t sched_fn;
5933 var CtrlMessage rx_ctrl;
5934 var GsmArfcn req_arfcn := 862;
5935 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005936 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005937
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005938 if (use_old_ctrl_iface) {
5939 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5940 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5941 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005942
5943 /* Initialize NS/BSSGP side */
5944 f_init_bssgp();
5945 /* Initialize GPRS MS side */
5946 f_init_gprs_ms();
5947 ms := g_ms[0]; /* We only use first MS in this test */
5948
5949 /* Initialize the PCU interface abstraction */
5950 f_init_raw(testcasename(), info_ind);
5951
5952 /* Make sure we are not affected by full cache from previous tests */
5953 f_pcuvty_flush_neigh_caches();
5954
5955 /* Establish BSSGP connection to the PCU */
5956 f_bssgp_establish();
5957 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5958
5959 /* Send PACKET RESOURCE REQUEST */
5960 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5961 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5962 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5963
5964 /* Start NACC from MS side */
5965 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5966 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5967
5968 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005969 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005970 /* RIM procedure: */
5971 as_outbound_nacc_rim_resolve(info_ind);
5972
5973 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
5974 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5975 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5976 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5977
5978 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005979 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005980 /* RIM procedure: */
5981 as_outbound_nacc_rim_resolve(info_ind);
5982 /* Transmit SI back to MS */
5983 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5984
5985 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5986 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5987 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5988 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5989 f_shutdown(__BFILE__, __LINE__);
5990 }
5991 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5992 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5993 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5994 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5995 }
5996}
5997
5998/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
5999testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6000 var PollFnCtx pollctx;
6001 var GprsMS ms;
6002 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6003 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6004 var RlcmacDlBlock dl_block;
6005 var uint32_t sched_fn;
6006 var CtrlMessage rx_ctrl;
6007 var GsmArfcn req_arfcn := 862;
6008 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006009 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006010
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006011 if (use_old_ctrl_iface) {
6012 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6013 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6014 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006015
6016 /* Initialize NS/BSSGP side */
6017 f_init_bssgp();
6018 /* Initialize GPRS MS side */
6019 f_init_gprs_ms();
6020 ms := g_ms[0]; /* We only use first MS in this test */
6021
6022 /* Initialize the PCU interface abstraction */
6023 f_init_raw(testcasename(), info_ind);
6024
6025 /* Make sure we are not affected by full cache from previous tests */
6026 f_pcuvty_flush_neigh_caches();
6027
6028 /* Establish BSSGP connection to the PCU */
6029 f_bssgp_establish();
6030 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6031
6032 /* Send PACKET RESOURCE REQUEST */
6033 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6034 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6035 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6036
6037 /* Start NACC from MS side */
6038 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6039 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6040
6041 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006042 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006043 /* RIM procedure: */
6044 as_outbound_nacc_rim_resolve(info_ind);
6045
6046 /* Announce SI back to MS, continue NACC procedure */
6047 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6048
6049 /* trigger a Pkt Cell Change Notif with different tgt cell */
6050 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6051 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6052
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006053 /* It should trigger RAC_CI resolution to start again: */
6054 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6055
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006056 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6057 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6058
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006059 /* RIM procedure: */
6060 as_outbound_nacc_rim_resolve(info_ind);
6061 /* Transmit SI back to MS */
6062 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6063
6064 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6065 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6066 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6067 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6068 f_shutdown(__BFILE__, __LINE__);
6069 }
6070 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6071 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6072 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6073 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6074 }
6075}
6076
6077/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6078testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6079 var PollFnCtx pollctx;
6080 var GprsMS ms;
6081 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6082 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6083 var RlcmacDlBlock dl_block;
6084 var uint32_t sched_fn;
6085 var CtrlMessage rx_ctrl;
6086 var GsmArfcn req_arfcn := 862;
6087 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006088 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006089
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006090 if (use_old_ctrl_iface) {
6091 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6092 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6093 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006094
6095 /* Initialize NS/BSSGP side */
6096 f_init_bssgp();
6097 /* Initialize GPRS MS side */
6098 f_init_gprs_ms();
6099 ms := g_ms[0]; /* We only use first MS in this test */
6100
6101 /* Initialize the PCU interface abstraction */
6102 f_init_raw(testcasename(), info_ind);
6103
6104 /* Make sure we are not affected by full cache from previous tests */
6105 f_pcuvty_flush_neigh_caches();
6106
6107 /* Establish BSSGP connection to the PCU */
6108 f_bssgp_establish();
6109 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6110
6111 /* Send PACKET RESOURCE REQUEST */
6112 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6113 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6114 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6115
6116 /* Start NACC from MS side */
6117 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6118 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6119
6120 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006121 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006122 /* RIM procedure: */
6123 as_outbound_nacc_rim_resolve(info_ind);
6124
6125 /* Announce SI back to MS, continue NACC procedure */
6126 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6127
6128 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6129 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6130 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6131 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6132 f_shutdown(__BFILE__, __LINE__);
6133 }
6134
6135 /* trigger a Pkt Cell Change Notif with different tgt cell */
6136 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6137 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6138
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006139 /* It should trigger RAC_CI resolution to start again: */
6140 /* When using new PCUIF interface for resolution, we must
6141 * PCUIF.receive() here since that's the first message in the PCUIF
6142 * queue that PCU will have sent. Calling other functions doing
6143 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6144 * due to unexpected message receive. */
6145 if (not use_old_ctrl_iface) {
6146 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6147 }
6148
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006149 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6150 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6151 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6152 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6153 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006154
6155 /* When using CTRL interface, we must schedule the ACK before (see
6156 * above) blocking here waiting for the resoltion, otherwise we'll be
6157 * too late scheduling by the time the resolution is done. */
6158 if (use_old_ctrl_iface) {
6159 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6160 }
6161
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006162 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6163 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6164
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006165 /* RIM procedure: */
6166 as_outbound_nacc_rim_resolve(info_ind);
6167 /* Transmit SI back to MS */
6168 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6169
6170 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6171 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6172 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6173 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6174 f_shutdown(__BFILE__, __LINE__);
6175 }
6176 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6177 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6178 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6179 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6180 }
6181}
6182
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006183/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6184testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6185 var PollFnCtx pollctx;
6186 var GprsMS ms;
6187 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6188 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6189 var RlcmacDlBlock dl_block;
6190 var uint32_t sched_fn, dl_fn;
6191 var CtrlMessage rx_ctrl;
6192 var GsmArfcn req_arfcn := 862;
6193 var uint6_t req_bsic := 43;
6194 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006195 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006196
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006197 if (use_old_ctrl_iface) {
6198 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6199 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6200 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006201
6202 /* Initialize NS/BSSGP side */
6203 f_init_bssgp();
6204 /* Initialize GPRS MS side */
6205 f_init_gprs_ms();
6206 ms := g_ms[0]; /* We only use first MS in this test */
6207
6208 /* Initialize the PCU interface abstraction */
6209 f_init_raw(testcasename(), info_ind);
6210
6211 /* Make sure we are not affected by full cache from previous tests */
6212 f_pcuvty_flush_neigh_caches();
6213
6214 /* Establish BSSGP connection to the PCU */
6215 f_bssgp_establish();
6216 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6217
6218 /* Send PACKET RESOURCE REQUEST */
6219 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6220 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6221 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6222
6223 /* Start NACC from MS side */
6224 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6225 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6226
6227 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006228 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006229 /* RIM procedure: */
6230 as_outbound_nacc_rim_resolve(info_ind);
6231
6232 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6233 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6234 f_sleep(0.1);
6235 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6236 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6237
6238 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6239 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6240 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6241 * Data with unassigned DL TBF in line above): */
6242 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6243 /* Continue receiving Pkt Cell Neighbor Data */
6244 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6245
6246 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6247 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6248 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6249 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6250 f_shutdown(__BFILE__, __LINE__);
6251 }
6252 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6253 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6254 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6255 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6256 }
6257
6258 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6259 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6260 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6261 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6262 f_dl_block_ack_fn(dl_block, dl_fn));
6263}
6264
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006265
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006266function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6267runs on RAW_PCU_Test_CT
6268{
6269 var template (value) RAN_Information_Request_RIM_Container req_cont;
6270 var template (value) PDU_BSSGP bssgp_rim_pdu;
6271 var template PDU_BSSGP bssgp_rim_pdu_expect;
6272 var template RAN_Information_RIM_Container rim_cont_expect;
6273 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006274
6275 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006276 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);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006277 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006278 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);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006279 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006280 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);
6281 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006282 f_sleep(1.0);
6283
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006284 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006285
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006286 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6287 ts_RIM_Sequence_Number(1),
6288 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6289 ts_RIM_Protocol_Version_Number(1),
6290 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6291 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006292 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6293 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006294
6295 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6296 tr_RIM_Sequence_Number(1),
6297 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6298 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006299 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 3, si_default)),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006300 omit);
6301
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006302 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6303 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006304 rim_cont_expect);
6305 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006306 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006307 T.start;
6308 alt {
6309 [] RIM.receive(bssgp_rim_pdu_expect) { }
6310 [] RIM.receive {
6311 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6312 }
6313 [] T.timeout {
6314 setverdict(fail, "No BSSGP RIM PDU received");
6315 mtc.stop;
6316 }
6317 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006318}
6319/* Send a RIM RAN info request to the PCU and verify the response, we expect
6320 * getting the system information back which we have transfered to the PCU via
6321 * PCUIF on startup. */
6322testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6323 /* Initialize NS/BSSGP side */
6324 f_init_bssgp();
6325
6326 /* Initialize the PCU interface abstraction */
6327 f_init_raw(testcasename());
6328
6329 /* Establish BSSGP connection to the PCU */
6330 f_bssgp_establish();
6331
6332 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6333 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6334
6335 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6336 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6337
6338 f_shutdown(__BFILE__, __LINE__, final := true);
6339}
6340
6341/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6342 * Routing information, to verify PCU handles that kind of address just fine
6343 */
6344testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6345 /* Initialize NS/BSSGP side */
6346 f_init_bssgp();
6347
6348 /* Initialize the PCU interface abstraction */
6349 f_init_raw(testcasename());
6350
6351 /* Establish BSSGP connection to the PCU */
6352 f_bssgp_establish();
6353
6354 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6355 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6356
6357 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6358 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006359
6360 f_shutdown(__BFILE__, __LINE__, final := true);
6361}
6362
6363/* Same as above, but in this case we simulate the rare case in which the PCU
6364 * has no system information available. We expect getting a response back but
6365 * with no system information inside. */
6366testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006367 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006368 var PCUIF_Message pcu_msg;
6369 timer T := 2.0;
6370
6371 /* Initialize NS/BSSGP side */
6372 f_init_bssgp();
6373
6374 /* Initialize the PCU interface abstraction */
6375 f_init_raw(testcasename(), info_ind);
6376
6377 /* Establish BSSGP connection to the PCU */
6378 f_bssgp_establish();
6379
6380 /* Clear sysinfo from the PCU */
6381 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);
6382 BTS.send(si1_data_ind);
6383 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);
6384 BTS.send(si3_data_ind);
6385 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);
6386 BTS.send(si16_data_ind);
6387 f_sleep(1.0);
6388
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006389 var RIM_Routing_Address dst_addr;
6390 var RIM_Routing_Address src_addr;
6391 var template (value) RAN_Information_Request_RIM_Container req_cont;
6392 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006393 var template PDU_BSSGP bssgp_rim_pdu_expect;
6394 var template RAN_Information_RIM_Container rim_cont_expect;
6395
6396 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006397 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6398 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006399
6400 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6401 ts_RIM_Sequence_Number(1),
6402 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6403 ts_RIM_Protocol_Version_Number(1),
6404 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6405 omit);
6406 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6407 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6408 req_cont);
6409
6410
6411 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6412 tr_RIM_Sequence_Number(1),
6413 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6414 tr_RIM_Protocol_Version_Number(1),
6415 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6416 omit);
6417
6418 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6419 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6420 rim_cont_expect);
6421 RIM.send(bssgp_rim_pdu);
6422 T.start;
6423 alt {
6424 [] RIM.receive(bssgp_rim_pdu_expect) { }
6425 [] RIM.receive {
6426 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6427 }
6428 [] T.timeout {
6429 setverdict(fail, "No BSSGP RIM PDU received");
6430 mtc.stop;
6431 }
6432 }
6433
6434 f_shutdown(__BFILE__, __LINE__, final := true);
6435}
6436
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006437/* Verify PCU schedule idle blocks (len=0) if no TBF attached to it. See OS#4772, SYS#4919 */
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006438testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6439 var PCUIF_info_ind info_ind;
6440 var template (value) TsTrxBtsNum nr;
6441 var RlcmacDlBlock dl_block;
6442 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006443 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006444 timer T;
6445
6446 /* Initialize NS/BSSGP side */
6447 f_init_bssgp();
6448
6449 info_ind := valueof(ts_PCUIF_INFO_default);
6450 /* The 2 first TRX are enabled. */
6451 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6452 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6453 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6454
6455 /* Initialize the PCU interface abstraction */
6456 f_init_raw(testcasename(), info_ind);
6457
6458 /* Establish BSSGP connection to the PCU */
6459 f_bssgp_establish();
6460
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006461 for (ts := 0; ts < 2; ts := ts + 1) {
6462 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006463
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006464 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6465 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6466 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6467 T.start(0.5);
6468 alt {
6469 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6470 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6471 omit)) -> value data_msg {
6472 setverdict(pass);
6473 T.stop;
6474 }
6475 [] as_rx_fail_dummy(nr);
6476 [] BTS.receive {
6477 setverdict(fail, "Unexpected block from BTS");
6478 f_shutdown(__BFILE__, __LINE__);
6479 }
6480 [] T.timeout {
6481 setverdict(fail, "Expected IDLE block from BTS");
6482 f_shutdown(__BFILE__, __LINE__);
6483 }
6484 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006485 }
6486
6487 f_shutdown(__BFILE__, __LINE__, final := true);
6488}
6489
Oliver Smith3d174882021-09-03 11:38:51 +02006490/* Test stats for available and occupied PDCHs */
6491testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6492 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6493 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6494
6495 /* Initialize NS/BSSGP side */
6496 f_init_bssgp();
6497
Oliver Smithedcded22021-09-14 09:26:55 +02006498 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6499 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6500 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6501 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6502 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6503 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006504
Oliver Smith72d0c692021-09-08 10:03:52 +02006505 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006506 f_init_gprs_ms(4);
6507
6508 /* Initialize the PCU interface abstraction */
6509 f_init_raw(testcasename(), info_ind);
6510
6511 /* Reset stats */
6512 f_statsd_reset();
6513
6514 /* Establish BSSGP */
6515 f_bssgp_establish();
6516
6517 /* 8 PDCHs available, 0 occupied */
6518 var StatsDExpects expect := {
6519 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006520 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6521 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6522 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006523 };
6524 f_statsd_expect(expect);
6525
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006526 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006527 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006528 f_ms_establish_ul_tbf(g_ms[0]);
6529 f_ms_establish_ul_tbf(g_ms[1]);
6530 f_ms_establish_ul_tbf(g_ms[2]);
6531 f_ms_establish_ul_tbf_2phase_access(g_ms[3], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[3].tlli, ms_racap_egprs_def));
Oliver Smith3d174882021-09-03 11:38:51 +02006532
6533 /* 4 PDCHs occupied */
6534 expect := {
6535 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006536 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6537 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6538 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006539 };
6540 f_statsd_expect(expect);
6541
6542 f_shutdown(__BFILE__, __LINE__, final := true);
6543}
6544
Oliver Smithf04762d2021-09-14 17:20:38 +02006545/* Test stats for available and occupied PDCHs, for MS which is not known by
6546 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6547 * data arrives from SGSN) */
6548function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6549 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6550 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6551
6552 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6553 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6554 gprsmultislotclass := '00001'B,
6555 gprsextendeddynalloccap := '0'B
6556 };
6557 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6558 egprsmultislotclass := '00001'B,
6559 egprsextendeddynalloccap := '0'B
6560 };
6561 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6562 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6563 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6564 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6565
6566 /* Initialize NS/BSSGP side */
6567 f_init_bssgp();
6568
6569 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6570 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6571 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6572 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6573 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6574 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6575
6576 /* Allocate 1 GprsMS instance */
6577 f_init_gprs_ms(1);
6578
6579 /* Initialize the PCU interface abstraction */
6580 f_init_raw(testcasename(), info_ind);
6581
6582 /* Reset stats */
6583 f_statsd_reset();
6584
6585 /* Establish BSSGP */
6586 f_bssgp_establish();
6587
6588 /* 8 PDCHs available, 0 occupied */
6589 var StatsDExpects expect := {
6590 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6591 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6592 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6593 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6594 };
6595 f_statsd_expect(expect);
6596
6597 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6598 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6599
6600 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6601 var octetstring data := f_rnd_octstring(1400);
6602 if (egprs) {
6603 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6604 } else {
6605 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6606 }
6607 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6608
6609 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6610 f_sleep(X2002);
6611
6612 /* 1 PDCH occupied */
6613 if (egprs) {
6614 expect := {
6615 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6616 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6617 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6618 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6619 };
6620 } else {
6621 expect := {
6622 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6623 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6624 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6625 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6626 };
6627 }
6628 f_statsd_expect(expect);
6629
6630 /* Clean up */
6631 f_shutdown(__BFILE__, __LINE__, final := true);
6632}
6633testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6634 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6635}
6636testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6637 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6638}
6639
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006640/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6641testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
6642 var PCUIF_info_ind info_ind;
6643 var template IARRestOctets rest;
6644 var BIT11 ra11;
6645
6646 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006647
6648 /* Only the first TRX is enabled. */
6649 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
6650 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6651
6652 /* Initialize the PCU interface abstraction */
6653 f_init_raw(testcasename(), info_ind);
6654 f_statsd_reset();
6655
6656 var EGPRSPktChRequest req := {
6657 one_phase := {
6658 tag := '0'B,
6659 multislot_class := '10101'B,
6660 priority := '01'B,
6661 random_bits := '101'B
6662 }
6663 };
6664
6665 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
6666 for (var integer i := 0; i < 7; i := i + 1) {
6667 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
6668 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
6669 }
6670
6671 ra11 := enc_EGPRSPktChRequest2bits(req);
6672 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
6673
6674 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01006675 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006676
6677 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
6678 f_sleep(2.0);
6679 var StatsDExpects expect := {
6680 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
6681 };
6682 f_statsd_expect(expect);
6683
6684 f_shutdown(__BFILE__, __LINE__, final := true);
6685}
6686
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006687control {
6688 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01006689 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006690 execute( TC_ta_ptcch_idle() );
6691 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02006692 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006693 execute( TC_ta_idle_dl_tbf_ass() );
6694 execute( TC_ta_ptcch_ul_multi_tbf() );
6695 execute( TC_cs_lqual_ul_tbf() );
6696 execute( TC_cs_initial_ul() );
6697 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01006698 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01006699 execute( TC_cs_max_dl() );
6700 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01006701 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01006702 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01006703 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01006704 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02006705 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01006706 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02006707 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01006708 execute( TC_x2031_t3191() );
6709 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006710 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01006711 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01006712 execute( TC_t3172_wait_ind_size0() );
6713 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02006714 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02006715 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02006716 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006717 execute( TC_mo_ping_pong() );
6718 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02006719 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006720 execute( TC_mt_ping_pong() );
6721 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006722 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006723 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07006724 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006725 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01006726 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006727 execute( TC_paging_cs_from_bts() );
6728 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
6729 execute( TC_paging_cs_from_sgsn_sign() );
6730 execute( TC_paging_cs_from_sgsn_ptp() );
6731 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
6732 execute( TC_paging_ps_from_sgsn_sign() );
6733 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01006734 execute( TC_paging_pch_timeout() );
6735
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07006736 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
6737 execute( TC_paging_cs_multi_ms_imsi() );
6738 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02006739 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
6740 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01006741 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
6742 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006743
6744 /* EGPRS specific test cases */
6745 execute( TC_egprs_pkt_chan_req_signalling() );
6746 execute( TC_egprs_pkt_chan_req_one_phase() );
6747 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07006748 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07006749 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07006750 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02006751
6752 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07006753
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006754 /* Immediate Assignment on AGCH/PCH */
6755 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
6756 execute( TC_pcuif_fh_imm_ass_ul() );
6757 execute( TC_pcuif_fh_imm_ass_dl() );
6758 /* Packet Uplink/Downlink Assignment on PACCH */
6759 execute( TC_pcuif_fh_pkt_ass_ul() );
6760 execute( TC_pcuif_fh_pkt_ass_dl() );
6761 execute( TC_multitrx_multims_alloc() );
6762 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
6763 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
6764 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02006765 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02006766 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01006767 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
6768 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006769
Pau Espin Pedrole1303052020-11-16 11:13:51 +01006770 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07006771
6772 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01006773 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01006774 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006775 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01006776 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01006777 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006778 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006779 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
6780 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006781 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
6782 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
6783 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006784 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
6785 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006786 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
6787 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
6788 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006789 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006790 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
6791 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
6792 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
6793 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006794
6795 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006796 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006797 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006798
6799 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02006800
6801 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02006802 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
6803 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006804 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006805}
6806
Harald Weltea419df22019-03-21 17:23:04 +01006807}