blob: cab70e8e3e57cd9cef9bbc31d8d9598dc0070e01 [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;
Vadim Yanitskiy150d6d12022-10-20 19:10:04 +070025import from GSM_RestOctets all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020026
27import from Osmocom_VTY_Functions all;
28import from TELNETasp_PortType all;
29
30import from MobileL3_GMM_SM_Types all;
31import from RLCMAC_CSN1_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020032import from RLCMAC_CSN1_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020033import from RLCMAC_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020034import from RLCMAC_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020035
36import from MobileL3_CommonIE_Types all;
37import from L3_Templates all;
38
39import from NS_Types all;
40import from BSSGP_Types all;
41import from Osmocom_Gb_Types all;
42
43import from BSSGP_Emulation all; /* BssgpConfig */
44import from NS_Emulation all; /* NSConfiguration */
45
46import from UD_Types all;
47import from PCUIF_Types all;
48import from PCUIF_CodecPort all;
49import from PCUIF_Components all;
50import from IPL4asp_Types all;
51import from Native_Functions all;
52import from SGSN_Components all;
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +020053import from GPRS_Components all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020054
Daniel Willmann535aea62020-09-21 13:27:08 +020055import from StatsD_Types all;
56import from StatsD_CodecPort all;
57import from StatsD_CodecPort_CtrlFunct all;
58import from StatsD_Checker all;
59
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010060import from IPA_Emulation all;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +010061import from Osmocom_CTRL_Types all;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010062import from Osmocom_CTRL_Adapter all;
63import from Osmocom_CTRL_Functions all;
64
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020065modulepar {
66 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
67
68 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Daniel Willmann535aea62020-09-21 13:27:08 +020069
70 charstring mp_pcu_statsd_ip := "127.0.0.1";
71 integer mp_pcu_statsd_port := 8125;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010072
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +020073 charstring mp_ctrl_neigh_ip := ""; /* Use new PCUIF over IPA multiplex for Neigh Addr Resolution */
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010074 integer mp_ctrl_neigh_port := 4248;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020075}
76
77
78/* 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 +010079friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
80:= {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070081 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010082 flags := flags,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +010083 trx := ts_PCUIF_InfoTrxs_def(GPRS_Components.mp_base_arfcn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020084 bsic := 7,
85 mcc := 262,
86 mnc := 42,
87 mnc_3_digits := 0,
88 lac := 13135,
89 rac := 0,
90 nsei := mp_nsconfig.nsei,
91 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
92 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
93 cell_id := 20960,
94 repeat_time := 5 * 50,
95 repeat_count := 3,
Harald Welte5339b2e2020-10-04 22:52:56 +020096 bvci := mp_gb_cfg.bvc[0].bvci,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020097 t3142 := 20,
98 t3169 := 5,
99 t3191 := 5,
100 t3193_10ms := 160,
101 t3195 := 5,
Pau Espin Pedrol76de1662021-03-01 17:40:58 +0100102 n3101 := 10,
103 n3103 := 4,
104 n3105 := 8,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200105 cv_countdown := 15,
106 dl_tbf_ext := 250 * 10, /* ms */
107 ul_tbf_ext := 250 * 10, /* ms */
108 initial_cs := 2,
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100109 initial_mcs := 1,
Harald Welte90f19742020-11-06 19:34:40 +0100110 nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
111 local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
112 remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +0100113 remote_addr := f_PCUIF_RemoteAddr(
Philipp Maiere0666ea2023-11-01 16:55:45 +0100114 f_PCUIF_AF2addr_type(mp_nsconfig.nsvc[0].provider.ip.address_family), mp_nsconfig.nsvc[0].provider.ip.local_ip),
Philipp Maier7c66d802023-11-28 12:35:51 +0100115 bts_model := PCU_IF_BTS_MODEL_TRX
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200116}
117
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100118/* Passed in RAN-INFO message from emulated neighbor using RIM */
119const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
120const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
121const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
122const octetstring si_default := si1_default & si3_default & si13_default;
123
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +0100124const MultislotCap_GPRS mscap_gprs_def := {
125 gprsmultislotclass := '00011'B,
126 gprsextendeddynalloccap := '0'B
127};
128const MultislotCap_EGPRS mscap_egprs_def := {
129 egprsmultislotclass := '00011'B,
130 egprsextendeddynalloccap := '0'B
131};
132template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
133template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
134
135const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
136 gprsmultislotclass := '00011'B,
137 gprsextendeddynalloccap := '0'B
138};
139const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
140 egprsmultislotclass := '00011'B,
141 egprsextendeddynalloccap := '0'B
142};
143template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
144template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
145
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200146type record lqual_range {
147 /* component reference to the IPA_Client component used for RSL */
148 uint8_t low,
149 uint8_t high
150}
151
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100152type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700153 /* PCU interface abstraction component */
154 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700155
Daniel Willmann535aea62020-09-21 13:27:08 +0200156 /* StatsD */
157 var StatsD_Checker_CT vc_STATSD;
158
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200159 /* Connection to the PCUIF component */
Pau Espin Pedrolc77743d2024-04-12 21:17:39 +0200160 //port RAW_PCU_MSG_PT PCUIF;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200161 /* VTY connection to the PCU */
162 port TELNETasp_PT PCUVTY;
163
164 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
165 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
166 {low := 5, high := 8},
167 {low := 7, high := 13},
168 {low := 12,high := 35}};
169 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
170 {low := 5, high := 8},
171 {low := 7, high := 13},
172 {low := 12,high := 15},
173 {low := 14, high := 17},
174 {low := 16, high := 18},
175 {low := 17,high := 20},
176 {low := 19, high := 24},
177 {low := 23,high := 35}};
178 var uint8_t g_cs_initial_dl := 1;
179 var uint8_t g_cs_initial_ul := 1;
180 var uint8_t g_mcs_initial_dl := 1;
181 var uint8_t g_mcs_initial_ul := 1;
182 var uint8_t g_cs_max_dl := 4;
183 var uint8_t g_cs_max_ul := 4;
184 var uint8_t g_mcs_max_dl := 9;
185 var uint8_t g_mcs_max_ul := 9;
186
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200187 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200188
189 /* Guard timeout */
190 timer g_T_guard := 60.0;
191};
192
193private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
194 [] g_T_guard.timeout {
195 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700196 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200197 }
198}
199
200private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
201 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
202 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
203
204 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
205 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
206}
207
208private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
209 var charstring cmd;
210
211 cmd := "cs link-quality-ranges" &
212 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
213 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
214 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
215 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
216 f_vty_config2(PCUVTY, {"pcu"}, cmd);
217
218 cmd := "mcs link-quality-ranges" &
219 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
220 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
221 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
222 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
223 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
224 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
225 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
226 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
227 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
228 f_vty_config2(PCUVTY, {"pcu"}, cmd);
229}
230
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100231private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
232 f_pcuvty_set_neigh_caches(0, 0);
233}
234
235private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
236runs on RAW_PCU_Test_CT {
237 if (neigh_cache_secs == -1) {
238 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
239 } else {
240 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
241 }
242 if (si_cache_secs == -1) {
243 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
244 } else {
245 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
246 }
247}
248
Pau Espin Pedrole8a94442021-11-15 17:05:46 +0100249private function f_pcuvty_set_timer(integer t, integer val)
250runs on RAW_PCU_Test_CT {
251 if (t >= 0) {
252 f_vty_config2(PCUVTY, {"pcu"}, "timer T" & int2str(t) & " " & int2str(val));
253 } else {
254 f_vty_config2(PCUVTY, {"pcu"}, "timer X" & int2str(t * -1) & " " & int2str(val));
255 }
256}
257
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100258private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200259 map(self:PCUVTY, system:PCUVTY);
260 f_vty_set_prompts(PCUVTY);
261 f_vty_transceive(PCUVTY, "enable");
262
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100263 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
264 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200265 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
266 } else {
267 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
268 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200269
270 if (g_force_two_phase_access) {
271 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
272 } else {
273 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
274 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200275}
276
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200277function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200278runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200279 /* Start the guard timer */
280 g_T_guard.start;
281 activate(as_Tguard_RAW());
282
283 /* Init PCU interface component */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100284 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF") alive;
Pau Espin Pedrolc77743d2024-04-12 21:17:39 +0200285 //connect(vc_PCUIF:MTC, self:PCUIF);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200286 map(vc_PCUIF:PCU, system:PCU);
287
288 /* Create one BTS component (we may want more some day) */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100289 vc_BTS := RAW_PCU_BTS_CT.create("BTS") alive;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200290 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
291 connect(vc_BTS:TC, self:BTS);
292
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100293 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200294
Daniel Willmann535aea62020-09-21 13:27:08 +0200295 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
296 /* This is normally done in the ConnHdlr component, but here
297 * the Test_CT doubles as ConnHdlr */
298 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
299
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200300 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100301 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200302
303 /* Wait until the BTS is ready (SI13 negotiated) */
304 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
305}
306
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700307/* Register TLLI of each allocated GprsMS instance */
308private function f_multi_ms_bssgp_register()
309runs on RAW_PCU_Test_CT {
310 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
311 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
312 }
313}
314
315/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
316private function f_multi_ms_establish_tbf(boolean do_activate := false)
317runs on RAW_PCU_Test_CT {
318 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
319 /* Establish an Uplink TBF */
320 f_ms_establish_ul_tbf(g_ms[i]);
321
322 /* Send a random block, so this TBF becomes "active" */
323 if (do_activate) {
324 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100325 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700326 var octetstring dummy := f_rnd_octstring(12);
327 var RlcmacDlBlock dl_block;
328 var uint32_t poll_fn;
329
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200330 /* Wait until PCU starts requesting for UL block on this TBF: */
331 f_ms_wait_usf(g_ms[i]);
332
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200333 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 +0700334 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
335 }
336 }
337}
338
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100339private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
340 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
341runs on RAW_PCU_Test_CT return PollFnCtx {
342 var PollFnCtx pollctx;
343
344 /* Single block (two phase) packet access */
345 var uint16_t ra := bit2int(chan_req_sb);
346 if (g_force_two_phase_access) {
347 /* If 2phase access is enforced by the network, then let's
348 * request a One phase packet access, we'll receive a single block
349 * anyway
350 */
351 ra := bit2int(chan_req_def);
352 }
353
354 /* Establish an Uplink TBF */
355 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
356 f_ms_establish_ul_tbf(ms);
357
358 /* Make sure we've got an Uplink TBF assignment */
359 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
360 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
361 f_shutdown(__BFILE__, __LINE__);
362 }
363
364 /* Send PACKET RESOURCE REQUEST
365 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
366 */
367 if (istemplatekind(pkt_res_req, "omit")) {
368 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
369 }
370
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200371 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 +0100372 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100373 * overwrite the TS allocation on MS with info from new UL TBF:
374 */
375 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
376 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
377 return pollctx;
378}
379
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200380testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200381 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100382 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200383 timer T;
384
385 /* Initialize NS/BSSGP side */
386 f_init_bssgp();
387
388 /* Initialize the PCU interface abstraction */
389 f_init_raw(testcasename());
390
391 /* Establish BSSGP connection to the PCU */
392 f_bssgp_establish();
393
394 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
395
396 T.start(2.0);
397 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100398 [] 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 +0200399 setverdict(pass);
400 }
401 [] T.timeout {
402 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
403 }
404 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700405
406 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200407}
408
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100409/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
410testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
411 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200412 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100413 var RlcmacDlBlock dl_block;
414 var octetstring data := f_rnd_octstring(10);
415 var uint32_t sched_fn;
416 var uint32_t dl_fn;
417 var GprsMS ms;
418 timer T;
419
420 /* Initialize NS/BSSGP side */
421 f_init_bssgp();
422 /* Initialize GPRS MS side */
423 f_init_gprs_ms();
424 ms := g_ms[0]; /* We only use first MS in this test */
425
426 /* Initialize the PCU interface abstraction */
427 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
428
429 /* Establish BSSGP connection to the PCU */
430 f_bssgp_establish();
431 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
432
433 /* Establish an Uplink TBF */
434 f_ms_establish_ul_tbf(ms);
435
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200436 /* Wait until PCU starts requesting for UL block on this TBF: */
437 f_ms_wait_usf(ms);
438
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100439 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200440 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200441 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 +0100442 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
443 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
444 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
445
446 /* UL block should be received in SGSN */
447 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
448
449 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +0200450 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +0200451 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100452
453 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
454 f_sleep(X2002);
455 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
456
457 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
458 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
459
460 T.start(2.0);
461 alt {
462 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
463 setverdict(pass);
464 }
465 [] T.timeout {
466 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
467 f_shutdown(__BFILE__, __LINE__);
468 }
469 }
470
471 /* Make sure we don't receive data for that TBF since it was released
472 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200473 f_pcuif_rx_data_req_pdtch(data_msg);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100474 if (data_msg.dl_block == omit) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200475 /* IDLE block, expected on new PCU versions */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200476 } else {
477 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100478 f_shutdown(__BFILE__, __LINE__);
479 }
480
481 /* New data arrives, PCU should page the MS since no TBF active exists: */
482 /* Send some more data, it will never reach the MS */
Philipp Maier7f064e62023-09-22 16:38:19 +0200483 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +0200484 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100485
486 f_shutdown(__BFILE__, __LINE__, final := true);
487}
488
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200489/* Test of correct Timing Advance at the time of TBF establishment
490 * (derived from timing offset of the Access Burst). */
491testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200492 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200493
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200494 /* Initialize GPRS MS side */
495 f_init_gprs_ms();
496 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200497 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100498 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200499
500 /* We cannot send too many TBF requests in a short time because
501 * at some point the PCU will fail to allocate a new TBF. */
502 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
503 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200504 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700505 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200506
507 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200508 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700509 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200510 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700511 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700512 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200513 }
514 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700515
516 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200517}
518
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200519/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
520 * sent in response to the first Uplink block after resource allocation. */
521testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
522 var GprsMS ms := valueof(t_GprsMS_def);
523 var PacketUlAckNack ul_ack_nack;
524 var PacketTimingAdvance pkt_ta;
525 var RlcmacDlBlock dl_block;
526 var uint32_t sched_fn;
527
528 /* Initialize NS/BSSGP side */
529 f_init_bssgp();
530
531 /* Initialize the PCU interface abstraction */
532 f_init_raw(testcasename());
533
534 /* Establish BSSGP connection to the PCU */
535 f_bssgp_establish();
536 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
537
538 /* Establish an Uplink TBF */
539 f_ms_establish_ul_tbf(ms);
540
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200541 /* Wait until PCU starts requesting for UL block on this TBF: */
542 f_ms_wait_usf(ms);
543
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200544 /* In a busy network, there can be a significant delay between resource
545 * allocation (Packet Uplink Assignment above) and the actual time when
546 * the MS is allowed to transmit the first Uplink data block. */
547
548 /* Simulate a delay > 0 */
549 ms.ta := 2;
550
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200551 /* We're in One-Phase Access contention resolution, include TLLI */
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200552 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
553 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
554
555 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
556 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
557 pkt_ta := ul_ack_nack.gprs.pkt_ta;
558 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
559 pkt_ta := ul_ack_nack.egprs.pkt_ta;
560 } else {
561 setverdict(fail, "PacketTimingAdvance IE is not present");
562 f_shutdown(__BFILE__, __LINE__);
563 }
564
565 if (not ispresent(pkt_ta.val)) {
566 setverdict(fail, "Timing Advance value is not present");
567 f_shutdown(__BFILE__, __LINE__);
568 } else if (pkt_ta.val != ms.ta) {
569 setverdict(fail, "Timing Advance mismatch: expected ",
570 ms.ta, ", but received ", pkt_ta.val);
571 f_shutdown(__BFILE__, __LINE__);
572 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +0200573
574 f_shutdown(__BFILE__, __LINE__, final := true);
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200575}
576
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200577/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
578 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
579 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
580 * no active TBF exists at the moment of establishment (idle mode). */
581testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100582 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200583
584 /* Initialize NS/BSSGP side */
585 f_init_bssgp();
586
587 /* Initialize the PCU interface abstraction */
588 f_init_raw(testcasename());
589
590 /* Establish BSSGP connection to the PCU */
591 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100592 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200593
594 /* SGSN sends some DL data, PCU will initiate Packet Downlink
595 * Assignment on CCCH (PCH). We don't care about the payload. */
Philipp Maierc49069b2023-09-22 16:32:42 +0200596 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10), imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +0200597 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200598
599 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
600 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
601 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100602 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700603 setverdict(fail, "Timing Advance value doesn't match");
604 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700605
606 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200607}
608
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200609/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200610 * while neither Uplink nor Downlink TBF is established. */
611testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100612 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200613 timer T;
614
615 /* Initialize the PCU interface abstraction */
616 f_init_raw(testcasename());
617
618 /* Sent an RTS.req for PTCCH/D */
619 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
620 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
621 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100622
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200623 T.start(5.0);
624 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200625 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
626 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
627 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200628 }
629 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100630 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
631 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200632 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200633 [] BTS.receive(PCUIF_Message:?) { repeat; }
634 [] T.timeout {
635 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700636 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200637 }
638 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100639 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700640
641 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200642}
643
644/* Test of correct Timing Advance during an active Uplink TBF.
645 *
646 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
647 * are not continuous and there can be long time gaps between them. This happens
648 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
649 * significantly change between such rare Uplink transmissions, so GPRS introduces
650 * additional mechanisms to control Timing Advance, and thus reduce interference
651 * between neighboring TDMA time-slots.
652 *
653 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
654 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
655 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
656 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
657 * among with the initial Timing Advance value. And here PTCCH comes to play.
658 *
659 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
660 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
661 * continuously. To ensure continuous measurements of the signal propagation
662 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
663 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
664 *
665 * The purpose of this test case is to verify the assignment of Timing Advance
666 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
667 * first establishes several Uplink TBFs, but does not transmit any Uplink
668 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
669 * indications to the PCU, checking the correctness of two received PTCCH/D
670 * messages (period of PTCCH/D is two multi-frames).
671 */
672
673/* List of ToA values for Access Bursts to be sent on PTCCH/U,
674 * each ToA (Timing of Arrival) value is in units of 1/4 of
675 * a symbol (i.e. 1 symbol is 4 QTA units). */
676type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
677const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
678 0, 0, 0, 0,
679 0, 0, 0, 0,
680 0, 0, 0, 0,
681 0, 0, 0, 0
682};
683
684private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
685 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
686runs on RAW_PCU_Test_CT {
687 var RAW_PCU_Event event;
688 var integer ss;
689
690 /* Send Access Bursts on PTCCH/U for every TA Index */
691 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
692 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700693 if (ss < 0) { /* Shall not happen */
694 f_shutdown(__BFILE__, __LINE__);
695 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200696
697 log("Sending an Access Burst on PTCCH/U",
698 ", sub-slot=", ss, " (TAI)",
699 ", fn=", event.data.tdma_fn,
700 ", ToA=", toa_map[ss], " (QTA)");
701 /* TODO: do we care about RA and burst format? */
702 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
703 ra := oct2int('3A'O),
704 is_11bit := 0,
705 burst_type := BURST_TYPE_0,
706 fn := event.data.tdma_fn,
707 arfcn := 871,
708 qta := toa_map[ss],
709 sapi := PCU_IF_SAPI_PTCCH));
710 repeat;
711 }
712}
713
714private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
715 template PTCCHDownlinkMsg t_ta_msg)
716runs on RAW_PCU_Test_CT {
717 var PTCCHDownlinkMsg ta_msg;
718 var PCUIF_Message pcu_msg;
719 timer T;
720
721 /* First, send an RTS.req for the upcoming PTCCH/D block */
722 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
723 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
724 arfcn := 871, block_nr := 0));
725 T.start(2.0);
726 alt {
727 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
728 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
729 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
730 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
731 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
732 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
733 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
734 log("Rx PTCCH/D message: ", ta_msg);
735
736 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700737 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200738 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
739 }
740 }
741 [] BTS.receive { repeat; }
742 [] T.timeout {
743 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200744 }
745 }
746}
747
748testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
749 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200750 var GprsMS ms;
751
752 /* Initialize GPRS MS side */
753 f_init_gprs_ms();
754 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200755
756 /* Initialize the PCU interface abstraction */
757 f_init_raw(testcasename());
758
759 /* Enable forwarding of PTCCH/U TDMA events to us */
760 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
761
762 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
763 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200764 /* Establish an Uplink TBF */
765 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200766
767 /* We expect incremental TFI/USF assignment (dynamic allocation) */
768 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200769 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200770 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700771 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200772 }
773
774 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200775 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200776 setverdict(fail, "Failed to match Timing Advance Index for #", i);
777 /* Keep going, the current OsmoPCU does not assign TA Index */
778 }
779 }
780
781 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
782 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
783 for (var integer i := 0; i < 7; i := i + 1) {
784 /* ToA in units of 1/4 of a symbol */
785 toa_map[i] := (i + 1) * 7 * 4;
786 }
787
788 /* Now we have all 7 TBFs established in one-phase access mode,
789 * however we will not be sending any data on them. Instead, we
790 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
791 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
792 *
793 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
794 * time-slots, so at the moment of scheduling a PTCCH/D block
795 * the PCU has odd number of PTCCH/U Access Bursts received. */
796 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
797 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
798 /* Other values are not known (yet) */
799 tai3_ta := ?));
800 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
801 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
802 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
803 /* Other values are out of our interest */
804 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700805
806 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200807}
808
809/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
810 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
811 *
812 * NOTE: the ranges are intentionally overlapping because OsmoPCU
813 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
814private template integer CS1_lqual_dB_range := (-infinity .. 6);
815private template integer CS2_lqual_dB_range := (5 .. 8);
816private template integer CS3_lqual_dB_range := (7 .. 13);
817private template integer CS4_lqual_dB_range := (12 .. infinity);
818
819testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200820 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200821 var GprsMS ms;
822 var uint32_t unused_fn, sched_fn;
823 var uint4_t cv;
824
825 /* Initialize GPRS MS side */
826 f_init_gprs_ms();
827 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200828
829 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100830 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200831
832 f_pcuvty_set_allowed_cs_mcs();
833 f_pcuvty_set_link_quality_ranges();
834
835 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200836 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200837
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200838 /* Wait until PCU starts requesting for UL block on this TBF: */
839 f_ms_wait_usf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200840
841 /* The actual / old link quality values. We need to keep track of the old
842 * (basically previous) link quality value, because OsmoPCU actually
843 * changes the coding scheme if not only the actual, but also the old
844 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200845 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200846 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200847
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200848 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200849 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200850 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
851 /* 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 +0200852 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 +0200853 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
854 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
855 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200856
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200857 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
858 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200859 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200860 lqual_old := ms.lqual_cb;
861 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200862
863 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200864 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
865 if (i > g_bs_cv_max) {
866 cv := 15;
867 } else {
868 cv := i;
869 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200870
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200871 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
872
873 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
874 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700875 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200876 continue;
877 }
878 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
879 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
880 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
881 f_shutdown(__BFILE__, __LINE__);
882 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200883
884 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
885 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
886
887 /* Match the received Channel Coding Command. Since we are increasing
888 * the link quality value on each iteration and not decreasing, there
889 * is no need to check the both old and current link quality values. */
890 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200891 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200892 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
893 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
894 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
895 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
896 }
897
898 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
899 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200900 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200901 }
902 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700903
904 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200905}
906
907/* Test the max UL CS set by VTY works fine */
908testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200909 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200910 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200911 var uint32_t unused_fn, sched_fn;
912 var GprsMS ms;
913
914 /* Initialize GPRS MS side */
915 f_init_gprs_ms();
916 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200917
918 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100919 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200920
921 /* Set initial UL CS to 3 */
922 g_cs_initial_ul := 3;
923 f_pcuvty_set_allowed_cs_mcs();
924 f_pcuvty_set_link_quality_ranges();
925
926 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200927 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200928
929 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200930 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200931
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200932 /* Wait until PCU starts requesting for UL block on this TBF: */
933 f_ms_wait_usf(ms);
934
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200935 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200936 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200937 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
938 /* 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 +0200939 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 +0200940 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
941 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
942 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200943
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200944 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
945 while (true) {
946 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
947 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700948 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200949 continue;
950 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200951
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200952 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
953 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
954 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
955 f_shutdown(__BFILE__, __LINE__);
956 break;
957 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200958
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200959 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200960 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200961 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200962 if (last_ch_coding != CH_CODING_CS3) {
963 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200964 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200965 }
966
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200967 /* Remaining UL blocks are used to make sure regardless of initial
968 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200969 /* 0 dB, make sure we downgrade CS */
970 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200971 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200972 f_ms_tx_ul_data_block_multi(ms, 5);
973 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
974 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
975 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200976
977 if (last_ch_coding != CH_CODING_CS1) {
978 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200979 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200980 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700981
982 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200983}
984
985/* Test the max UL CS set by VTY works fine */
986testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200987 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200988 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200989 var uint32_t unused_fn, sched_fn;
990 var GprsMS ms;
991
992 /* Initialize GPRS MS side */
993 f_init_gprs_ms();
994 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200995
996 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100997 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200998
999 /* Set maximum allowed UL CS to 3 */
1000 g_cs_max_ul := 3;
1001 f_pcuvty_set_allowed_cs_mcs();
1002 f_pcuvty_set_link_quality_ranges();
1003
1004 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001005 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001006
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02001007 /* Wait until PCU starts requesting for UL block on this TBF: */
1008 f_ms_wait_usf(ms);
1009
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001010 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02001011 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001012 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1013 /* 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 +02001014 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 +02001015 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1016 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1017 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001018
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001019 ms.lqual_cb := 40*10; /* 40 dB */
1020 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001021
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001022 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1023 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001024
1025 if (last_ch_coding != CH_CODING_CS3) {
1026 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001027 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001028 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001029
1030 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001031}
1032
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001033/* Test the initial DL CS set by VTY works fine */
1034testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1035 var octetstring data := f_rnd_octstring(10);
1036 var CodingScheme exp_dl_cs_mcs;
1037 var RlcmacDlBlock dl_block;
1038 var uint32_t poll_fn;
1039 var GprsMS ms;
1040
1041 /* Initialize NS/BSSGP side */
1042 f_init_bssgp();
1043 /* Initialize GPRS MS side */
1044 f_init_gprs_ms();
1045 ms := g_ms[0]; /* We only use first MS in this test */
1046
1047 /* Initialize the PCU interface abstraction */
1048 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1049
1050 /* Set initial allowed DL CS to 3 */
1051 g_cs_initial_dl := 3;
1052 exp_dl_cs_mcs := CS_3;
1053 /* Set maximum allowed UL CS to 4 */
1054 g_cs_max_dl := 4;
1055 f_pcuvty_set_allowed_cs_mcs();
1056 f_pcuvty_set_link_quality_ranges();
1057
1058 /* Establish BSSGP connection to the PCU */
1059 f_bssgp_establish();
1060 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1061
1062 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001063 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001064 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001065
1066 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1067 f_sleep(X2002);
1068 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1069
1070 /* ACK the DL block */
1071 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1072 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1073 f_dl_block_ack_fn(dl_block, poll_fn));
1074
1075 f_shutdown(__BFILE__, __LINE__, final := true);
1076}
1077
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001078/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001079function 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 +01001080 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001081 var RlcmacDlBlock prev_dl_block, dl_block;
1082 var uint32_t ack_fn;
1083 var uint32_t fn;
1084 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001085 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001086 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001087 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1088 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001089 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001090
1091 if (using_egprs) {
1092 exp_tmp_csmcs := mcs_egprs_any;
1093 bsn_mod := 2048;
1094 } else {
1095 exp_tmp_csmcs := cs_gprs_any;
1096 bsn_mod := 128;
1097 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001098
1099 /* Establish BSSGP connection to the PCU */
1100 f_bssgp_establish();
1101
1102 ms := g_ms[0]; /* We only use first MS in this test */
1103 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1104
1105 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001106 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001107 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001108
1109 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1110 f_sleep(X2002);
1111
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001112 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
1113 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
1114
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001115 for (var integer i := 0; i < 800; i := i + 1) {
1116 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001117
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001118 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001119 /* No more data to receive, done */
1120 break;
1121 }
1122
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001123 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001124
1125 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001126 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001127
1128 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001129 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001130 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001131 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 +01001132 if (tx_data_remain != 0) {
1133 /* Submit more data from time to time to keep the TBF ongoing */
1134 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1135 tx_data_remain := tx_data_remain - 1;
1136 }
1137 }
1138 prev_dl_block := dl_block;
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001139 f_rx_rlcmac_dl_block(dl_block, fn);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001140 }
1141
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001142 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1143 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001144
1145
1146 f_shutdown(__BFILE__, __LINE__, final := true);
1147}
1148
1149/* Verify DL CS above "cs max" set by VTY is never used */
1150testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1151 /* Initialize NS/BSSGP side */
1152 f_init_bssgp();
1153 /* Initialize GPRS MS side */
1154 f_init_gprs_ms();
1155
1156 /* Initialize the PCU interface abstraction */
1157 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1158
1159 /* Set maximum allowed DL CS to 3 */
1160 g_cs_initial_dl := 1;
1161 g_cs_max_dl := 3;
1162 f_pcuvty_set_allowed_cs_mcs();
1163 f_pcuvty_set_link_quality_ranges();
1164
1165 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001166
1167 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001168}
1169
1170/* Check DL CS4 is used in good link conditions if allowed by config */
1171testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1172 /* Initialize NS/BSSGP side */
1173 f_init_bssgp();
1174 /* Initialize GPRS MS side */
1175 f_init_gprs_ms();
1176
1177 /* Initialize the PCU interface abstraction */
1178 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1179
1180 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1181 g_cs_initial_dl := 1;
1182 g_cs_max_dl := 4;
1183 f_pcuvty_set_allowed_cs_mcs();
1184 f_pcuvty_set_link_quality_ranges();
1185
1186 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001187
1188 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001189}
1190
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001191/* Test the initial UL MCS set by VTY works fine */
1192testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1193 var RlcmacDlBlock dl_block;
1194 var PollFnCtx pollctx;
1195 var EgprsChCodingCommand last_ch_coding;
1196 var uint32_t unused_fn, sched_fn;
1197 var GprsMS ms;
1198 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001199
1200 /* Initialize GPRS MS side */
1201 f_init_gprs_ms();
1202 ms := g_ms[0]; /* We only use first MS in this test */
1203
1204 /* Initialize the PCU interface abstraction */
1205 f_init_raw(testcasename());
1206
1207 /* Set initial UL MCS to 3 */
1208 g_mcs_initial_ul := 3;
1209 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1210 f_pcuvty_set_allowed_cs_mcs();
1211 f_pcuvty_set_link_quality_ranges();
1212
1213 /* Take lqual (dB->cB) so that we stay in that MCS */
1214 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1215
1216 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001217 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 +01001218
1219 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1220 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1221 f_shutdown(__BFILE__, __LINE__);
1222 }
1223
1224 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1225 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1226
1227 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1228 while (true) {
1229 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1230 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001231 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001232 continue;
1233 }
1234
1235 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1236 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1237 f_shutdown(__BFILE__, __LINE__);
1238 break;
1239 }
1240
1241 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1242 break;
1243 }
1244 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1245 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1246 f_shutdown(__BFILE__, __LINE__);
1247 }
1248
1249 /* Remaining UL blocks are used to make sure regardless of initial
1250 * lqual, we can go lower at any time
1251 * 0 dB, make sure we downgrade MCS */
1252 ms.lqual_cb := 0;
1253 /* 5 UL blocks, check we are in same initial MCS: */
1254 f_ms_tx_ul_data_block_multi(ms, 5);
1255 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1256 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1257 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1258
1259 if (last_ch_coding != CH_CODING_MCS1) {
1260 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1261 f_shutdown(__BFILE__, __LINE__);
1262 }
1263
1264 f_shutdown(__BFILE__, __LINE__, final := true);
1265}
1266
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001267/* Test the maximum UL MCS set by VTY works fine */
1268testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1269 var RlcmacDlBlock dl_block;
1270 var EgprsChCodingCommand last_ch_coding;
1271 var PollFnCtx pollctx;
1272 var uint32_t unused_fn, sched_fn;
1273 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001274
1275 /* Initialize GPRS MS side */
1276 f_init_gprs_ms();
1277 ms := g_ms[0]; /* We only use first MS in this test */
1278
1279 /* Initialize the PCU interface abstraction */
1280 f_init_raw(testcasename());
1281
1282 /* Set maximum allowed UL MCS to 5 */
1283 g_mcs_max_ul := 5;
1284 f_pcuvty_set_allowed_cs_mcs();
1285 f_pcuvty_set_link_quality_ranges();
1286
1287 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001288 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 +01001289 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1290 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1291
1292 ms.lqual_cb := 40*10; /* 40 dB */
1293 f_ms_tx_ul_data_block_multi(ms, 16);
1294
1295 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1296 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1297
1298 if (last_ch_coding != CH_CODING_MCS5) {
1299 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1300 f_shutdown(__BFILE__, __LINE__);
1301 }
1302
1303 f_shutdown(__BFILE__, __LINE__, final := true);
1304}
1305
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001306/* Test the initial DL CS set by VTY works fine */
1307testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1308 var octetstring data := f_rnd_octstring(10);
1309 var CodingScheme exp_dl_cs_mcs;
1310 var RlcmacDlBlock dl_block;
1311 var uint32_t poll_fn;
1312 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001313
1314 /* Initialize NS/BSSGP side */
1315 f_init_bssgp();
1316 /* Initialize GPRS MS side */
1317 f_init_gprs_ms();
1318 ms := g_ms[0]; /* We only use first MS in this test */
1319
1320 /* Initialize the PCU interface abstraction */
1321 f_init_raw(testcasename());
1322
1323 /* Set initial allowed DL MCS to 3 */
1324 g_mcs_initial_dl := 3;
1325 exp_dl_cs_mcs := MCS_3;
1326 /* Set maximum allowed DL MCS to 4 */
1327 g_mcs_max_dl := 4;
1328 f_pcuvty_set_allowed_cs_mcs();
1329 f_pcuvty_set_link_quality_ranges();
1330
1331 /* Establish BSSGP connection to the PCU */
1332 f_bssgp_establish();
1333 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1334
1335 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001336 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001337 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001338
1339 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1340 f_sleep(X2002);
1341 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1342
1343 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001344 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1345 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 +01001346 f_dl_block_ack_fn(dl_block, poll_fn));
1347
1348 f_shutdown(__BFILE__, __LINE__, final := true);
1349}
1350
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001351/* Verify DL MCS above "mcs max" set by VTY is never used */
1352testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1353 /* Initialize NS/BSSGP side */
1354 f_init_bssgp();
1355 /* Initialize GPRS MS side */
1356 f_init_gprs_ms();
1357
1358 /* Initialize the PCU interface abstraction */
1359 f_init_raw(testcasename());
1360
1361 /* Set maximum allowed DL CS to 3 */
1362 g_mcs_initial_dl := 1;
1363 g_mcs_max_dl := 3;
1364 f_pcuvty_set_allowed_cs_mcs();
1365 f_pcuvty_set_link_quality_ranges();
1366
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001367 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_mcs_max_dl, true), bssgp_ms_racap_egprs_def);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001368
1369 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001370}
1371
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001372/* Verify PCU drops TBF after some time of inactivity. */
1373testcase TC_t3141() runs on RAW_PCU_Test_CT {
1374 var PCUIF_info_ind info_ind;
1375 var template (value) TsTrxBtsNum nr;
1376 var BTS_PDTCH_Block data_msg;
1377 var GprsMS ms;
1378 var uint3_t rx_usf;
1379 timer T_3141 := 1.0;
1380 var boolean ul_tbf_usf_req := false;
1381
1382 /* Initialize NS/BSSGP side */
1383 f_init_bssgp();
1384 /* Initialize GPRS MS side */
1385 f_init_gprs_ms();
1386 ms := g_ms[0]; /* We only use first MS in this test */
1387
1388 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1389 /* Only use 1 PDCH to simplify test: */
1390 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1391 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1392 /* Initialize the PCU interface abstraction */
1393 f_init_raw(testcasename(), info_ind);
1394
1395 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1396
1397 /* Establish BSSGP connection to the PCU */
1398 f_bssgp_establish();
1399 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1400
1401 /* Establish a one-phase access Uplink TBF */
1402 f_ms_establish_ul_tbf(ms);
1403
1404 T_3141.start;
1405
1406 /* Now we wait for PCU to transmit our USF */
1407 nr := ts_TsTrxBtsNum;
1408 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1409 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1410 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1411 block_nr := nr.blk_nr));
1412
1413 alt {
1414 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1415 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1416 ?)) -> value data_msg {
1417 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1418 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1419 f_shutdown(__BFILE__, __LINE__);
1420 }
1421
1422 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1423 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1424 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1425 ul_tbf_usf_req := true;
1426 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))
1427 } else if (rx_usf == USF_UNUSED) {
1428 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1429 if (ul_tbf_usf_req) {
1430 /* TBF was dropped by T3141, success */
1431 setverdict(pass);
1432 break;
1433 } else {
1434 log("PCU never requested USF, unexpected");
1435 f_shutdown(__BFILE__, __LINE__);
1436 }
1437 } /* else: Keep waiting for TBF to be active by network */
1438 } else {
1439 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1440 f_shutdown(__BFILE__, __LINE__);
1441 }
1442
1443 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1444 if (match(data_msg.dl_block,
1445 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1446 tr_UlAckNackGprs(tlli := ?,
1447 acknack_desc := ?,
1448 rel99 := *))))
1449 {
1450 log("Received UL ACK/NACK with TLLI set");
1451 f_shutdown(__BFILE__, __LINE__);
1452 }
1453
1454 nr := ts_TsTrxBtsNum;
1455 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1456 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1457 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1458 block_nr := nr.blk_nr));
1459 repeat;
1460 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001461 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1462 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1463 omit)) {
1464 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1465 our last RTS.req because there's no longer any MS listening on
1466 the TS. */
1467 setverdict(pass);
1468 break;
1469 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001470 [] T_3141.timeout {
1471 log("T_3141 expired but TBF is still active, unexpected");
1472 f_shutdown(__BFILE__, __LINE__);
1473 }
1474 [] BTS.receive {
1475 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1476 * because we never sent the TLLI to the PCU */
1477 setverdict(fail, "Unexpected BTS message");
1478 f_shutdown(__BFILE__, __LINE__);
1479 }
1480 }
1481
1482 f_shutdown(__BFILE__, __LINE__, final := true);
1483}
1484
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001485/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1486 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1487 * T3169. See OS#5033 */
1488testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1489 var PCUIF_info_ind info_ind;
1490 var template (value) TsTrxBtsNum nr;
1491 var BTS_PDTCH_Block data_msg;
1492 var GprsMS ms;
1493 var uint3_t rx_usf;
1494 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1495 var integer n3101 := 0;
1496 timer T_3169 := 1.0;
1497
1498 /* Initialize NS/BSSGP side */
1499 f_init_bssgp();
1500 /* Initialize GPRS MS side */
1501 f_init_gprs_ms();
1502 ms := g_ms[0]; /* We only use first MS in this test */
1503
1504 /* Initialize the PCU interface abstraction */
1505 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1506 info_ind.n3101 := N3101_MAX;
1507 info_ind.t3169 := 1;
1508 f_init_raw(testcasename(), info_ind);
1509
1510 /* Establish BSSGP connection to the PCU */
1511 f_bssgp_establish();
1512 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1513
1514 /* Establish UL TBF */
1515 f_ms_establish_ul_tbf(ms);
1516
1517 /* Now we wait for PCU to transmit our USF */
1518 nr := ts_TsTrxBtsNum;
1519 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1520 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1521 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1522 block_nr := nr.blk_nr));
1523
1524 alt {
1525 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1526 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1527 ?)) -> value data_msg {
1528 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1529 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1530 f_shutdown(__BFILE__, __LINE__);
1531 }
1532
1533 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1534 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1535 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1536 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001537 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1538 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001539 f_shutdown(__BFILE__, __LINE__);
1540 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001541 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001542 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1543 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1544 if (not T_3169.running) {
1545 log("T3169 started");
1546 T_3169.start;
1547 }
1548 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1549 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1550 f_shutdown(__BFILE__, __LINE__);
1551 } else {
1552 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1553 }
1554 nr := ts_TsTrxBtsNum;
1555 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1556 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1557 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1558 block_nr := nr.blk_nr));
1559 repeat;
1560 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001561 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1562 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001563 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001564 [] T_3169.timeout {
1565 log("T_3169 expired");
1566 /* Done in alt */
1567 }
1568 [] BTS.receive {
1569 setverdict(fail, "Unexpected BTS message");
1570 f_shutdown(__BFILE__, __LINE__);
1571 }
1572 }
1573
1574 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1575 /* USFs as per previous TBF since they were freed at expiration time: */
1576 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1577 var uint5_t old_tfi := ms.ul_tbf.tfi;
1578 f_ms_establish_ul_tbf(ms);
1579 if (old_tfi != ms.ul_tbf.tfi) {
1580 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1581 f_shutdown(__BFILE__, __LINE__);
1582 }
1583 for (var integer i := 0; i < 8; i := i +1) {
1584 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1585 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1586 f_shutdown(__BFILE__, __LINE__);
1587 }
1588 }
1589
1590 f_shutdown(__BFILE__, __LINE__, final := true);
1591}
1592
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001593
1594/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1595 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1596 the final UL ACK sent at us. */
1597testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1598 var PCUIF_info_ind info_ind;
1599 var BTS_PDTCH_Block data_msg;
1600 var RlcmacDlBlock dl_block;
1601 var uint32_t sched_fn;
1602 var template (value) TsTrxBtsNum nr;
1603 var template RlcmacDlBlock exp_ul_ack;
1604 var template UlAckNackGprs exp_ul_ack_sub;
1605 var GprsMS ms;
1606 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1607 var integer N3103 := 0;
1608 timer T_3169 := 1.0;
1609
1610 /* Initialize GPRS MS side */
1611 f_init_gprs_ms();
1612 ms := g_ms[0]; /* We only use first MS in this test */
1613
1614 /* Initialize the PCU interface abstraction */
1615 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1616 info_ind.n3103 := N3103_MAX;
1617 info_ind.t3169 := 1;
1618 f_init_raw(testcasename(), info_ind);
1619
1620 /* Establish an Uplink TBF */
1621 f_ms_establish_ul_tbf(ms);
1622
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02001623 /* Wait until PCU starts requesting for UL block on this TBF: */
1624 f_ms_wait_usf(ms);
1625
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001626 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001627 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1628 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1629
1630 nr := ts_TsTrxBtsNum;
1631 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1632 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1633 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1634 block_nr := nr.blk_nr));
1635 alt {
1636 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1637 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1638 exp_ul_ack)) -> value data_msg {
1639 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1640 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1641 f_shutdown(__BFILE__, __LINE__);
1642 }
1643
1644 nr := ts_TsTrxBtsNum;
1645 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1646 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1647 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1648 block_nr := nr.blk_nr));
1649 N3103 := N3103 + 1;
1650 if (N3103 == N3103_MAX) {
1651 /* At this point in time (N3103_MAX reached), PCU is
1652 * moving the TBF to RELEASE state so no data/ctrl for
1653 * it is tx'ed, hence the dummy blocks: */
1654 T_3169.start;
1655 }
1656 repeat;
1657 }
1658 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1659 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1660 exp_ul_ack)) -> value data_msg {
1661 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1662 f_shutdown(__BFILE__, __LINE__);
1663 }
1664 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001665 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001666 [T_3169.running] T_3169.timeout {
1667 log("T_3169 timeout");
1668 /* Done in alt, wait for pending RTS initiated previously in
1669 * above case before continuing (expect /* Dummy block): */
1670 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1671 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001672 tr_RLCMAC_DL_DUMMY_CTRL));
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001673 }
1674 [] BTS.receive {
1675 setverdict(fail, "Unexpected BTS message");
1676 f_shutdown(__BFILE__, __LINE__);
1677 }
1678 }
1679
1680 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1681 * USFs as per previous TBF since they were freed at expiration time: */
1682 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1683 var uint5_t old_tfi := ms.ul_tbf.tfi;
1684 f_ms_establish_ul_tbf(ms);
1685 if (old_tfi != ms.ul_tbf.tfi) {
1686 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1687 f_shutdown(__BFILE__, __LINE__);
1688 }
1689 for (var integer i := 0; i < 8; i := i +1) {
1690 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1691 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1692 f_shutdown(__BFILE__, __LINE__);
1693 }
1694 }
1695
1696 f_shutdown(__BFILE__, __LINE__, final := true);
1697}
1698
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001699/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1700 * point the TBF is no longer available. In order to get to start of T3191, we
1701 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1702 * until TBF release procedure starts after draining DL queue. */
1703testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1704 var PCUIF_info_ind info_ind;
1705 var RlcmacDlBlock dl_block;
1706 var octetstring data1 := f_rnd_octstring(200);
1707 var octetstring data2 := f_rnd_octstring(10);
1708 var uint32_t dl_fn;
1709 var template (value) TsTrxBtsNum nr;
1710 var BTS_PDTCH_Block data_msg;
1711 var GprsMS ms;
1712
1713 /* Initialize NS/BSSGP side */
1714 f_init_bssgp();
1715 /* Initialize GPRS MS side */
1716 f_init_gprs_ms();
1717 ms := g_ms[0]; /* We only use first MS in this test */
1718
1719 /* Initialize the PCU interface abstraction */
1720 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1721 /* Set timer to 1 sec (default 5) to speedup test: */
1722 info_ind.t3191 := 1;
1723 f_init_raw(testcasename(), info_ind);
1724
1725 /* Establish BSSGP connection to the PCU */
1726 f_bssgp_establish();
1727 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1728
1729 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001730 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001731 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001732
1733 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1734 f_sleep(X2002);
1735
1736 while (true) {
1737 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1738
1739 /* Keep Ack/Nack description updated (except for last BSN) */
1740 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1741
1742 if (f_dl_block_rrbp_valid(dl_block)) {
1743 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1744 f_dl_block_ack_fn(dl_block, dl_fn));
1745 break;
1746 }
1747 }
1748
1749 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1750 nr := ts_TsTrxBtsNum;
1751 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1752 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1753 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1754 block_nr := nr.blk_nr));
1755 alt {
1756 [] as_ms_rx_ignore_dummy(ms, nr);
1757 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1758 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1759 ?)) -> value data_msg {
1760 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1761 log("Received FINAL_ACK");
1762 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1763 break;
1764 }
1765 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1766 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1767 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1768 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1769 }
1770 nr := ts_TsTrxBtsNum;
1771 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1772 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1773 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1774 block_nr := nr.blk_nr));
1775 repeat;
1776 }
1777 [] BTS.receive {
1778 setverdict(fail, "Unexpected BTS message");
1779 f_shutdown(__BFILE__, __LINE__);
1780 }
1781 }
1782
1783 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1784 to time out. We simply sleep instead of requesting blocks because
1785 otherwise retransmissions would keep restarting the timer. */
1786 f_sleep(int2float(info_ind.t3191));
1787
1788 /* The TBF should be freed now, so new data should trigger an Assignment: */
Philipp Maier7f064e62023-09-22 16:38:19 +02001789 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001790 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001791
1792 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1793 f_sleep(X2002);
1794 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1795 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1796 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1797 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1798 f_dl_block_ack_fn(dl_block, dl_fn));
1799
1800 f_shutdown(__BFILE__, __LINE__, final := true);
1801}
1802
1803/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1804testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1805 var PCUIF_info_ind info_ind;
1806 var RlcmacDlBlock dl_block;
1807 var octetstring data1 := f_rnd_octstring(1400);
1808 var octetstring data2 := f_rnd_octstring(10);
1809 var uint32_t dl_fn;
1810 var GprsMS ms;
1811
1812 /* Initialize NS/BSSGP side */
1813 f_init_bssgp();
1814 /* Initialize GPRS MS side */
1815 f_init_gprs_ms();
1816 ms := g_ms[0]; /* We only use first MS in this test */
1817
1818 /* Initialize the PCU interface abstraction */
1819 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1820 /* Set timer to 1 sec (default 5) to speedup test: */
1821 info_ind.t3191 := 1;
1822 f_init_raw(testcasename(), info_ind);
1823
1824 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1825
1826 /* Establish BSSGP connection to the PCU */
1827 f_bssgp_establish();
1828 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1829
1830 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001831 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001832 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001833
1834 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1835 f_sleep(X2002);
1836
1837 /* Send enough DL data to at least be able to DL ACK once (excl the
1838 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1839 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1840 while (true) {
1841 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1842
1843 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1844 log("Received FINAL_ACK");
1845 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1846 break;
1847 }
1848
1849 /* Keep Ack/Nack description updated (except for last BSN) */
1850 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1851
1852 if (f_dl_block_rrbp_valid(dl_block)) {
1853 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1854 f_dl_block_ack_fn(dl_block, dl_fn));
1855 }
1856 }
1857
1858 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1859 to time out. We simply sleep instead of requesting blocks because
1860 otherwise retransmissions would keep restarting the timer. */
1861 f_sleep(int2float(info_ind.t3191));
1862
1863 /* The TBF should be freed now, so new data should trigger an Assignment: */
Philipp Maier7f064e62023-09-22 16:38:19 +02001864 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001865 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001866
1867 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1868 f_sleep(X2002);
1869 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1870 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1871 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1872 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1873 f_dl_block_ack_fn(dl_block, dl_fn));
1874
1875 f_shutdown(__BFILE__, __LINE__, final := true);
1876}
1877
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001878/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1879 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1880 * T3193) after DL TBF release */
1881testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001882 var RlcmacDlBlock dl_block;
1883 var octetstring data := f_rnd_octstring(10);
1884 var boolean ok;
1885 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001886 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001887 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001888 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1889
1890 /* Initialize NS/BSSGP side */
1891 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001892 /* Initialize GPRS MS side */
1893 f_init_gprs_ms();
1894 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001895
1896 /* Initialize the PCU interface abstraction */
1897 f_init_raw(testcasename());
1898
Pau Espin Pedrol1c6a9e42023-06-20 11:54:56 +02001899 /* Disable "idle DL TBF alive" timer, to make the test easier and avoid
1900 * having to keep receiving dummy LLC blocks for a while until the last
1901 * block with FBI=1 is set. This way the first and only DL block is already
1902 * the FBI one. */
1903 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1904
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001905 /* Establish BSSGP connection to the PCU */
1906 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001907 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001908
1909 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001910 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001911 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001912
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001913 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1914 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001915 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol1c6a9e42023-06-20 11:54:56 +02001916 if (dl_block.data.mac_hdr.hdr_ext.fbi == false) {
1917 setverdict(fail, "Expected DL data block with FBI=1 but got FBI=0");
1918 f_shutdown(__BFILE__, __LINE__);
1919 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001920
1921 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001922 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1923 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1924 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001925
1926 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001927 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001928 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001929 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001930 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001931
1932 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001933
1934 /* 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 +07001935 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001936 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1937 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1938 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001939
1940 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001941}
1942
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001943/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1944 freed and no longer available. Trigger it by sending DL blocks and never DL
1945 ACKing the data (which are requested through RRBP) */
1946testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1947 var PCUIF_info_ind info_ind;
1948 var RlcmacDlBlock dl_block;
1949 var octetstring data1 := f_rnd_octstring(1000);
1950 var octetstring data2 := f_rnd_octstring(10);
1951 var uint32_t dl_fn;
1952 var template (value) TsTrxBtsNum nr;
1953 var BTS_PDTCH_Block data_msg;
1954 var GprsMS ms;
1955 const integer N3105_MAX := 2;
1956 var integer N3105 := 0;
1957 timer T_3195 := 1.0;
1958 var integer num_poll_recv := 0;
1959
1960 /* Initialize NS/BSSGP side */
1961 f_init_bssgp();
1962 /* Initialize GPRS MS side */
1963 f_init_gprs_ms();
1964 ms := g_ms[0]; /* We only use first MS in this test */
1965
1966 /* Initialize the PCU interface abstraction */
1967 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1968 /* Speedup test: */
1969 info_ind.n3105 := N3105_MAX;
1970 info_ind.t3195 := 1;
1971 f_init_raw(testcasename(), info_ind);
1972
1973 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1974 * MS and retransmitted after the TBF is released and later on created
1975 * (because the MS is reused) */
1976 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1977
1978 /* Establish BSSGP connection to the PCU */
1979 f_bssgp_establish();
1980 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1981
1982 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001983 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001984 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001985
1986 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1987 f_sleep(X2002);
1988
1989 /* Now we go on receiving DL data and not answering RRBP: */
1990 nr := ts_TsTrxBtsNum;
1991 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1992 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1993 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1994 block_nr := nr.blk_nr));
1995 alt {
1996 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1997 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1998 tr_RLCMAC_DATA)) -> value data_msg {
1999 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
2000 if (num_poll_recv == 0) {
2001 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
2002 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
2003 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2004 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
2005 } else {
2006 log("Ignoring RRBP ", num_poll_recv);
2007 N3105 := N3105 + 1;
2008 }
2009 num_poll_recv := num_poll_recv + 1;
2010 }
2011
2012 nr := ts_TsTrxBtsNum;
2013 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2014 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2015 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2016 block_nr := nr.blk_nr));
2017 repeat;
2018 }
2019 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002020 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002021 */
2022 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2023 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002024 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002025 if (not T_3195.running) {
2026 T_3195.start;
2027 /* We even send some new data, nothing should be sent to MS */
2028 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2029 }
2030 nr := ts_TsTrxBtsNum;
2031 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2032 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2033 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2034 block_nr := nr.blk_nr));
2035 repeat;
2036 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01002037 /* We may already receive idle blocks before our own TTCN3 timer
2038 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002039 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002040 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002041 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002042 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002043 * above case before continuing (expect empty block): */
Pau Espin Pedrolaedacf32023-09-26 19:29:38 +02002044 alt {
2045 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002046 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrolaedacf32023-09-26 19:29:38 +02002047 omit)); /* DONE, continue after altstep. */
2048 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2049 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2050 tr_RLCMAC_DL_DUMMY_CTRL)) {
2051 setverdict(fail, "Rx unexpected DUMMY message, expected empty data block");
2052 f_shutdown(__BFILE__, __LINE__);
2053 }
2054 }
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002055 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002056 [] BTS.receive {
2057 setverdict(fail, "Unexpected BTS message");
2058 f_shutdown(__BFILE__, __LINE__);
2059 }
2060 }
2061
2062 /* after T_3195 timeout, TBF is released */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002063 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002064 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002065
2066 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2067 f_sleep(X2002);
2068 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2069
2070 /* ACK the DL block */
2071 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2072 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2073 f_dl_block_ack_fn(dl_block, dl_fn));
2074
2075 f_shutdown(__BFILE__, __LINE__, final := true);
2076}
2077
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002078/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2079function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2080 var PCUIF_info_ind info_ind;
2081 var template IARRestOctets rest;
2082 var BIT11 ra11;
2083 var GprsMS ms;
2084 var octetstring data := f_rnd_octstring(10);
2085 var RlcmacDlBlock dl_block;
2086 var template RlcmacDlBlock rej_tmpl;
2087 var uint32_t dl_fn;
2088 var uint32_t sched_fn;
2089 var uint8_t wait_ind_val;
2090
2091 /* Initialize NS/BSSGP side */
2092 f_init_bssgp();
2093 /* Initialize GPRS MS side */
2094 f_init_gprs_ms();
2095 ms := g_ms[0]; /* We only use first MS in this test */
2096
2097 info_ind := valueof(ts_PCUIF_INFO_default);
2098
2099 /* Only the first TRX is enabled. */
2100 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2101 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2102
2103 /* Initialize the PCU interface abstraction */
2104 f_init_raw(testcasename(), info_ind);
2105
2106 f_pcuvty_set_timer(3172, t3172_ms);
2107
2108 /* Establish BSSGP connection to the PCU */
2109 f_bssgp_establish();
2110 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2111
2112 var EGPRSPktChRequest req := {
2113 one_phase := {
2114 tag := '0'B,
2115 multislot_class := '10101'B,
2116 priority := '01'B,
2117 random_bits := '101'B
2118 }
2119 };
2120
2121 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2122 for (var integer i := 0; i < 7; i := i + 1) {
2123 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2124 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2125 }
2126
2127 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002128 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002129 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002130
2131 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2132 f_sleep(X2002);
2133 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2134
2135 /* ACK the DL block */
2136 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2137 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2138 f_dl_block_ack_fn(dl_block, dl_fn));
2139
2140 /* Since all USF are taken, we should receive a Reject: */
2141
2142 if (wait_ind_size == '0'B) {
2143 wait_ind_val := t3172_ms / 1000;
2144 } else {
2145 wait_ind_val := t3172_ms / 20;
2146 }
2147 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2148 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2149 wait_ind_val,
2150 wait_ind_size)));
2151 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2152 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2153 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2154 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2155 block_nr := nr.blk_nr));
2156 alt {
2157 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2158 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2159 rej_tmpl));
2160 [] BTS.receive {
2161 setverdict(fail, "Unexpected BTS message");
2162 f_shutdown(__BFILE__, __LINE__);
2163 }
2164 }
2165 f_shutdown(__BFILE__, __LINE__, final := true);
2166}
2167testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2168 /* size=0 means value is provided in seconds. Due to value being 8
2169 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2170 * = 5100. Hence, values above it should use size=0 to be able to
2171 * provide values in range. Let's use 6 seconds, 6000ms
2172 */
2173 f_TC_t3172(6000, '0'B);
2174}
2175testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2176 f_TC_t3172(3000, '1'B);
2177}
2178
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002179/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2180testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002181 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002182 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002183 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002184 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002185
2186 /* Initialize NS/BSSGP side */
2187 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002188 /* Initialize GPRS MS side */
2189 f_init_gprs_ms();
2190 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002191
2192 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002193 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002194
2195 /* Establish BSSGP connection to the PCU */
2196 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002197 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002198
2199 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002200 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002201
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002202 /* Wait until PCU starts requesting for UL block on this TBF: */
2203 f_ms_wait_usf(ms);
2204
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002205 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002206 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002207 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002208 /* 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 +02002209 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 +02002210 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2211 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002212 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002213
2214 /* Send enough blocks to test whole procedure: Until Nth block
2215 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2216 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002217 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002218 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2219 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002220 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002221
2222 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002223 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 +07002224
2225 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002226}
2227
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002228/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2229testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2230 var RlcmacDlBlock dl_block;
2231 var uint32_t dl_fn, sched_fn;
2232 var octetstring payload;
2233 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002234 var template (value) LlcBlockHdr blk_hdr;
2235 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002236 var integer blk_len;
2237 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002238 var GprsMS ms;
2239
2240 /* Initialize NS/BSSGP side */
2241 f_init_bssgp();
2242 /* Initialize GPRS MS side */
2243 f_init_gprs_ms();
2244 ms := g_ms[0]; /* We only use first MS in this test */
2245
2246 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002247 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002248
2249 /* Establish BSSGP connection to the PCU */
2250 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002251 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002252
2253 /* Establish an Uplink TBF */
2254 f_ms_establish_ul_tbf(ms);
2255
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002256 /* Wait until PCU starts requesting for UL block on this TBF: */
2257 f_ms_wait_usf(ms);
2258
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002259 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002260 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002261 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002262 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2263 more := false, e := true);
2264 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002265 /* 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 +01002266 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2267 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002268 cv := 15,
2269 bsn := ms.ul_tbf.bsn,
2270 blocks := blocks,
2271 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002272 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002273 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002274
2275 /* ACK and check it was received fine */
2276 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2277 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2278 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2279 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002280 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 +02002281
2282 /* Test sending LLC PDUS of incrementing size */
2283 var integer max_size := 49;
2284 for (var integer i := 1; i <= max_size; i := i + 1) {
2285 var integer cv;
2286 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2287 log("Sending DATA.ind with LLC payload size ", i);
2288 if (i < max_size - g_bs_cv_max) {
2289 cv := 15;
2290 } else {
2291 cv := max_size - i;
2292 }
2293
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002294 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2295 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002296 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002297 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2298 more := false, e := true);
2299 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002300 /* 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 +01002301 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2302 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002303 cv := cv,
2304 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002305 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002306 f_ultbf_inc_bsn(ms.ul_tbf);
2307 f_ms_tx_ul_block(ms, ul_data);
2308
2309 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002310 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 +02002311
2312 /* we will receive UL ACK/NACK from time to time, handle it. */
2313 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002314 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002315 continue;
2316 }
2317 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2318 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2319 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2320 f_shutdown(__BFILE__, __LINE__);
2321 }
2322
2323 log("Rx Packet Uplink ACK / NACK");
2324 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2325 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2326 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2327 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002328
2329 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002330}
2331
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002332function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2333 var octetstring payload;
2334 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002335 var template (value) LlcBlockHdr blk_hdr;
2336 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002337 var integer block_len, max_valid_data_len;
2338 timer T;
2339
2340 block_len := f_rlcmac_cs_mcs2block_len(cs);
2341 /* We need to send with TLLI since we are in One-Phase Access Contenion
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002342 * resolution), so that's -4 bytes of data, -3 for headers, -1 for LI
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002343 * indicator, -1 for spare bits octet at the end */
2344 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2345 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 +07002346 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2347 more := false, e := true);
2348 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002349 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2350 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002351 cv := cv,
2352 bsn := ms.ul_tbf.bsn,
2353 blocks := blocks,
2354 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002355 f_ultbf_inc_bsn(ms.ul_tbf);
2356 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2357
2358 T.start(0.5);
2359 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002360 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002361 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2362 f_shutdown(__BFILE__, __LINE__);
2363 }
2364 [] T.timeout {
2365 setverdict(pass);
2366 }
2367 }
2368}
2369/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2370 blocks intentionally contain last byte of data placed in last byte of RLC
2371 containing padding/spare bits, which is incorrect. Spare bits exist and are
2372 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2373 discounting padding in octet" */
2374testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2375 var GprsMS ms;
2376 var integer block_len, max_valid_data_len;
2377
2378 /* Initialize NS/BSSGP side */
2379 f_init_bssgp();
2380 /* Initialize GPRS MS side */
2381 f_init_gprs_ms();
2382 ms := g_ms[0]; /* We only use first MS in this test */
2383
2384 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002385 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002386
2387 /* Establish BSSGP connection to the PCU */
2388 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002389 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002390
2391 /* Establish an Uplink TBF */
2392 f_ms_establish_ul_tbf(ms);
2393
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002394 /* Wait until PCU starts requesting for UL block on this TBF: */
2395 f_ms_wait_usf(ms);
2396
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002397 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2398 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2399 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2400
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002401 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002402}
2403
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002404/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2405 * answered, so TBFs for uplink and later for downlink are created.
2406 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002407private 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 +02002408 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002409 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002410 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002411 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002412 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002413
2414 /* Initialize NS/BSSGP side */
2415 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002416 /* Initialize GPRS MS side */
2417 f_init_gprs_ms();
2418 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002419
2420 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002421 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002422
2423 /* Establish BSSGP connection to the PCU */
2424 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002425 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002426
2427 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002428 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002429
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002430 /* Wait until PCU starts requesting for UL block on this TBF: */
2431 f_ms_wait_usf(ms);
2432
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002433 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002434 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002435 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 +02002436 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2437 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002438 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002439
2440 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002441 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002442
2443 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002444 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002445 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002446
2447 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2448 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002449 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002450
2451 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002452 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2453 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2454 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002455
2456 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002457}
2458
2459/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2460 * answered, so TBFs for uplink and later for downlink are created.
2461 */
2462testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002463 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002464 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002465}
2466
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002467/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2468 * answered, so TBFs for uplink and later for downlink are created.
2469 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002470private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2471 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002472 template (present) CodingScheme exp_ul_cs_mcs := ?,
2473 template (present) CodingScheme exp_dl_cs_mcs := ?)
2474runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002475 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002476 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002477 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002478 var uint32_t sched_fn;
2479 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002480 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002481 var GprsMS ms;
2482
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002483 /* Initialize NS/BSSGP side */
2484 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002485 /* Initialize GPRS MS side */
2486 f_init_gprs_ms();
2487 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002488
2489 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002490 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002491
2492 /* Establish BSSGP connection to the PCU */
2493 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002494 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002495
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002496 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2497 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 +02002498
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002499 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2500 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 +02002501 f_shutdown(__BFILE__, __LINE__);
2502 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002503
2504 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2505 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002506 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002507
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002508 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002509 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 +02002510
2511 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002512 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002513
2514 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002515 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002516 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2517 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002518 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002519 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002520 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002521
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002522 /* PCU acks the UL data after having received CV=0) */
2523 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2524
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002525 /* 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 +02002526 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 +02002527
2528 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002529 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2530 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 +02002531 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002532
2533 f_shutdown(__BFILE__, __LINE__, final := true);
2534}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002535
2536testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002537 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2538 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002539
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002540 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 +01002541
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002542 var StatsDExpects expect := {
2543 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2544 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2545 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2546 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2547 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2548 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2549 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2550 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2551 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2552 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2553 };
2554 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002555
2556 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002557}
2558
2559testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002560 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2561 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002562
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002563 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 +01002564
2565 var StatsDExpects expect := {
2566 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2567 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2568 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2569 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2570 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2571 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2572 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2573 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2574 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2575 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2576 };
2577 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002578
2579 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002580}
2581
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002582testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2583 /* Configure PCU to force two phase access */
2584 g_force_two_phase_access := true;
2585
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002586 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002587 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002588
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002589 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 +01002590
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002591 var StatsDExpects expect := {
2592 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2593 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2594 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2595 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2596 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2597 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2598 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2599 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2600 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2601 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2602 };
2603 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002604
2605 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002606}
2607
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002608/* Test scenario where SGSN wants to send some data against MS and it is
2609 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2610 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002611private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2612 template (present) CodingScheme exp_cs_mcs := ?)
2613runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002614 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002615 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002616 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002617 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002618 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002619
2620 /* Initialize NS/BSSGP side */
2621 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002622 /* Initialize GPRS MS side */
2623 f_init_gprs_ms();
2624 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002625
2626 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002627 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002628
2629 /* Establish BSSGP connection to the PCU */
2630 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002631 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002632
2633 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002634 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002635 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002636
2637 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2638 f_sleep(X2002);
Pau Espin Pedrol3f2b5e42022-11-29 14:54:34 +01002639 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2640 dl_fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
2641
2642 f_rlcmac_dl_block_exp_data(dl_block, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002643
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002644 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002645 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2646 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 +02002647 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002648
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002649 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002650 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002651
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002652 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002653 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002654 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002655 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2656 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002657 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002658
2659 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002660 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002661
2662 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002663}
2664
2665testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002666 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002667 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2668}
2669
2670/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2671/* information about the MS */
2672testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002673 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002674 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002675}
2676
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002677/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2678 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2679 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2680 * be transferred).
2681 */
2682testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002683 var RlcmacDlBlock dl_block;
2684 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002685 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002686 var octetstring total_payload;
2687 var octetstring payload;
2688 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002689 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002690 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002691 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002692
2693 /* Initialize NS/BSSGP side */
2694 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002695 /* Initialize GPRS MS side */
2696 f_init_gprs_ms();
2697 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002698
2699 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002700 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002701
2702 /* Establish BSSGP connection to the PCU */
2703 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002704 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002705
2706 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002707 f_ms_establish_ul_tbf(ms);
2708 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002709
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002710 /* Wait until PCU starts requesting for UL block on this TBF: */
2711 f_ms_wait_usf(ms);
2712
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002713 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002714 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002715 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 +02002716 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 +02002717
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002718 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2719 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002720 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002721 total_payload := payload;
2722
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002723 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2724
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002725 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002726 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002727 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002728 total_payload := total_payload & payload;
2729
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002730 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002731 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002732 total_payload := total_payload & payload;
2733
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002734 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002735 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 +02002736 total_payload := total_payload & lost_payload;
2737
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002738 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002739 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002740 total_payload := total_payload & payload;
2741
2742 /* 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 +02002743 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002744
2745 /* On CV=0, we'll receive a UL ACK asking about missing block */
2746 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2747 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002748 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2749 tfi := tfi,
2750 cv := 15,
2751 bsn := 3,
2752 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002753 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002754
2755 /* Now final ack is recieved */
2756 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2757 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002758 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002759
2760 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002761 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 +07002762
2763 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002764}
2765
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002766/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2767 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2768 * timeout occurs (specified by sent RRBP on DL block). */
2769testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002770 var RlcmacDlBlock dl_block;
2771 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002772 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002773 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002774
2775 /* Initialize NS/BSSGP side */
2776 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002777 /* Initialize GPRS MS side */
2778 f_init_gprs_ms();
2779 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002780
2781 /* Initialize the PCU interface abstraction */
2782 f_init_raw(testcasename());
2783
2784 /* Establish BSSGP connection to the PCU */
2785 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002786 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002787
2788 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002789 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002790 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002791
2792 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2793 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002794 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002795
2796 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2797 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2798 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002799 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002800
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002801 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2802 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002803 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002804
2805 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002806 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2807 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2808 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002809
2810 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002811}
2812
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002813/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2814testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2815 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2816 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002817 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002818 var RlcmacDlBlock dl_block;
2819 var uint32_t ack_fn;
2820 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002821 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002822 timer T := 5.0;
2823
2824 /* Initialize NS/BSSGP side */
2825 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002826 /* Initialize GPRS MS side */
2827 f_init_gprs_ms();
2828 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002829
2830 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002831 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002832
Daniel Willmann535aea62020-09-21 13:27:08 +02002833 f_statsd_reset();
2834
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002835 /* Establish BSSGP connection to the PCU */
2836 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002837 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002838
2839 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002840 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002841 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002842
2843 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2844 f_sleep(X2002);
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002845 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2846 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002847
2848 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002849 f_rlcmac_dl_block_exp_data(dl_block, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002850 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002851
2852 /* TDMA frame number on which we are supposed to send the ACK */
2853 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2854
2855 /* SGSN sends more blocks during the indicated RRBP */
2856 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2857 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002858 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002859
2860 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2861
2862 /* Make sure this block has the same TFI as was assigned
2863 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002864 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002865 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2866 dl_block.data.mac_hdr.hdr_ext.tfi);
2867 f_shutdown(__BFILE__, __LINE__);
2868 }
2869
2870 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002871 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002872
2873 /* Break if this is the end of RRBP */
2874 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002875 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002876 break;
2877 }
2878 }
2879
2880 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002881 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 +07002882
2883 /* Make sure that the next block (after the Ack) is dummy */
2884 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2885
Daniel Willmann535aea62020-09-21 13:27:08 +02002886 var StatsDExpects expect := {
2887 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2888 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2889 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2890 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2891 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002892 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002893 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2894 };
2895 f_statsd_expect(expect);
2896
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002897 f_shutdown(__BFILE__, __LINE__, final := true);
2898}
2899
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002900/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2901 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2902 * Check "3GPP TS 44.060" Annex B. */
2903testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2904 var RlcmacDlBlock dl_block;
2905 var octetstring dataA := f_rnd_octstring(20);
2906 var octetstring dataB := f_rnd_octstring(13);
2907 var octetstring dataC := f_rnd_octstring(3);
2908 var octetstring dataD := f_rnd_octstring(12);
2909 var uint32_t sched_fn;
2910 var GprsMS ms;
2911 var template (value) RlcmacUlBlock ul_data;
2912
2913 /* Initialize NS/BSSGP side */
2914 f_init_bssgp();
2915 /* Initialize GPRS MS side */
2916 f_init_gprs_ms();
2917 ms := g_ms[0]; /* We only use first MS in this test */
2918
2919 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002920 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002921
2922 /* Establish BSSGP connection to the PCU */
2923 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002924 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002925
2926 /* Establish an Uplink TBF */
2927 f_ms_establish_ul_tbf(ms);
2928
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002929 /* Wait until PCU starts requesting for UL block on this TBF: */
2930 f_ms_wait_usf(ms);
2931
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002932 /* Summary of what's transmitted:
2933 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2934 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2935 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2936 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2937 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2938 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2939 */
2940
2941 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002942 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2943 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002944 cv := 3,
2945 bsn := ms.ul_tbf.bsn,
2946 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2947 tlli := ms.tlli);
2948 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2949 * RLCMAC block being sent. */
2950 ul_data.data.mac_hdr.e := true;
2951 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002952 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002953
2954 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002955 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2956 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002957 cv := 2,
2958 bsn := ms.ul_tbf.bsn,
2959 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2960 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2961 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2962 },
2963 tlli := ms.tlli);
2964 f_ultbf_inc_bsn(ms.ul_tbf);
2965 f_ms_tx_ul_block(ms, ul_data);
2966
2967 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002968 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 +02002969
2970 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002971 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2972 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002973 cv := 1,
2974 bsn := ms.ul_tbf.bsn,
2975 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2976 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2977 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2978 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2979 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2980 },
2981 tlli := ms.tlli);
2982 f_ultbf_inc_bsn(ms.ul_tbf);
2983 f_ms_tx_ul_block(ms, ul_data);
2984
2985 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002986 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2987 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 +02002988
2989 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002990 ul_data := t_RLCMAC_UL_DATA_TLLI(
2991 cs := CS_1,
2992 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002993 cv := 0,
2994 bsn := ms.ul_tbf.bsn,
2995 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2996 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2997 },
2998 tlli := ms.tlli);
2999 f_ultbf_inc_bsn(ms.ul_tbf);
3000 f_ms_tx_ul_block(ms, ul_data);
3001
3002 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003003 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 +02003004
3005 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3006 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3007 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3008
3009 f_shutdown(__BFILE__, __LINE__, final := true);
3010}
3011
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003012/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
3013 * ACK/NACK is not answered */
3014testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
3015 var RlcmacDlBlock dl_block;
3016 var octetstring data1 := f_rnd_octstring(200);
3017 var octetstring data2 := f_rnd_octstring(10);
3018 var uint32_t dl_fn;
3019 var GprsMS ms;
3020 var template (value) TsTrxBtsNum nr;
3021 var BTS_PDTCH_Block data_msg;
3022
3023 /* Initialize NS/BSSGP side */
3024 f_init_bssgp();
3025 /* Initialize GPRS MS side */
3026 f_init_gprs_ms();
3027 ms := g_ms[0]; /* We only use first MS in this test */
3028
3029 /* Initialize the PCU interface abstraction */
3030 f_init_raw(testcasename())
3031
3032 /* Establish BSSGP connection to the PCU */
3033 f_bssgp_establish();
3034 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3035
3036 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02003037 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003038 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003039
3040 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3041 f_sleep(X2002);
3042
3043 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
3044 while (true) {
3045 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3046
3047 /* Keep Ack/Nack description updated (except for last BSN) */
3048 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3049
3050 if (f_dl_block_rrbp_valid(dl_block)) {
3051 /* Don't transmit DL ACK here on purpose ignore it */
3052 break;
3053 }
3054 }
3055
3056 /* PCU starts whole process again */
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003057 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003058
3059 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3060 f_sleep(X2002);
3061
3062 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
3063 /* DL data), after that we receive only DUMMY blocks so we are done */
3064 var boolean data_received := false;
3065 nr := ts_TsTrxBtsNum;
3066 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3067 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3068 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3069 block_nr := nr.blk_nr));
3070 alt {
3071 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3072 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003073 tr_RLCMAC_DL_DUMMY_CTRL)) { /* done */ }
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003074 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3075 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3076 tr_RLCMAC_DATA)) -> value data_msg {
3077 data_received := true;
3078 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3079 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3080 log("Received FINAL_ACK");
3081 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3082 }
3083 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3084 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3085 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3086 }
3087 nr := ts_TsTrxBtsNum;
3088 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3089 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3090 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3091 block_nr := nr.blk_nr));
3092 repeat;
3093 }
3094 [] BTS.receive {
3095 setverdict(fail, "Unexpected BTS message");
3096 f_shutdown(__BFILE__, __LINE__);
3097 }
3098 }
3099
3100 f_shutdown(__BFILE__, __LINE__, final := true);
3101}
3102
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003103/* OS#5508: Verify scheduling of LLC frames with SAPI=1 (GMM) takes precedence
3104 * over SAPI2/7/8 which in turn take prececende over others */
3105testcase TC_dl_llc_sapi_priority() runs on RAW_PCU_Test_CT {
3106 var octetstring data_sapi1 := f_pad_oct('01'O, 19, 'ff'O);
3107 var octetstring data_sapi2 := f_pad_oct('02'O, 19, 'ff'O);
3108 var octetstring data_sapi7 := f_pad_oct('07'O, 19, 'ff'O);
3109 var octetstring data_sapi8 := f_pad_oct('08'O, 19, 'ff'O);
3110 var octetstring data_sapi_other := f_pad_oct('03'O, 19, 'ff'O);
3111 var RlcmacDlBlock dl_block;
3112 var uint32_t dl_fn;
3113 var GprsMS ms;
3114 var integer state := 1;
3115
3116 /* Initialize NS/BSSGP side */
3117 f_init_bssgp();
3118 /* Initialize GPRS MS side */
3119 f_init_gprs_ms();
3120 ms := g_ms[0]; /* We only use first MS in this test */
3121
3122 /* Initialize the PCU interface abstraction */
3123 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3124
3125 /* Lock to CS1 to keep same DL RLCMAC data block size: */
3126 g_cs_initial_dl := 1;
3127 g_mcs_max_dl := 1;
3128 f_pcuvty_set_allowed_cs_mcs();
3129
3130 /* Establish BSSGP connection to the PCU */
3131 f_bssgp_establish();
3132 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3133
3134 /* SGSN sends some low prio DL data, PCU will page on CCCH (PCH) */
3135 for (var integer i := 0; i < 10; i := i + 1) {
Philipp Maier1ec31b32023-09-22 12:59:10 +02003136 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi_other, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003137 }
Philipp Maier7f064e62023-09-22 16:38:19 +02003138 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi2, imsi := ts_BSSGP_IMSI(ms.imsi)));
3139 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi7, imsi := ts_BSSGP_IMSI(ms.imsi)));
3140 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi8, imsi := ts_BSSGP_IMSI(ms.imsi)));
3141 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003142 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003143
3144 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3145 f_sleep(X2002);
3146
3147 while (state != 0) {
3148 var OCT1 rx_sapi;
3149 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3150 rx_sapi := dl_block.data.blocks[0].payload[0];
3151
3152 select (state) {
3153 case(1) { /* We expect the first GMM LLC frame here (SAPI=1, highest prio) */
3154 if (rx_sapi != '01'O) {
3155 setverdict(fail, "Wrong prio: Expected LLC SAPI 1 (GMM) but got ", rx_sapi);
3156 f_shutdown(__BFILE__, __LINE__);
3157 }
3158 state := 2;
3159 }
3160 case(2) { /* We expect the second LLC frame here (SAPI=2, middle prio) */
3161 if (rx_sapi != '02'O) {
3162 setverdict(fail, "Wrong prio: Expected LLC SAPI 2 but got ", rx_sapi);
3163 f_shutdown(__BFILE__, __LINE__);
3164 }
3165 state := 7;
3166 }
3167 case(7) { /* We expect the third LLC frame here (SAPI=7, middle prio) */
3168 if (rx_sapi != '07'O) {
3169 setverdict(fail, "Wrong prio: Expected LLC SAPI 7 but got ", rx_sapi);
3170 f_shutdown(__BFILE__, __LINE__);
3171 }
3172 state := 8;
3173 }
3174 case(8) { /* We expect the fourth LLC frame here (SAPI=8, middle prio) */
3175 if (rx_sapi != '08'O) {
3176 setverdict(fail, "Wrong prio: Expected LLC SAPI 8 but got ", rx_sapi);
3177 f_shutdown(__BFILE__, __LINE__);
3178 }
3179 state := 3;
3180 }
3181 case(3) { /* We expect the other LLC frame here (SAPI=3, lower prio) */
3182 if (rx_sapi != '03'O) {
3183 setverdict(fail, "Wrong prio: Expected LLC SAPI 3 but got ", rx_sapi);
3184 f_shutdown(__BFILE__, __LINE__);
3185 }
3186 state := 0; /* Done, break */
3187 }
3188 }
3189 /* Keep Ack/Nack description updated (except for last BSN) */
3190 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3191
3192 if (f_dl_block_rrbp_valid(dl_block)) {
3193 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3194 f_dl_block_ack_fn(dl_block, dl_fn));
3195 }
3196 }
3197
3198 f_shutdown(__BFILE__, __LINE__, final := true);
3199}
3200
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003201/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3202testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003203 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003204 var octetstring data := f_rnd_octstring(10);
3205 var PacketDlAssign dl_tbf_ass;
3206 var RlcmacDlBlock dl_block;
3207 var uint32_t poll_fn;
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003208 var uint32_t dl_fn;
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003209 var uint32_t sched_fn;
3210 var GprsMS ms;
3211 timer T := 5.0;
3212
3213 /* Initialize NS/BSSGP side */
3214 f_init_bssgp();
3215 /* Initialize GPRS MS side */
3216 f_init_gprs_ms();
3217 ms := g_ms[0]; /* We only use first MS in this test */
3218
3219 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003220 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3221 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003222
3223 /* Initialize the PCU interface abstraction */
3224 f_init_raw(testcasename(), info_ind);
3225
3226 /* Establish BSSGP connection to the PCU */
3227 f_bssgp_establish();
3228 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3229
3230 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3231 through PDCH (no multiblock assignment possible through PCH) */
3232 f_ms_establish_ul_tbf(ms);
3233
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003234 /* Wait until PCU starts requesting for UL block on this TBF: */
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003235 dl_fn := f_ms_wait_usf(ms, nr := f_ms_tx_TsTrxBtsNum(ms));
3236 sched_fn := f_next_pdch_block(dl_fn);
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003237
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003238 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003239 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003240 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := sched_fn,
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003241 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003242 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3243 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3244
3245 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3246 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3247 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3248 gprsextendeddynalloccap := '0'B
3249 };
3250 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3251 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3252 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3253 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3254 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3255 f_shutdown(__BFILE__, __LINE__);
3256 }
3257 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3258
3259 f_shutdown(__BFILE__, __LINE__, final := true);
3260}
3261
Pau Espin Pedrol85ad3d02023-07-28 15:00:19 +02003262/* Test DL TBF assignment over PACCH if Multislot class is unknown both at PCU
3263 * and SGSN (eg. because MS started 1-phase access and SGSN answered back).
3264 * Since the msclass is unknown, it shouldn't assign multiple timeslots since
3265 * the MS may not support it. Related OS#6118. */
3266testcase TC_dl_multislot_tbf_ms_class_unknown() runs on RAW_PCU_Test_CT
3267{
3268 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3269 var RlcmacDlBlock dl_block;
3270 var octetstring payload;
3271 var template (value) LlcBlockHdr blk_hdr;
3272 var template (value) LlcBlocks blocks;
3273 var uint32_t sched_fn;
3274 var uint32_t dl_fn;
3275 var template RlcmacDlBlock acknack_tmpl;
3276 var GprsMS ms;
3277 var octetstring data := f_rnd_octstring(10);
3278
3279 /* Initialize NS/BSSGP side */
3280 f_init_bssgp();
3281
3282 /* Only 1 TRX with 8 PDCH */
3283 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3284 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
3285
3286 /* Initialize GPRS MS side */
3287 f_init_gprs_ms();
3288 ms := g_ms[0]; /* We only use first MS in this test */
3289
3290 /* Initialize the PCU interface abstraction */
3291 f_init_raw(testcasename(), info_ind);
3292
3293 /* Establish BSSGP connection to the PCU */
3294 f_bssgp_establish();
3295 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3296
3297 /* Establish an Uplink TBF. 1 TS is assigned over AGCH. */
3298 f_ms_establish_ul_tbf(ms);
3299
3300 /* Wait until PCU starts requesting for UL block on this TBF: */
3301 dl_fn := f_ms_wait_usf(ms, nr := f_ms_tx_TsTrxBtsNum(ms));
3302 sched_fn := f_next_pdch_block(dl_fn);
3303
3304 /* Send one UL block (with TLLI since we are in One-Phase Access
3305 * contention resolution) and make sure it is ACKED fine. */
3306 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
3307 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
3308 more := false, e := true);
3309 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
3310 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
3311 f_ms_tx_ul_data_blocks_gprs(ms, blocks, cv := 15, with_tlli := true, fn := sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3312
3313 /* UL block should be received in SGSN */
3314 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3315
3316 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3317 tr_UlAckNackGprs(ms.tlli,
3318 tr_AckNackDescription(final_ack := '0'B)))
3319 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl, nr := f_ms_tx_TsTrxBtsNum(ms));
3320
3321 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap := omit));
3322 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3323 if (f_dltbf_num_slots(ms.dl_tbf) != 1) {
3324 setverdict(fail, "Expected 1 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3325 f_shutdown(__BFILE__, __LINE__);
3326 }
3327
3328 f_shutdown(__BFILE__, __LINE__, final := true);
3329}
3330
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003331testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003332 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003333 var RlcmacDlBlock dl_block;
3334 var octetstring data := f_rnd_octstring(10);
3335 var PollFnCtx pollctx;
3336 var uint32_t sched_fn;
3337 var GprsMS ms;
3338
3339 var MultislotCap_GPRS mscap_gprs := {
3340 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3341 gprsextendeddynalloccap := '0'B
3342 };
3343 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3344
3345
3346 /* Initialize NS/BSSGP side */
3347 f_init_bssgp();
3348 /* Initialize GPRS MS side */
3349 f_init_gprs_ms();
3350 ms := g_ms[0]; /* We only use first MS in this test */
3351
3352 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003353 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3354 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003355
3356 /* Initialize the PCU interface abstraction */
3357 f_init_raw(testcasename(), info_ind);
3358
3359 /* Establish BSSGP connection to the PCU */
3360 f_bssgp_establish();
3361 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3362
3363 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3364 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3365
3366 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3367 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3368
3369 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3370 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3371 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3372 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3373 f_shutdown(__BFILE__, __LINE__);
3374 }
3375 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3376
3377 f_shutdown(__BFILE__, __LINE__, final := true);
3378}
3379
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003380testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3381 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3382 var RlcmacDlBlock dl_block;
3383 var octetstring data := f_rnd_octstring(10);
3384 var PollFnCtx pollctx;
3385 var uint32_t sched_fn;
3386 var GprsMS ms;
3387
3388 var MultislotCap_GPRS mscap_gprs := {
3389 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3390 gprsextendeddynalloccap := '0'B
3391 };
3392 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3393
3394
3395 /* Initialize NS/BSSGP side */
3396 f_init_bssgp();
3397 /* Initialize GPRS MS side */
3398 f_init_gprs_ms();
3399 ms := g_ms[0]; /* We only use first MS in this test */
3400
3401 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003402 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3403 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003404
3405 /* Initialize the PCU interface abstraction */
3406 f_init_raw(testcasename(), info_ind);
3407
3408 /* Establish BSSGP connection to the PCU */
3409 f_bssgp_establish();
3410 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3411
3412 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3413 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3414
3415 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3416 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3417 f_shutdown(__BFILE__, __LINE__);
3418 }
3419
3420 f_shutdown(__BFILE__, __LINE__, final := true);
3421}
3422
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003423/* Test scenario where MS wants to request a new TBF once the current one is
3424 * ending, by means of sending a Packet Resource Request on ul slot provided by
3425 * last Pkt Ul ACK's RRBP.
3426 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3427testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003428 var RlcmacDlBlock dl_block;
3429 var octetstring data := f_rnd_octstring(10);
3430 var uint32_t sched_fn;
3431 var uint32_t dl_fn;
3432 var template RlcmacDlBlock acknack_tmpl;
3433 var GprsMS ms;
3434
3435 /* Initialize NS/BSSGP side */
3436 f_init_bssgp();
3437 /* Initialize GPRS MS side */
3438 f_init_gprs_ms();
3439 ms := g_ms[0]; /* We only use first MS in this test */
3440
3441 /* Initialize the PCU interface abstraction */
3442 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003443 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003444
3445 /* Establish BSSGP connection to the PCU */
3446 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003447 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003448
3449 /* Establish an Uplink TBF */
3450 f_ms_establish_ul_tbf(ms);
3451
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003452 /* Wait until PCU starts requesting for UL block on this TBF: */
3453 f_ms_wait_usf(ms);
3454
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003455 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003456 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003457 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 +02003458
3459 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003460 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003461
3462 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3463 tr_UlAckNackGprs(ms.tlli,
3464 tr_AckNackDescription(final_ack := '1'B),
3465 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3466 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3467
3468 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3469
3470 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003471 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 +07003472 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003473 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3474 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3475
3476 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3477 and make sure it is ACKED fine */
3478 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3479
3480 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003481 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003482
3483 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3484 /* ACK the ACK */
3485 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3486
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003487 var StatsDExpects expect := {
3488 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3489 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3490 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3491 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3492 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3493 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3494 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3495 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3496 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3497 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3498 };
3499 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003500
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003501 f_shutdown(__BFILE__, __LINE__, final := true);
3502}
3503
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003504/* Test scenario where MS wants to request a new TBF once the current one is
3505 * ending, by means of sending a Packet Resource Request on ul slot provided by
3506 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3507 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003508testcase TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() runs on RAW_PCU_Test_CT {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003509 var PCUIF_info_ind info_ind;
3510 var RlcmacDlBlock dl_block;
3511 var octetstring data := f_rnd_octstring(10);
3512 var uint32_t sched_fn;
3513 var uint32_t dl_fn;
3514 var template (value) TsTrxBtsNum nr;
3515 var BTS_PDTCH_Block data_msg;
3516 var template RlcmacDlBlock acknack_tmpl;
3517 var GprsMS ms;
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003518 var integer cnt_rrbp := 0;
3519 var integer cnt_dummy_after_timeout := 0;
3520 /* Maximum T3168 value = 8 * 500 ms = 4s => * 4 retrans = 16s */
3521 timer T_3168 := 16.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003522
3523 /* Initialize NS/BSSGP side */
3524 f_init_bssgp();
3525 /* Initialize GPRS MS side */
3526 f_init_gprs_ms();
3527 ms := g_ms[0]; /* We only use first MS in this test */
3528
3529 /* Initialize the PCU interface abstraction */
3530 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003531 /* TODO: Speedup test by sending a PCU_IF_SAPI_BCCH SI13 with T3168=0 (500ms) */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003532 f_init_raw(testcasename(), info_ind);
3533
3534 /* Establish BSSGP connection to the PCU */
3535 f_bssgp_establish();
3536 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3537
3538 /* Establish an Uplink TBF */
3539 f_ms_establish_ul_tbf(ms);
3540
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003541 /* Wait until PCU starts requesting for UL block on this TBF: */
3542 f_ms_wait_usf(ms);
3543
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003544 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003545 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003546 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3547
3548 /* UL block should be received in SGSN */
3549 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3550
3551 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3552 tr_UlAckNackGprs(ms.tlli,
3553 tr_AckNackDescription(final_ack := '1'B),
3554 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3555 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3556
3557 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3558
3559 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003560 T_3168.start;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003561 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3562
3563 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3564 /* Now we go on receiving DL data and not answering RRBP: */
3565 nr := ts_TsTrxBtsNum;
3566 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3567 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3568 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3569 block_nr := nr.blk_nr));
3570 alt {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003571 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003572 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3573 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003574 /* We should not be receiving PKT UL ASS anymore after T3168 timeout */
3575 if (not T_3168.running) {
3576 setverdict(fail, log2str("Unexpected PKT UL ASS after T3168 timeout: ", data_msg));
3577 f_shutdown(__BFILE__, __LINE__);
3578 }
3579
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003580 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003581 log("Ignoring RRBP ", cnt_rrbp);
3582 cnt_rrbp := cnt_rrbp + 1;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003583 }
3584 nr := ts_TsTrxBtsNum;
3585 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3586 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3587 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3588 block_nr := nr.blk_nr));
3589 repeat;
3590 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003591 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003592 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003593 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003594 nr := ts_TsTrxBtsNum;
3595 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3596 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3597 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3598 block_nr := nr.blk_nr));
3599 repeat;
3600 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003601 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003602 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3603 omit)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003604
3605 /* T3168 expired and we are not receiving blocks anymore, meaning PCU released the TBF. */
3606 break;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003607 }
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003608 [] BTS.receive {
3609 setverdict(fail, "Unexpected BTS message");
3610 f_shutdown(__BFILE__, __LINE__);
3611 }
3612 }
3613
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003614 /* Check that we received at least a few PKT UL ASS before T3168 expiration */
3615 if (cnt_rrbp <= 3) {
3616 setverdict(fail, log2str("Received only ", cnt_rrbp, " before T3168 timeout!"));
3617 f_shutdown(__BFILE__, __LINE__);
3618 }
3619
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003620 f_shutdown(__BFILE__, __LINE__, final := true);
3621}
3622
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003623/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3624 * transmitted on ul slot provided by its DL TBF.
3625 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3626function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3627 var GprsMS ms;
3628 var octetstring data := f_rnd_octstring(10);
3629 var RlcmacDlBlock dl_block;
3630 var template RlcmacDlBlock rej_tmpl;
3631 var uint32_t dl_fn;
3632 var uint32_t sched_fn;
3633 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3634
3635 if (use_egprs == true) {
3636 racap_tmpl := bssgp_ms_racap_egprs_def;
3637 } else {
3638 racap_tmpl := bssgp_ms_racap_gprs_def;
3639 }
3640
3641 /* Initialize NS/BSSGP side */
3642 f_init_bssgp();
3643 /* Initialize GPRS MS side */
3644 f_init_gprs_ms();
3645 ms := g_ms[0]; /* We only use first MS in this test */
3646 /* Initialize the PCU interface abstraction */
3647 f_init_raw(testcasename());
3648
3649 /* Establish BSSGP connection to the PCU */
3650 f_bssgp_establish();
3651 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3652
3653 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02003654 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003655 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003656
3657 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3658 f_sleep(X2002);
3659 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3660
3661 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3662 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3663 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3664 f_dl_block_ack_fn(dl_block, dl_fn));
3665
3666 /* We should receive a Pkt Ul ASS */
3667 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3668 f_shutdown(__BFILE__, __LINE__, final := true);
3669}
3670testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3671 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3672}
3673testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3674 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3675}
3676
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003677/* Test UL data blocks BSN 0..127 and then continue again at BSN 0... up to 300
3678 * BSNs in total to test several wrap arounds. */
3679testcase TC_ul_tbf_bsn_wraparound_gprs() runs on RAW_PCU_Test_CT
3680{
3681 var PCUIF_info_ind info_ind;
3682 var RlcmacDlBlock dl_block;
3683 var octetstring payload;
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003684 var template (value) LlcBlockHdr blk_hdr;
3685 var template (value) LlcBlocks blocks;
3686 var uint32_t sched_fn;
3687 var uint32_t dl_fn;
3688 var template (value) TsTrxBtsNum nr;
3689 var BTS_PDTCH_Block data_msg;
3690 var template RlcmacDlBlock acknack_tmpl;
3691 var GprsMS ms;
3692 var integer blocks_sent := 0;
3693 var integer blocks_received := 0;
3694 const integer target_bsn_set := 300;
3695
3696 /* Initialize NS/BSSGP side */
3697 f_init_bssgp();
3698 /* Initialize GPRS MS side */
3699 f_init_gprs_ms();
3700 ms := g_ms[0]; /* We only use first MS in this test */
3701
3702 /* Initialize the PCU interface abstraction */
3703 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3704 f_init_raw(testcasename(), info_ind);
3705
3706 /* Establish BSSGP connection to the PCU */
3707 f_bssgp_establish();
3708 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3709
3710 /* Establish an Uplink TBF */
3711 f_ms_establish_ul_tbf(ms);
3712
3713 /* Wait until PCU starts requesting for UL block on this TBF: */
3714 dl_fn := f_ms_wait_usf(ms);
3715 sched_fn := f_next_pdch_block(dl_fn);
3716
3717 /* Send one UL block (with TLLI since we are in One-Phase Access
3718 contention resolution) and make sure it is ACKED fine. */
3719 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
3720 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
3721 more := false, e := true);
3722 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
3723 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedrolbd849cc2023-07-28 14:54:46 +02003724 f_ms_tx_ul_data_blocks_gprs(ms, blocks, cv := 15, with_tlli := true, fn := sched_fn);
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003725 blocks_sent := blocks_sent + 1;
3726
3727 /* UL block should be received in SGSN */
3728 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3729
3730 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3731 tr_UlAckNackGprs(ms.tlli,
3732 tr_AckNackDescription(final_ack := '0'B)))
3733 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3734
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003735 nr := f_ms_tx_TsTrxBtsNum(ms);
3736 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3737 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3738 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3739 block_nr := nr.blk_nr));
3740 alt {
3741 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3742 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3743 tr_RLCMAC_UL_ACK_NACK_GPRS)) -> value data_msg {
3744
3745 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3746 var uint32_t ack_fn := f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn)
3747 log("ACKING FN ", data_msg.raw.fn, " on FN ", ack_fn);
3748 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), ack_fn);
3749 }
Pau Espin Pedrolbd849cc2023-07-28 14:54:46 +02003750 f_ms_tx_ul_data_blocks_gprs(ms, blocks);
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003751 blocks_sent := blocks_sent + 1;
3752
3753 if (blocks_sent == target_bsn_set) {
3754 break;
3755 }
3756
3757 nr := f_ms_tx_TsTrxBtsNum(ms);
3758 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3759 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3760 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3761 block_nr := nr.blk_nr));
3762 repeat;
3763 }
3764 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3765 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3766 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
3767
Pau Espin Pedrolbd849cc2023-07-28 14:54:46 +02003768 f_ms_tx_ul_data_blocks_gprs(ms, blocks);
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003769 blocks_sent := blocks_sent + 1;
3770
3771 if (blocks_sent == target_bsn_set) {
3772 break;
3773 }
3774
3775 nr := f_ms_tx_TsTrxBtsNum(ms);
3776 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3777 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3778 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3779 block_nr := nr.blk_nr));
3780 repeat;
3781 }
3782 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3783 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3784 omit)) -> value data_msg {
3785 nr := f_ms_tx_TsTrxBtsNum(ms);
3786 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3787 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3788 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3789 block_nr := nr.blk_nr));
3790 repeat;
3791 }
3792 [] BTS.receive {
3793 setverdict(fail, "Unexpected BTS message");
3794 f_shutdown(__BFILE__, __LINE__);
3795 }
3796 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id)) {
3797 blocks_received := blocks_received + 1;
3798 repeat;
3799 }
3800 }
3801
3802 /* Validate most part of them were accepted and forwarded: */
3803 if (blocks_received < target_bsn_set * 95 / 100) {
3804 setverdict(fail, "Forwarded ", blocks_received, " out of ", target_bsn_set, " transmitted");
3805 f_shutdown(__BFILE__, __LINE__);
3806 }
3807 log("Forwarded ", blocks_received, " out of ", target_bsn_set, " transmitted");
3808
3809 f_shutdown(__BFILE__, __LINE__, final := true);
3810}
3811
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003812/* Test CS paging over the BTS<->PCU socket.
3813 * 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.
3814 * Paging should be send on the PACCH.
3815 *
3816 * 1. Send a Paging Request over PCU socket.
3817 * 2. Send a Ready-To-Send message over PCU socket
3818 * 3. Expect a Paging Frame
3819 */
3820testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003821 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003822 var MobileIdentityLV mi;
3823 var octetstring mi_enc_lv;
3824 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003825 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003826
3827 /* Initialize NS/BSSGP side */
3828 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003829 /* Initialize GPRS MS side */
3830 f_init_gprs_ms();
3831 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003832
3833 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003834 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003835
3836 /* Establish BSSGP connection to the PCU */
3837 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003838 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003839
3840 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003841 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003842
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003843 /* Wait until PCU starts requesting for UL block on this TBF: */
3844 f_ms_wait_usf(ms);
3845
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003846 /* build mobile Identity */
3847 mi := valueof(ts_MI_IMSI_LV(imsi));
3848 mi_enc_lv := enc_MobileIdentityLV(mi);
3849 /* Send paging request */
3850 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3851 sapi :=PCU_IF_SAPI_PDTCH));
3852
3853 /* Receive it on BTS side towards MS */
3854 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3855
3856 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003857 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3858 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3859 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3860 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003861
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003862 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003863}
3864
3865/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3866 */
3867private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3868runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003869 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003870 var hexstring imsi := f_gen_imsi(42);
3871 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003872 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003873
3874 /* Initialize NS/BSSGP side */
3875 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003876 /* Initialize GPRS MS side */
3877 f_init_gprs_ms();
3878 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003879
3880 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003881 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003882
3883 /* Establish BSSGP connection to the PCU */
3884 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003885 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003886
3887 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003888 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003889
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003890 /* Wait until PCU starts requesting for UL block on this TBF: */
3891 f_ms_wait_usf(ms);
3892
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003893 /* Send paging request with or without TMSI */
3894 if (use_ptmsi) {
3895 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3896 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3897 } else {
3898 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3899 }
3900
Pau Espin Pedrol00fec582022-11-29 16:03:13 +01003901 /* Now receive it on BTS side towards MS.
3902 * Skip any dummy blocks in case the PCUIF req arrives before the BSSP CS_PAGING:
3903 */
3904 f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
3905
3906 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
3907 setverdict(fail, "Failed to match Packet Paging Request: ",
3908 dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
3909 f_shutdown(__BFILE__, __LINE__);
3910 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003911
3912 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003913 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003914 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003915 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3916 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3917 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003918 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003919 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3920 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3921 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003922 }
3923
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003924 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003925}
3926
3927testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3928 f_tc_paging_cs_from_sgsn(0, true);
3929}
3930
3931testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3932 f_tc_paging_cs_from_sgsn(0);
3933}
3934
3935testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003936 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003937}
3938
3939/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3940 */
3941private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3942runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003943 var integer imsi_suff_tx := 423;
3944 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003945 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003946
3947 /* Initialize NS/BSSGP side */
3948 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003949 /* Initialize GPRS MS side */
3950 f_init_gprs_ms();
3951 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003952
Oliver Smith61b4e732021-07-22 08:14:29 +02003953 f_statsd_reset();
3954
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003955 /* Establish BSSGP connection to the PCU */
3956 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003957 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003958
3959 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3960 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3961 if (use_ptmsi) {
3962 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3963 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3964 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3965 } else {
3966 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3967 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3968 }
3969
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003970 var StatsDExpects expect := {
3971 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3972 /* After the PCU receives the paging request from SGSN,
3973 * and it doesn't have any errors, PCU sends it to the
3974 * BTS to do paging over PCH. */
3975 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3976 };
3977 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003978}
3979
3980testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3981 /* Initialize the PCU interface abstraction */
3982 f_init_raw(testcasename());
3983
3984 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003985
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003986 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003987}
3988
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003989testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003990 /* Initialize the PCU interface abstraction */
3991 f_init_raw(testcasename());
3992
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003993 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003994
3995 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003996}
3997
3998testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003999 /* Initialize the PCU interface abstraction */
4000 f_init_raw(testcasename());
4001
Harald Welte5339b2e2020-10-04 22:52:56 +02004002 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02004003
4004 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004005}
4006
Oliver Smithe1a77c42021-07-28 13:36:09 +02004007testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
4008 /* Initialize the PCU interface abstraction */
4009 f_init_raw(testcasename());
4010
4011 /* Set T3113 to 1s to shorten the test duration */
4012 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
4013
4014 /* Reset stats and send paging PS request */
4015 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
4016
4017 /* Verify that counter increases when T3113 times out (MS did not start
4018 * TBF to respond to paging). */
4019 f_sleep(1.2);
4020 var StatsDExpects expect := {
4021 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
4022 };
4023 f_statsd_expect(expect);
4024
4025 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
4026 f_shutdown(__BFILE__, __LINE__, final := true);
4027}
4028
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004029/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
4030testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
4031 var RlcmacDlBlock dl_block;
4032 var octetstring data := f_rnd_octstring(10);
4033 var uint32_t sched_fn;
4034 var uint32_t dl_fn;
4035 var GprsMS ms;
4036
4037 /* Initialize NS/BSSGP side */
4038 f_init_bssgp();
4039 /* Initialize GPRS MS side */
4040 f_init_gprs_ms();
4041 ms := g_ms[0]; /* We only use first MS in this test */
4042
4043 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004044 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004045
Daniel Willmann535aea62020-09-21 13:27:08 +02004046 f_statsd_reset();
4047
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004048 /* Establish BSSGP connection to the PCU */
4049 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004050 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004051
4052 /* Establish an Uplink TBF */
4053 f_ms_establish_ul_tbf(ms);
4054
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004055 /* Wait until PCU starts requesting for UL block on this TBF: */
4056 f_ms_wait_usf(ms);
4057
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004058 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004059 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 +02004060 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4061 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4062 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4063
4064 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02004065 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004066
4067 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4068 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004069 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004070
4071 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
4072 f_sleep(X2002);
4073 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4074
4075 /* ACK the DL block */
4076 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
4077 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
4078 f_dl_block_ack_fn(dl_block, dl_fn));
4079
Daniel Willmann535aea62020-09-21 13:27:08 +02004080 var StatsDExpects expect := {
4081 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
4082 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
4083 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
4084 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01004085 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01004086 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02004087 };
4088 f_statsd_expect(expect);
4089
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004090 f_shutdown(__BFILE__, __LINE__, final := true);
4091}
4092
4093/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
4094testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
4095 var RlcmacDlBlock dl_block;
4096 var octetstring data := f_rnd_octstring(10);
4097 var uint32_t sched_fn;
4098 var uint32_t dl_fn;
4099 var GprsMS ms;
4100
4101 /* Initialize NS/BSSGP side */
4102 f_init_bssgp();
4103 /* Initialize GPRS MS side */
4104 f_init_gprs_ms();
4105 ms := g_ms[0]; /* We only use first MS in this test */
4106
4107 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004108 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004109
4110 /* Establish BSSGP connection to the PCU */
4111 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004112 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004113
4114 /* Establish an Uplink TBF */
4115 f_ms_establish_ul_tbf(ms);
4116
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004117 /* Wait until PCU starts requesting for UL block on this TBF: */
4118 f_ms_wait_usf(ms);
4119
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004120 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004121 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 +02004122 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4123 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4124 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4125
4126 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02004127 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004128
4129 /* Now SGSN sends some DL data with an invalid IMSI */
4130 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
4131
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01004132 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004133
4134 /* TODO: make sure no data is sent over PCU -> MS */
4135
4136 f_shutdown(__BFILE__, __LINE__, final := true);
4137}
4138
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004139private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
4140 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
4141 var octetstring data := f_rnd_octstring(6);
4142 var RlcmacDlBlock dl_block;
4143 var GprsMS ms;
4144 var uint32_t fn;
4145
4146 /* Initialize NS/BSSGP side */
4147 f_init_bssgp();
4148 /* Initialize GPRS MS side */
4149 f_init_gprs_ms();
4150 ms := g_ms[0]; /* We only use first MS in this test */
4151
4152 /* Initialize the PCU interface abstraction */
4153 f_init_raw(testcasename());
4154
4155 /* Establish BSSGP connection to the PCU */
4156 f_bssgp_establish();
4157 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4158
4159 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004160 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004161 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004162
4163 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
4164 f_sleep(X2002);
4165
4166 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
4167 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
4168
4169 if (ischosen(dl_block.data_egprs)) {
4170 if (lengthof(dl_block.data_egprs.blocks) != 2) {
4171 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
4172 f_shutdown(__BFILE__, __LINE__);
4173 }
4174 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
4175 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
4176 f_shutdown(__BFILE__, __LINE__);
4177 }
4178 if (not match(dl_block.data_egprs.blocks[1].payload,
4179 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
4180 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
4181 f_shutdown(__BFILE__, __LINE__);
4182 }
4183 } else if (lengthof(dl_block.data.blocks) > 1) {
4184 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
4185 f_shutdown(__BFILE__, __LINE__);
4186 }
4187
4188 f_shutdown(__BFILE__, __LINE__, final := true);
4189}
4190
4191/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
4192 * containing llc data. See OS#4849 */
4193testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
4194 f_tc_dl_data_no_llc_ui_dummy(omit);
4195}
4196
4197/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
4198 * containing llc data. See OS#4849 */
4199testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004200 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004201}
4202
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004203/* Scenario: MS creates one phase access, does contention resolution CV>0 and
4204 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
4205 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
4206 * has to assign a DL TBF (through PCH because of FINISHED state, TS 44.060 9.3.3.3.2).
4207 * Make sure the assignment is not done until we receive the PKT CTRL ACK from the MS
4208 * (at that time we know the MS is listening on PCH again). OS#5700.
4209 */
4210testcase TC_ul_tbf_finished_pkt_dl_ass_pch() runs on RAW_PCU_Test_CT {
4211 var RlcmacDlBlock dl_block;
4212 var octetstring data := f_rnd_octstring(10);
4213 var uint32_t sched_fn;
4214 var uint32_t dl_fn;
4215 var GprsMS ms;
4216 timer T;
4217 var octetstring payload;
4218
4219 /* Initialize NS/BSSGP side */
4220 f_init_bssgp();
4221 /* Initialize GPRS MS side */
4222 f_init_gprs_ms();
4223 ms := g_ms[0]; /* We only use first MS in this test */
4224
4225 /* Initialize the PCU interface abstraction */
4226 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4227
4228 /* Establish BSSGP connection to the PCU */
4229 f_bssgp_establish();
4230 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4231
4232 /* Establish an Uplink TBF */
4233 f_ms_establish_ul_tbf(ms);
4234
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004235 /* Wait until PCU starts requesting for UL block on this TBF: */
4236 f_ms_wait_usf(ms);
4237
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004238 /* Send one UL block (with TLLI since we are in One-Phase Access
4239 contention resolution) and make sure it is ACKED fine. */
4240 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4241 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4242 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4243
4244 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4245 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4246 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4247 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4248
4249 /* 1 UL block should be received in SGSN */
4250 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4251 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004252 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004253
4254 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4255 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004256 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004257 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
4258 f_sleep(X2002);
4259 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4260
4261 f_shutdown(__BFILE__, __LINE__, final := true);
4262}
4263
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004264/* Scenario: MS creates a UL TBF and
4265 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
4266 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
4267 * has to assign a DL TBF on PCH. While the network is waiting for the MS to
4268 * move to PDCH before transmitting DL data (timer X2002), the MS finds out it
4269 * needs to send new UL data and hence sends a RACH request to create a new UL
4270 * TBF.
4271 * Make sure the the MS is assigned a DL TBF through PACCH in that case even if
4272 * no new DL data is received from the SGSN. OS#5700.
4273 * This test validates the specific case where the 2nd UL TBF is done through
4274 * 1phase-access.
4275 */
4276testcase TC_ul_tbf_1phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4277 var RlcmacDlBlock dl_block;
4278 var octetstring data := f_rnd_octstring(10);
4279 var uint32_t sched_fn;
4280 var uint32_t poll_fn;
4281 var uint32_t dl_fn;
4282 var GprsMS ms;
4283 timer T;
4284 var octetstring payload;
4285
4286 /* Initialize NS/BSSGP side */
4287 f_init_bssgp();
4288 /* Initialize GPRS MS side */
4289 f_init_gprs_ms();
4290 ms := g_ms[0]; /* We only use first MS in this test */
4291
4292 /* Initialize the PCU interface abstraction */
4293 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4294
4295 /* Establish BSSGP connection to the PCU */
4296 f_bssgp_establish();
4297 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4298
4299 /* Establish an Uplink TBF */
4300 f_ms_establish_ul_tbf(ms);
4301
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004302 /* Wait until PCU starts requesting for UL block on this TBF: */
4303 f_ms_wait_usf(ms);
4304
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004305 /* Send one UL block (with TLLI since we are in One-Phase Access
4306 contention resolution) and make sure it is ACKED fine. */
4307 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4308 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4309 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4310
4311 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4312 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4313 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4314 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4315
4316 /* 1 UL block should be received in SGSN */
4317 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4318 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004319 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004320
4321 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4322 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004323 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004324
4325 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4326 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4327 f_ms_establish_ul_tbf(ms);
4328
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004329 /* Wait until PCU starts requesting for UL block on this TBF: */
4330 dl_fn := f_ms_wait_usf(ms);
4331
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004332 /* Send one UL block (with TLLI since we are in One-Phase Access
4333 * contention resolution) and make sure it is ACKED fine. */
4334 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004335 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4336
4337 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4338 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4339
4340 /* The PCU considers the MS to have gone over Contention Resolution
4341 * after having sent the first UL ACK/NACK to it, hence next it will try to
4342 * assign the DL-TBF to send the data it received from the SGSN previously: */
4343 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4344 /* the MS ACKs the PKT_DL_ASS: */
4345 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4346
4347 /* We should finally receive the DL-data that was received previously from the SGSN: */
4348 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4349
4350 f_shutdown(__BFILE__, __LINE__, final := true);
4351}
4352
4353/* Same as TC_ul_tbf_2phase_while_dl_ass_pch, but this test validates the
4354 * specific case where the 2nd UL TBF is done through 2phase-access. */
4355testcase TC_ul_tbf_2phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4356 var RlcmacDlBlock dl_block;
4357 var octetstring data := f_rnd_octstring(10);
4358 var uint32_t sched_fn;
4359 var uint32_t poll_fn;
4360 var uint32_t dl_fn;
4361 var GprsMS ms;
4362 timer T;
4363 var octetstring payload;
4364 var PollFnCtx pollctx;
4365
4366 /* Initialize NS/BSSGP side */
4367 f_init_bssgp();
4368 /* Initialize GPRS MS side */
4369 f_init_gprs_ms();
4370 ms := g_ms[0]; /* We only use first MS in this test */
4371
4372 /* Initialize the PCU interface abstraction */
4373 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4374
4375 /* Establish BSSGP connection to the PCU */
4376 f_bssgp_establish();
4377 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4378
4379 /* Establish an Uplink TBF */
4380 f_ms_establish_ul_tbf(ms);
4381
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004382 /* Wait until PCU starts requesting for UL block on this TBF: */
4383 f_ms_wait_usf(ms);
4384
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004385 /* Send one UL block (with TLLI since we are in One-Phase Access
4386 contention resolution) and make sure it is ACKED fine. */
4387 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4388 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4389 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4390
4391 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4392 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4393 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4394 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4395
4396 /* 1 UL block should be received in SGSN */
4397 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4398 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004399 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004400
4401 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4402 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004403 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004404
4405 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4406 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4407 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4408
4409 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4410 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4411
4412 /* Now that MS seized the UL-TBF, PCU sends DL-TBF Assignment on PACCH */
4413 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4414 /* the MS ACKs the PKT_DL_ASS: */
4415 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4416
4417 /* We should finally receive the DL-data that was received previously from the SGSN: */
4418 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4419
4420 f_shutdown(__BFILE__, __LINE__, final := true);
4421}
4422
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004423private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004424 template GsmRrMessage t_imm_ass := ?,
4425 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004426runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004427 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004428 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004429
4430 ra11 := enc_EGPRSPktChRequest2uint(req);
4431 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
4432
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07004433 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004434 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004435 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004436 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004437 }
4438
4439 setverdict(pass);
4440}
4441
4442testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
4443 var template GsmRrMessage imm_ass;
4444 var template IaRestOctets rest;
4445 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004446 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004447
4448 /* Initialize the PCU interface abstraction */
4449 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004450 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004451
4452 var EGPRSPktChRequest req := {
4453 /* NOTE: other fields are set in the loop */
4454 signalling := { tag := '110011'B }
4455 };
4456
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004457 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004458 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4459 req.signalling.random_bits := ext_ra;
4460
4461 /* For signalling, do we expect Multiblock UL TBF Assignment? */
4462 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4463 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4464 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4465
4466 f_TC_egprs_pkt_chan_req(req, imm_ass);
4467 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004468
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004469 var StatsDExpects expect := {
4470 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4471 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4472 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4473 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4474 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4475 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4476 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4477 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4478 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4479 };
4480 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004481
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004482 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004483}
4484
4485testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
4486 var template GsmRrMessage imm_ass;
4487 var template IaRestOctets rest;
4488 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004489 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004490
4491 /* Initialize the PCU interface abstraction */
4492 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004493 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004494
4495 var EGPRSPktChRequest req := {
4496 /* NOTE: other fields are set in the loop */
4497 one_phase := { tag := '0'B }
4498 };
4499
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004500 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004501 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4502 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
4503 var BIT2 priority := substr(ext_ra, 0, 2);
4504 var BIT3 rand := substr(ext_ra, 2, 3);
4505
4506 req.one_phase.multislot_class := mslot_class;
4507 req.one_phase.priority := priority;
4508 req.one_phase.random_bits := rand;
4509
4510 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
4511 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
4512 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4513 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4514
4515 f_TC_egprs_pkt_chan_req(req, imm_ass);
4516 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004517
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004518 var StatsDExpects expect := {
4519 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4520 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4521 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4522 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4523 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4524 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4525 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4526 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4527 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4528 };
4529 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004530
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004531 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004532}
4533
4534testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4535 var template GsmRrMessage imm_ass;
4536 var template IaRestOctets rest;
4537 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004538 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004539
4540 /* Initialize the PCU interface abstraction */
4541 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004542 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004543
4544 var EGPRSPktChRequest req := {
4545 /* NOTE: other fields are set in the loop */
4546 two_phase := { tag := '110000'B }
4547 };
4548
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004549 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004550 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4551 var BIT2 priority := substr(ext_ra, 0, 2);
4552 var BIT3 rand := substr(ext_ra, 2, 3);
4553
4554 req.two_phase.priority := priority;
4555 req.two_phase.random_bits := rand;
4556
4557 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4558 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4559 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4560 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4561
4562 f_TC_egprs_pkt_chan_req(req, imm_ass);
4563 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004564
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004565 var StatsDExpects expect := {
4566 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4567 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4568 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4569 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4570 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4571 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4572 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4573 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4574 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4575 };
4576 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004577
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004578 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004579}
4580
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004581private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4582 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004583 PCUIF_BurstType bt := BURST_TYPE_1,
4584 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004585runs on RAW_PCU_Test_CT {
4586 var template ReqRefWaitInd tr_ref;
4587 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004588
4589 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4590 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4591 ra := bit2int(ra11), is_11bit := 1,
4592 burst_type := bt, fn := fn,
4593 arfcn := 871));
4594
4595 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004596 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004597
4598 /* Just to have a short-name reference to the actual message */
4599 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4600
4601 /* Make sure that Request Reference list contains at least one entry
4602 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004603 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004604 if (not match(iar.payload, { *, tr_ref, * })) {
4605 setverdict(fail, "Request Reference list does not match");
4606 f_shutdown(__BFILE__, __LINE__);
4607 }
4608
4609 /* Match Feature Indicator (must indicate PS domain) */
4610 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4611 setverdict(fail, "Feature Indicator does not match");
4612 f_shutdown(__BFILE__, __LINE__);
4613 }
4614
4615 /* Match IAR Rest Octets */
4616 if (not match(iar.rest_octets, rest)) {
4617 setverdict(fail, "IAR Rest Octets does not match: ",
4618 iar.rest_octets, " vs expected ", rest);
4619 f_shutdown(__BFILE__, __LINE__);
4620 }
4621
4622 setverdict(pass);
4623}
4624
4625/* Verify the contents of RR Immediate Assignment Reject message and its
4626 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4627testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4628 var template IARRestOctets rest;
4629 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004630 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004631
4632 /* Initialize the PCU interface abstraction */
4633 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004634 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004635
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004636 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004637 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4638 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4639
4640 /* Intentionally incorrect message (see table 11.2.5a.2) */
4641 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4642 }
4643
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004644 var StatsDExpects expect := {
4645 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4646 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4647 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4648 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4649 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4650 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4651 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4652 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4653 };
4654 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004655
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004656 f_shutdown(__BFILE__, __LINE__, final := true);
4657}
4658
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004659/* At the moment, the IUT does not support any emergency services. Make sure
4660 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4661testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4662 var template IARRestOctets rest;
4663 var BIT5 ext_ra;
4664 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004665 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004666
4667 /* Initialize the PCU interface abstraction */
4668 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004669 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004670
4671 var EGPRSPktChRequest req := {
4672 /* NOTE: other fields are set in the loop */
4673 emergency := { tag := '110111'B }
4674 };
4675
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004676 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004677 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4678 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4679
4680 req.emergency.random_bits := ext_ra;
4681 ra11 := enc_EGPRSPktChRequest2bits(req);
4682
4683 /* Intentionally incorrect message (see table 11.2.5a.2) */
4684 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4685 }
4686
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004687 var StatsDExpects expect := {
4688 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4689 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4690 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4691 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4692 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4693 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4694 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4695 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4696 };
4697 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004698
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004699 f_shutdown(__BFILE__, __LINE__, final := true);
4700}
4701
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004702/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4703testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004704 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004705 var template IARRestOctets rest;
4706 var BIT11 ra11;
4707
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004708 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004709 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004710
4711 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004712 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4713 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004714
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004715 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004716 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004717 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004718
4719 var EGPRSPktChRequest req := {
4720 one_phase := {
4721 tag := '0'B,
4722 multislot_class := '10101'B,
4723 priority := '01'B,
4724 random_bits := '101'B
4725 }
4726 };
4727
4728 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4729 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4730 for (var integer i := 0; i < 7; i := i + 1) {
4731 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4732 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4733 }
4734
4735 ra11 := enc_EGPRSPktChRequest2bits(req);
4736 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4737
4738 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004739 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004740
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004741 var StatsDExpects expect := {
4742 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4743 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4744 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4745 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4746 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4747 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4748 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4749 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4750 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4751 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4752 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4753 };
4754 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004755
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004756 f_shutdown(__BFILE__, __LINE__, final := true);
4757}
4758
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004759/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004760private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004761return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004762 /* Pick a random MA length in range 2 .. max_ma_len */
4763 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4764
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004765 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4766 hsn := f_rnd_int(63),
4767 maio := f_rnd_int(63),
4768 ma := f_rnd_bitstring(ma_len));
4769}
4770
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004771private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4772 in GsmRrMessage rr_msg)
4773{
4774 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004775 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004776
4777 var template PacketChannelDescription tr_pkt_chan_desc := {
4778 channel_Type_spare := ?,
4779 tn := ?,
4780 tsc := ts.tsc,
4781 presence := '1'B,
4782 zero := omit,
4783 one := {
4784 maio := ts.maio,
4785 hsn := ts.hsn
4786 }
4787 };
4788
4789 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4790 setverdict(fail, "Packet Channel Description does not match: ",
4791 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4792 }
4793
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004794 /* Mobile Allocation is expected to be octet-aligned */
4795 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4796 var template MobileAllocationLV tr_ma := {
4797 len := ma_oct_len, /* in bytes */
4798 ma := substr(ts.ma, 0, ma_oct_len * 8)
4799 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004800
4801 if (not match(ia.mobile_allocation, tr_ma)) {
4802 setverdict(fail, "Mobile Allocation does not match: ",
4803 ia.mobile_allocation, " vs ", tr_ma);
4804 }
4805
4806 setverdict(pass);
4807}
4808
4809/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4810testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004811 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004812 var GprsMS ms := valueof(t_GprsMS_def);
4813
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004814 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004815 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004816
4817 /* Initialize the PCU interface abstraction */
4818 f_init_raw(testcasename(), info_ind);
4819
4820 /* EGPRS Packet Channel Request (cause=Signalling) */
4821 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4822
4823 /* Establish an Uplink EGPRS TBF */
4824 f_ms_establish_ul_tbf(ms);
4825
4826 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4827 f_shutdown(__BFILE__, __LINE__, final := true);
4828}
4829
4830/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4831testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004832 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004833 var GprsMS ms := valueof(t_GprsMS_def);
4834
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004835 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004836 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004837
4838 /* Initialize the PCU interface abstraction */
4839 f_init_raw(testcasename(), info_ind);
4840
4841 /* Establish an Uplink TBF */
4842 f_ms_establish_ul_tbf(ms);
4843
4844 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4845 f_shutdown(__BFILE__, __LINE__, final := true);
4846}
4847
4848/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4849testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004850 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004851 var GprsMS ms := valueof(t_GprsMS_def);
4852
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004853 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004854 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004855
4856 /* Initialize NS/BSSGP side */
4857 f_init_bssgp();
4858
4859 /* Initialize the PCU interface abstraction */
4860 f_init_raw(testcasename(), info_ind);
4861
4862 /* Establish BSSGP connection to the PCU */
4863 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004864 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004865
4866 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4867 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
Philipp Maier4222f472023-08-22 17:28:00 +02004868
4869 /* The PCU will send an IMMEDIATE ASSIGNMENT message on the AGCH. It
4870 * should be noted that IMMEDIATE ASSIGNMENT messages for DL TBFs are
4871 * commonly sent on the PCH. However in this case the IMSI is not
4872 * known to the PCU and hence no paging group can be calculated. The
4873 * PCU is then forced to use the AGCH.
4874 *
4875 * As a background information to this it should be noted that this
4876 * works because the IMSI is commonly unknown during a GMM ATTACH
4877 * REQUEST. In this phase the MS is in non-DRX mode, which means that
4878 * it listens on all CCCH blocks (PCH and AGCH)
4879 *
4880 * See also: 3gpp TS 44.060, section 5.5.1.5 and
4881 * 3gpp TS 45.002, section 6.5.3, 6.5.6
4882 */
4883 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_AGCH_2);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004884
4885 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4886 f_shutdown(__BFILE__, __LINE__, final := true);
4887}
4888
4889private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4890 in FrequencyParameters fp)
4891{
4892 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004893 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004894
4895 /* Table 12.8.1: Frequency Parameters information elements */
4896 var template FrequencyParameters tr_fp := {
4897 tsc := ts.tsc,
4898 presence := '10'B, /* Direct encoding 1 */
4899 arfcn := omit,
4900 indirect := omit,
4901 direct1 := {
4902 maio := ts.maio,
4903 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4904 mobile_allocation := {
4905 hsn := ts.hsn,
4906 rfl_number_list_present := '0'B,
4907 rfl_number_list := omit,
4908 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004909 ma_length := ts.ma_bit_len,
4910 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004911 }
4912 },
4913 direct2 := omit
4914 };
4915
4916 if (not match(fp, tr_fp)) {
4917 setverdict(fail, "Frequency Parameters IE does not match: ",
4918 fp, " vs ", tr_fp);
4919 }
4920
4921 setverdict(pass);
4922}
4923
4924/* Make sure that Packet Uplink Assignment contains hopping parameters */
4925testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004926 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004927 var GprsMS ms := valueof(t_GprsMS_def);
4928 var uint32_t poll_fn;
4929
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004930 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004931 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004932
4933 /* Initialize the PCU interface abstraction */
4934 f_init_raw(testcasename(), info_ind);
4935
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004936 /* Single block (two phase) packet access */
4937 var uint16_t ra := bit2int(chan_req_sb);
4938 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4939
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004940 /* Establish an Uplink TBF */
4941 f_ms_establish_ul_tbf(ms);
4942
4943 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004944 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4945 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004946
4947 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004948 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4949 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004950
4951 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4952 var template (omit) FrequencyParameters fp;
4953 if (ua.is_egprs == '1'B) {
4954 fp := ua.egprs.freq_par;
4955 } else {
4956 fp := ua.gprs.freq_par;
4957 }
4958
4959 /* This is an optional IE, so it's worth to check its presence */
4960 if (istemplatekind(fp, "omit")) {
4961 setverdict(fail, "Frequency Parameters IE is not present");
4962 f_shutdown(__BFILE__, __LINE__);
4963 }
4964
4965 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4966 f_shutdown(__BFILE__, __LINE__, final := true);
4967}
4968
4969/* Make sure that Packet Downlink Assignment contains hopping parameters */
4970testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004971 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004972 var octetstring data := f_rnd_octstring(10);
4973 var GprsMS ms := valueof(t_GprsMS_def);
4974 var RlcmacDlBlock dl_block;
4975 var uint32_t poll_fn;
4976
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004977 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004978 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004979
4980 /* Initialize NS/BSSGP side */
4981 f_init_bssgp();
4982
4983 /* Initialize the PCU interface abstraction */
4984 f_init_raw(testcasename(), info_ind);
4985
4986 /* Establish BSSGP connection to the PCU */
4987 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004988 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004989
4990 /* Establish an Uplink TBF */
4991 f_ms_establish_ul_tbf(ms);
4992
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004993 /* Wait until PCU starts requesting for UL block on this TBF: */
4994 f_ms_wait_usf(ms);
4995
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004996 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004997 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 +07004998
4999 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5000 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
5001 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
5002
5003 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
5004 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
5005
5006 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01005007 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
5008 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07005009
5010 /* This is an optional IE, so it's worth to check its presence */
5011 if (not ispresent(da.freq_par)) {
5012 setverdict(fail, "Frequency Parameters IE is not present");
5013 f_shutdown(__BFILE__, __LINE__);
5014 }
5015
5016 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
5017 f_shutdown(__BFILE__, __LINE__, final := true);
5018}
5019
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005020/* Check if the IUT handles subsequent INFO.ind messages */
5021testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01005022 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01005023 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005024
5025 /* Initialize the PCU interface abstraction */
5026 f_init_raw(testcasename(), info_ind);
5027
5028 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
5029 for (var integer i := 0; i < 16; i := i + 1) {
5030 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01005031 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005032 }
5033
5034 f_shutdown(__BFILE__, __LINE__, final := true);
5035}
5036
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005037/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
5038testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
5039 var PCUIF_info_ind info_ind;
5040 var integer i;
5041 const integer num_ms := 8;
5042
5043 /* Initialize NS/BSSGP side */
5044 f_init_bssgp();
5045 /* Initialize GPRS MS side */
5046 f_init_gprs_ms(num_ms);
5047
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01005048 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005049 /* Only the 3 first TRX are enabled. The enabled ones all have same
5050 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005051 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
5052 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
5053 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
5054 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005055
5056 /* Initialize the PCU interface abstraction */
5057 f_init_raw(testcasename(), info_ind);
5058
5059 /* Establish BSSGP connection to the PCU */
5060 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07005061 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005062
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07005063 /* Establish an Uplink TBF for each GprsMS instance */
5064 f_multi_ms_establish_tbf(do_activate := false);
5065
5066 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005067 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005068 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01005069 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005070 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005071 f_shutdown(__BFILE__, __LINE__);
5072 }
5073 }
5074
5075 f_shutdown(__BFILE__, __LINE__, final := true);
5076}
5077
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005078/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
5079 * downgraded to CS1-4 so that GPRS can read the USF).
5080 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
5081 */
5082testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
5083 var PCUIF_info_ind info_ind;
5084 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
5085 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005086 var uint32_t sched_fn, dl_fn, ack_fn;
5087 var octetstring data := f_rnd_octstring(10);
5088 var RlcmacDlBlock dl_block;
5089 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005090 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005091 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
5092 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
5093
5094 /* Initialize NS/BSSGP side */
5095 f_init_bssgp();
5096 /* Initialize GPRS MS side */
5097 f_init_gprs_ms(num_ms);
5098
5099 info_ind := valueof(ts_PCUIF_INFO_default);
5100 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005101 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
5102 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005103
5104 /* Initialize the PCU interface abstraction */
5105 f_init_raw(testcasename(), info_ind);
5106
5107 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
5108 g_mcs_initial_dl := 5;
5109 g_mcs_max_dl := 5;
5110 f_pcuvty_set_allowed_cs_mcs();
5111
5112 /* Establish BSSGP connection to the PCU */
5113 f_bssgp_establish();
5114 f_multi_ms_bssgp_register();
5115
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005116 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005117 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 +01005118 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
5119 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
5120 f_shutdown(__BFILE__, __LINE__);
5121 }
5122 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5123 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
5124
5125 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005126 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 +01005127 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
5128 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
5129 f_shutdown(__BFILE__, __LINE__);
5130 }
5131 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5132 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
5133
5134 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
5135 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5136 f_sleep(0.1);
5137 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
5138 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
5139 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
5140 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
5141 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
5142 /* ACK the DL block */
5143 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
5144 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
5145 f_dl_block_ack_fn(dl_block, dl_fn));
5146
5147 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
5148 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5149 f_sleep(0.1);
5150 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
5151 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
5152 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
5153 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
5154 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
5155 /* ACK the DL block */
5156 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
5157 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
5158 f_dl_block_ack_fn(dl_block, dl_fn));
5159
5160 data := f_rnd_octstring(1400);
5161 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5162 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5163
5164 for (var integer i := 0; i < 800; i := i + 1) {
5165 f_rx_rlcmac_dl_block(dl_block, dl_fn);
5166
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005167 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005168 /* No more data to receive, done */
5169 break;
5170 }
5171
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005172 usf_ms := -1;
5173
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005174 if (ischosen(dl_block.ctrl)) {
5175 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
5176 f_shutdown(__BFILE__, __LINE__);
5177 } else if (ischosen(dl_block.data_egprs)) {
5178 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
5179 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
5180 f_shutdown(__BFILE__, __LINE__);
5181 }
5182 tgt_ms := 1;
5183 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
5184 if (dl_block.data_egprs.mcs > MCS_4) {
5185 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
5186 f_shutdown(__BFILE__, __LINE__);
5187 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005188 usf_ms := 0;
5189 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005190 } else {
5191 if (dl_block.data_egprs.mcs <= MCS_4) {
5192 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
5193 f_shutdown(__BFILE__, __LINE__);
5194 }
5195 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005196 usf_ms := 1;
5197 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005198 }
5199 }
5200 } else {
5201 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
5202 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
5203 f_shutdown(__BFILE__, __LINE__);
5204 }
5205 tgt_ms := 0;
5206 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 +01005207 usf_ms := 0;
5208 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005209 } 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 +01005210 usf_ms := 1;
5211 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005212 }
5213 }
5214
5215 /* Keep Ack/Nack description updated */
5216 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
5217
5218 /* TDMA frame number on which we are supposed to send the ACK */
5219 if (f_dl_block_rrbp_valid(dl_block)) {
5220 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
5221 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);
5222 if (tx_data_remain != 0) {
5223 /* Submit more data from time to time to keep the TBF ongoing */
5224 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5225 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5226 tx_data_remain := tx_data_remain - 1;
5227 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005228 } else if (tx_data_remain != 0) {
5229 /* keep sending UL blocks when requested by USF to avoid
5230 * UL TBF timeout and hence stop receival of USFs */
5231 if (usf_ms != -1) {
5232 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
5233 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005234 }
5235 }
5236
5237 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 +01005238 /* He we check that DL blocks scheduled at GPRS can still request UL
5239 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
5240 * condition also ensures the downgrade to <=MCS4 condition is tested
5241 * above */
5242 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
5243 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005244 f_shutdown(__BFILE__, __LINE__);
5245 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005246 /* Here check for some level of fairness between them (at least ~40%): */
5247 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
5248 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
5249 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
5250 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
5251 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
5252 f_shutdown(__BFILE__, __LINE__);
5253 }
5254 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
5255 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
5256 f_shutdown(__BFILE__, __LINE__);
5257 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005258
5259 f_shutdown(__BFILE__, __LINE__, final := true);
5260}
5261
5262
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005263private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
5264 boolean exp_imsi, boolean exp_tmsi)
5265runs on RAW_PCU_Test_CT {
5266 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
5267 var integer pending := lengthof(g_ms);
5268 var RlcmacDlBlock dl_block;
5269 var boolean f1, f2;
5270
5271 while (pending > 0) {
5272 var uint32_t poll_fn;
5273
5274 /* Obtain a Downlink block and make sure it is a paging request */
5275 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
5276 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
5277 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5278 break;
5279 }
5280
5281 /* This should not happen in general, but who knows... */
5282 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
5283 if (not ispresent(req.repeated_pageinfo)) {
5284 setverdict(fail, "Repeated Page Info IE is absent?!?");
5285 break;
5286 }
5287
5288 /* A single message may contain several MIs depending on their type */
5289 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5290 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
5291 ps_domain := false);
5292 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
5293 ps_domain := false);
5294 if (not f1 and not f2)
5295 { continue; }
5296
5297 /* Detect duplicate MIs */
5298 if (mask[i] == '1'B) {
5299 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
5300 continue;
5301 }
5302
5303 mask[i] := '1'B;
5304 }
5305
5306 pending := pending - lengthof(req.repeated_pageinfo);
5307 }
5308
5309 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
5310 if (mask[i] != '1'B) {
5311 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
5312 log("===== mask := ", mask);
5313 }
5314 }
5315
5316 /* All messages must have been received by now, expect a dummy block */
5317 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
5318}
5319
5320private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
5321runs on RAW_PCU_Test_CT {
5322 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5323 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5324
5325 /* Initialize NS/BSSGP side */
5326 f_init_bssgp();
5327
5328 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005329 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005330
5331 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
5332 f_init_gprs_ms(7 * 8);
5333
5334 /* Initialize the PCU interface abstraction */
5335 f_init_raw(testcasename(), info_ind);
5336
5337 /* Establish BSSGP connection to the PCU */
5338 f_bssgp_establish();
5339 f_multi_ms_bssgp_register();
5340
5341 /* Establish an Uplink TBF for each GprsMS instance */
5342 f_multi_ms_establish_tbf(do_activate := true);
5343}
5344
5345testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
5346 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5347
5348 /* Common part: send INFO.ind, establish TBFs... */
5349 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5350
5351 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
5352 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5353 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5354 }
5355
5356 /* FIXME: work around a race condition between PCUIF and BSSGP */
5357 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5358
5359 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5360 * The IUT is expected to page on all PDCH slots of all transceivers. */
5361 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5362 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5363 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
5364 }
5365
5366 f_shutdown(__BFILE__, __LINE__, final := true);
5367}
5368
5369testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
5370 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5371
5372 /* Common part: send INFO.ind, establish TBFs... */
5373 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5374
5375 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
5376 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5377 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5378 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5379 }
5380
5381 /* FIXME: work around a race condition between PCUIF and BSSGP */
5382 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5383
5384 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5385 * The IUT is expected to page on all PDCH slots of all transceivers. */
5386 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5387 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5388 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
5389 }
5390
5391 f_shutdown(__BFILE__, __LINE__, final := true);
5392}
5393
5394testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
5395 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5396
5397 /* Common part: send INFO.ind, establish TBFs... */
5398 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5399
5400 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
5401 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5402 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5403 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
5404 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5405 } else {
5406 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5407 }
5408 }
5409
5410 /* FIXME: work around a race condition between PCUIF and BSSGP */
5411 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5412
5413 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5414 * The IUT is expected to page on all PDCH slots of all transceivers. */
5415 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5416 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5417 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
5418 }
5419
5420 f_shutdown(__BFILE__, __LINE__, final := true);
5421}
5422
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005423private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005424runs on RAW_PCU_Test_CT return RlcmacDlBlock {
5425 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005426 var integer i := 0;
5427 while (true) {
5428 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005429 if (not match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005430 break;
5431 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005432 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005433 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5434 f_shutdown(__BFILE__, __LINE__);
5435 }
5436 i := i + 1;
5437 }
5438 return dl_block;
5439}
5440
Vadim Yanitskiy03f74d42023-02-10 09:22:42 +07005441private const GsmMcc c_BssgpCellMcc := '623'H; /* MCC: Central African Republic */
5442private const GsmMnc c_BssgpCellMnc := '03'H; /* MNC: Celca (Socatel) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005443private template (value) BssgpCellId ts_BssgpCellIdDstAddr_default := {
5444 ra_id := {
5445 lai := {
5446 mcc_mnc := f_build_BcdMccMnc(c_BssgpCellMcc, c_BssgpCellMnc),
5447 lac := 423
5448 },
5449 rac := 2
5450 },
5451 cell_id := 5
5452}
5453
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005454private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
5455runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005456 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5457 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5458 var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(src_mcc_mnc, info_ind.lac), info_ind.rac),
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005459 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005460 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005461 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005462 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5463 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5464 var template (value) RAN_Information_RIM_Container res_cont :=
5465 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5466 ts_RIM_Sequence_Number(2),
5467 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5468 ts_RIM_Protocol_Version_Number(1),
5469 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
5470 omit);
5471 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5472 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5473 res_cont));
5474}
5475
5476altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
5477runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005478 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5479 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5480 var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(src_mcc_mnc, info_ind.lac), info_ind.rac),
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005481 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005482 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005483 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005484 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5485 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5486 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5487 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5488 tr_RAN_Information_Request_RIM_Container)) {
5489 if (do_answer) {
5490 f_outbound_nacc_rim_tx_resp(info_ind);
5491 }
5492 if (do_repeat) {
5493 repeat;
5494 }
5495 }
5496}
5497
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005498private function f_ctrl_rx_nacc_rac_ci_req(out CtrlMessage ctrl_req,
5499 PCUIF_info_ind info_ind,
5500 GsmArfcn req_arfcn,
5501 uint6_t req_bsic)
5502runs on RAW_PCU_Test_CT {
5503 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5504 int2str(info_ind.lac) & "." &
5505 int2str(info_ind.cell_id) & "." &
5506 int2str(req_arfcn) & "." &
5507 int2str(req_bsic);
5508 f_ipa_ctrl_wait_link_up();
5509 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value ctrl_req;
5510}
5511
5512private function f_ctrl_tx_nacc_rac_ci_rsp(in CtrlMessage ctrl_req)
5513runs on RAW_PCU_Test_CT {
5514 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5515 IPA_CTRL.send(ts_CtrlMsgGetRepl(ctrl_req.cmd.id,
5516 ctrl_req.cmd.variable,
5517 hex2str(c_BssgpCellMcc) & "-" &
5518 hex2str(c_BssgpCellMnc) & "-" &
5519 int2str(addr.ra_id.lai.lac) & "-" &
5520 int2str(addr.ra_id.rac) & "-" &
5521 int2str(addr.cell_id)));
5522}
5523
5524private function f_pcuif_rx_nacc_rac_ci_req(out PCUIF_Message addr_req,
5525 PCUIF_info_ind info_ind,
5526 GsmArfcn req_arfcn,
5527 uint6_t req_bsic)
5528runs on RAW_PCU_Test_CT {
5529 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id,
5530 req_arfcn, req_bsic)) -> value addr_req;
5531}
5532
5533private function f_pcuif_tx_nacc_rac_ci_rsp(in PCUIF_Message addr_req)
5534runs on RAW_PCU_Test_CT {
5535 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5536 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, addr_req.u.container.u.neigh_addr_req, 0,
5537 str2int(hex2str(c_BssgpCellMcc)),
5538 str2int(hex2str(c_BssgpCellMnc)),
5539 lengthof(c_BssgpCellMnc) - 2,
5540 addr.ra_id.lai.lac,
5541 addr.ra_id.rac,
5542 addr.cell_id));
5543}
5544
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005545private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
5546 boolean answer := true, boolean use_old_ctrl_iface := false)
5547runs on RAW_PCU_Test_CT {
5548 if (use_old_ctrl_iface == true) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005549 var CtrlMessage ctrl_req;
5550 f_ctrl_rx_nacc_rac_ci_req(ctrl_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005551 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005552 f_ctrl_tx_nacc_rac_ci_rsp(ctrl_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005553 }
5554 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005555 var PCUIF_Message pcuif_req;
5556 f_pcuif_rx_nacc_rac_ci_req(pcuif_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005557 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005558 f_pcuif_tx_nacc_rac_ci_rsp(pcuif_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005559 }
5560 }
5561}
5562
Philipp Maiere640d8f2023-06-30 14:43:01 +02005563private function f_outbound_nacc_success_no_si(inout GprsMS ms, PCUIF_info_ind info_ind,
5564 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5565 boolean skip_final_ctrl_ack := false,
5566 boolean use_old_ctrl_iface := false,
5567 template (value) RlcmacUlCtrlMsg cell_chg_notif)
5568runs on RAW_PCU_Test_CT {
5569 var template RlcmacDlCtrlMsg cell_chg_cont;
5570 var RlcmacDlBlock dl_block;
5571 var uint32_t sched_fn;
5572
5573 /* Start NACC from MS side */
5574 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5575
5576 /* Obtain a Downlink block and make sure it is a PacketCellChangeContine. We also make sure that this
5577 * PacketCellChangeContine message does not contain any ARFCN/BSIC. */
5578 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5579 cell_chg_cont := tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE
5580 cell_chg_cont.u.cell_chg_continue.arfcn_bsic_presence := '0'B
5581 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, cell_chg_cont))) {
5582 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5583 f_shutdown(__BFILE__, __LINE__);
5584 }
5585
5586 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5587 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
5588 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5589 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5590 }
5591}
5592
5593/* Start NACC from MS side, propose an UTRAN cell */
5594private function f_outbound_nacc_success_utran(inout GprsMS ms, PCUIF_info_ind info_ind,
5595 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5596 boolean skip_final_ctrl_ack := false,
5597 boolean use_old_ctrl_iface := false)
5598runs on RAW_PCU_Test_CT {
5599 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
5600 var uint14_t req_uarfcn := 1234;
5601 var uint10_t req_scrambling_code := 456;
5602
5603 /* Start NACC from MS side */
5604 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF_UTRAN(ms.ul_tbf.tfi, req_uarfcn, req_scrambling_code);
5605 f_outbound_nacc_success_no_si(ms, info_ind, exp_rac_ci_query, exp_si_query, skip_final_ctrl_ack, use_old_ctrl_iface, cell_chg_notif);
5606}
5607
5608/* Start NACC from MS side, propose an E-UTRAN cell */
5609private function f_outbound_nacc_success_eutran(inout GprsMS ms, PCUIF_info_ind info_ind,
5610 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5611 boolean skip_final_ctrl_ack := false,
5612 boolean use_old_ctrl_iface := false)
5613runs on RAW_PCU_Test_CT {
5614 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
5615 var uint16_t req_earfcn := 1234;
5616 var uint9_t phys_layer_cell_id := 456;
5617
5618 /* Start NACC from MS side */
5619 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF_EUTRAN(ms.ul_tbf.tfi, req_earfcn, phys_layer_cell_id);
5620 f_outbound_nacc_success_no_si(ms, info_ind, exp_rac_ci_query, exp_si_query, skip_final_ctrl_ack, use_old_ctrl_iface, cell_chg_notif);
5621}
5622
Philipp Maier58c08332023-06-30 13:26:42 +02005623/* Start NACC from MS side, propose a GERAN cell */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005624private function f_outbound_nacc_success_geran(inout GprsMS ms, PCUIF_info_ind info_ind,
5625 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5626 boolean skip_final_ctrl_ack := false,
5627 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005628runs on RAW_PCU_Test_CT {
Philipp Maier7d187ae2023-06-20 14:38:24 +02005629 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Philipp Maier58c08332023-06-30 13:26:42 +02005630 var template RlcmacDlCtrlMsg cell_chg_cont;
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005631 var RlcmacDlBlock dl_block;
5632 var uint32_t sched_fn;
5633 var GsmArfcn req_arfcn := 862;
5634 var uint6_t req_bsic := 43;
5635
5636 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005637 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5638 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005639
5640 if (exp_rac_ci_query == true) {
5641 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005642 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 +01005643 }
5644
5645 if (exp_si_query == true) {
5646 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005647 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005648 }
5649
5650 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005651 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005652
Philipp Maier58c08332023-06-30 13:26:42 +02005653 /* Obtain a Downlink block and make sure it is a PacketCellChangeContinue, also verify that
5654 * the PacketCellChangeContinue message contains the ARFCN and BSIC which was proposed in
5655 * the PacketCellChangeNotification before. */
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005656 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Philipp Maier58c08332023-06-30 13:26:42 +02005657 cell_chg_cont := tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE
5658 cell_chg_cont.u.cell_chg_continue.arfcn_bsic_presence := '1'B
5659 cell_chg_cont.u.cell_chg_continue.arfcn := req_arfcn;
5660 cell_chg_cont.u.cell_chg_continue.bsic := req_bsic;
5661 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, cell_chg_cont))) {
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005662 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5663 f_shutdown(__BFILE__, __LINE__);
5664 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005665 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005666 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005667 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5668 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5669 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005670}
5671
Philipp Maiere640d8f2023-06-30 14:43:01 +02005672type enumerated f_TC_nacc_outbound_success_ran_type {
5673 NACC_RAN_GERAN,
5674 NACC_RAN_UTRAN,
5675 NACC_RAN_EUTRAN
5676}
5677
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005678/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005679function f_TC_nacc_outbound_success(f_TC_nacc_outbound_success_ran_type ran_type) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005680 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005681 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005682 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005683 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005684
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005685 if (use_old_ctrl_iface) {
5686 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5687 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5688 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005689
5690 /* Initialize NS/BSSGP side */
5691 f_init_bssgp();
5692 /* Initialize GPRS MS side */
5693 f_init_gprs_ms();
5694 ms := g_ms[0]; /* We only use first MS in this test */
5695
5696 /* Initialize the PCU interface abstraction */
5697 f_init_raw(testcasename(), info_ind);
5698
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005699 /* Make sure we are not affected by full cache from previous tests */
5700 f_pcuvty_flush_neigh_caches();
5701
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005702 /* Establish BSSGP connection to the PCU */
5703 f_bssgp_establish();
5704 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5705
5706 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005707 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 +01005708 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5709 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5710
5711 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005712 if (ran_type == NACC_RAN_GERAN) {
5713 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5714 } else if (ran_type == NACC_RAN_UTRAN) {
5715 f_outbound_nacc_success_utran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5716 } else if (ran_type == NACC_RAN_EUTRAN) {
5717 f_outbound_nacc_success_eutran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5718 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005719
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005720 f_shutdown(__BFILE__, __LINE__, final := true);
5721}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005722
Philipp Maiere640d8f2023-06-30 14:43:01 +02005723testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
5724 f_TC_nacc_outbound_success(NACC_RAN_GERAN);
5725}
5726
5727testcase TC_nacc_outbound_success_utran() runs on RAW_PCU_Test_CT {
5728 f_TC_nacc_outbound_success(NACC_RAN_UTRAN);
5729}
5730
5731testcase TC_nacc_outbound_success_eutran() runs on RAW_PCU_Test_CT {
5732 f_TC_nacc_outbound_success(NACC_RAN_EUTRAN);
5733}
5734
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005735/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5736testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5737 var PollFnCtx pollctx;
5738 var GprsMS ms;
5739 var RlcmacDlBlock dl_block;
5740 var uint32_t sched_fn;
5741 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005742 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005743
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005744 if (use_old_ctrl_iface) {
5745 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5746 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5747 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005748
5749 /* Initialize NS/BSSGP side */
5750 f_init_bssgp();
5751 /* Initialize GPRS MS side */
5752 f_init_gprs_ms();
5753 ms := g_ms[0]; /* We only use first MS in this test */
5754
5755 /* Initialize the PCU interface abstraction */
5756 f_init_raw(testcasename(), info_ind);
5757
5758 /* Make sure we are not affected by full cache from previous tests */
5759 f_pcuvty_flush_neigh_caches();
5760
5761 /* Establish BSSGP connection to the PCU */
5762 f_bssgp_establish();
5763 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5764
5765 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005766 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 +01005767 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5768 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5769
5770 /* Start NACC from MS side, avoid sending final CTRL ACK */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005771 f_outbound_nacc_success_geran(ms, info_ind, skip_final_ctrl_ack := true,
5772 use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005773
5774 /* Wait until we receive something non-dummy */
5775 dl_block := f_skip_dummy(0, sched_fn);
5776 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5777 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5778 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5779 }
5780 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5781 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5782 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5783 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5784 }
5785
5786 f_shutdown(__BFILE__, __LINE__, final := true);
5787}
5788
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005789/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5790testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5791 var PollFnCtx pollctx;
5792 var GprsMS ms;
5793 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02005794 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005795 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005796
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005797 if (use_old_ctrl_iface) {
5798 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5799 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5800 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005801
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005802 /* Initialize NS/BSSGP side */
5803 f_init_bssgp();
5804 /* Initialize GPRS MS side */
5805 f_init_gprs_ms();
5806 ms := g_ms[0]; /* We only use first MS in this test */
5807
5808 /* Initialize the PCU interface abstraction */
5809 f_init_raw(testcasename(), info_ind);
5810
5811 /* Make sure we are not affected by full cache from previous tests */
5812 f_pcuvty_flush_neigh_caches();
5813 /* Set timeout values for caches so that entries will be in cache during second try */
5814 f_pcuvty_set_neigh_caches(10, 10);
5815
5816 /* Establish BSSGP connection to the PCU */
5817 f_bssgp_establish();
5818 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5819
5820 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005821 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 +01005822 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5823 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5824
5825 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005826 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005827
5828 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005829 f_outbound_nacc_success_geran(ms, info_ind, false, false, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005830
5831 f_shutdown(__BFILE__, __LINE__, final := true);
5832}
5833
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005834/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5835 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5836 */
5837testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5838 var PollFnCtx pollctx;
5839 var GprsMS ms;
5840 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02005841 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005842 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005843
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005844 if (use_old_ctrl_iface) {
5845 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5846 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5847 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005848
5849 /* Initialize NS/BSSGP side */
5850 f_init_bssgp();
5851 /* Initialize GPRS MS side */
5852 f_init_gprs_ms();
5853 ms := g_ms[0]; /* We only use first MS in this test */
5854
5855 /* Initialize the PCU interface abstraction */
5856 f_init_raw(testcasename(), info_ind);
5857
5858 /* Make sure we are not affected by full cache from previous tests */
5859 f_pcuvty_flush_neigh_caches();
5860 /* Set timeout values for caches so that entries will be erased before the second try */
5861 f_pcuvty_set_neigh_caches(1, 1);
5862
5863 /* Establish BSSGP connection to the PCU */
5864 f_bssgp_establish();
5865 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5866
5867 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005868 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 +01005869 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5870 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5871
5872 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005873 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005874
5875 /* CTRL client should have disconnected from us */
5876 f_ipa_ctrl_wait_link_down();
5877 /* wait for cache entries to time out */
5878 f_sleep(2.0);
5879 /* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005880 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005881
5882 f_shutdown(__BFILE__, __LINE__, final := true);
5883}
5884
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005885/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005886testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5887 var RlcmacDlBlock dl_block;
5888 var PollFnCtx pollctx;
5889 var uint32_t sched_fn;
5890 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02005891 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005892 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005893 var GsmArfcn req_arfcn := 862;
5894 var uint6_t req_bsic := 43;
5895
5896 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5897 * resolution CTRL port, to trigger Conn Refused by socket:
5898 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5899 */
5900
5901 /* Initialize NS/BSSGP side */
5902 f_init_bssgp();
5903 /* Initialize GPRS MS side */
5904 f_init_gprs_ms();
5905 ms := g_ms[0]; /* We only use first MS in this test */
5906
5907 /* Initialize the PCU interface abstraction */
5908 f_init_raw(testcasename(), info_ind);
5909
5910 /* Make sure we are not affected by full cache from previous tests */
5911 f_pcuvty_flush_neigh_caches();
5912
5913 /* Establish BSSGP connection to the PCU */
5914 f_bssgp_establish();
5915 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5916
5917 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005918 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 +01005919 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5920 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5921
5922 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005923 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5924 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005925
5926 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005927 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005928 /* Make sure it is a Pkt Cell Chg Continue */
5929 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5930 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5931 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005932 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5933 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5934 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5935 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5936 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005937
5938 f_shutdown(__BFILE__, __LINE__, final := true);
5939}
5940
5941/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005942testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5943 var RlcmacDlBlock dl_block;
5944 var PollFnCtx pollctx;
5945 var uint32_t sched_fn;
5946 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02005947 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005948 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005949 var GsmArfcn req_arfcn := 862;
5950 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005951 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005952
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005953 if (use_old_ctrl_iface) {
5954 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5955 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5956 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005957
5958 /* Initialize NS/BSSGP side */
5959 f_init_bssgp();
5960 /* Initialize GPRS MS side */
5961 f_init_gprs_ms();
5962 ms := g_ms[0]; /* We only use first MS in this test */
5963
5964 /* Initialize the PCU interface abstraction */
5965 f_init_raw(testcasename(), info_ind);
5966
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005967 /* Make sure we are not affected by full cache from previous tests */
5968 f_pcuvty_flush_neigh_caches();
5969
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005970 /* Establish BSSGP connection to the PCU */
5971 f_bssgp_establish();
5972 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5973
5974 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005975 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 +01005976 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5977 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5978
5979 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005980 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5981 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005982
5983 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005984 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005985 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 +01005986
5987 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005988 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005989 /* Make sure it is a Pkt Cell Chg Continue */
5990 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5991 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5992 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005993 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5994 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5995 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5996 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5997 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005998
5999 f_shutdown(__BFILE__, __LINE__, final := true);
6000}
6001
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006002/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
6003testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
6004 var RlcmacDlBlock dl_block;
6005 var PollFnCtx pollctx;
6006 var uint32_t sched_fn;
6007 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02006008 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006009 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006010 var GsmArfcn req_arfcn := 862;
6011 var uint6_t req_bsic := 43;
6012
6013 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6014 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6015
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
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006025 /* Make sure we are not affected by full cache from previous tests */
6026 f_pcuvty_flush_neigh_caches();
6027
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006028 /* 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 */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01006033 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 +01006034 /* 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 */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006038 cell_chg_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_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006040
6041 /* osmo-pcu should now ask for resolution: */
6042 f_ipa_ctrl_wait_link_up();
6043 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
6044 int2str(info_ind.lac) & "." &
6045 int2str(info_ind.cell_id) & "." &
6046 int2str(req_arfcn) & "." &
6047 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006048 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006049 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
6050
6051 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006052 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006053 /* Make sure it is a Pkt Cell Chg Continue */
6054 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6055 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6056 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006057 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6058 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6059 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6060 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6061 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006062
6063 f_shutdown(__BFILE__, __LINE__, final := true);
6064}
6065
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006066/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
6067testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
6068 var RlcmacDlBlock dl_block;
6069 var PollFnCtx pollctx;
6070 var uint32_t sched_fn;
6071 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02006072 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006073 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006074 var GsmArfcn req_arfcn := 862;
6075 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006076 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006077
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006078 if (use_old_ctrl_iface) {
6079 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6080 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6081 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006082
6083 /* Initialize NS/BSSGP side */
6084 f_init_bssgp();
6085 /* Initialize GPRS MS side */
6086 f_init_gprs_ms();
6087 ms := g_ms[0]; /* We only use first MS in this test */
6088
6089 /* Initialize the PCU interface abstraction */
6090 f_init_raw(testcasename(), info_ind);
6091
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006092 /* Make sure we are not affected by full cache from previous tests */
6093 f_pcuvty_flush_neigh_caches();
6094
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006095 /* Establish BSSGP connection to the PCU */
6096 f_bssgp_establish();
6097 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6098
6099 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01006100 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 +01006101 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6102 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6103
6104 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006105 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6106 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006107
6108 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006109 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 +01006110
6111 /* RIM procedure: */
Vadim Yanitskiyd8aa5e82023-02-12 17:11:42 +07006112 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006113 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
6114
6115 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006116 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006117 /* Make sure it is a Pkt Cell Chg Continue */
6118 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6119 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6120 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006121 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6122 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6123 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6124 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6125 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006126
6127 f_shutdown(__BFILE__, __LINE__, final := true);
6128}
6129
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006130/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
6131testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
6132 var PollFnCtx pollctx;
6133 var GprsMS ms;
6134 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006135 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006136 var RlcmacDlBlock dl_block;
6137 var uint32_t sched_fn;
6138 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006139 var charstring ctrl_var;
6140 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006141 var GsmArfcn req_arfcn := 862;
6142 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006143 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006144
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006145 if (use_old_ctrl_iface) {
6146 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6147 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6148 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006149
6150 /* Initialize NS/BSSGP side */
6151 f_init_bssgp();
6152 /* Initialize GPRS MS side */
6153 f_init_gprs_ms();
6154 ms := g_ms[0]; /* We only use first MS in this test */
6155
6156 /* Initialize the PCU interface abstraction */
6157 f_init_raw(testcasename(), info_ind);
6158
6159 /* Make sure we are not affected by full cache from previous tests */
6160 f_pcuvty_flush_neigh_caches();
6161
6162 /* Establish BSSGP connection to the PCU */
6163 f_bssgp_establish();
6164 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6165
6166 /* Send PACKET RESOURCE REQUEST */
6167 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6168 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6169 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6170
6171 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006172 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6173 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006174
6175 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006176 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006177 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006178 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006179 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006180 }
6181
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006182 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006183 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006184 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006185
6186 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006187 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006188 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006189 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006190 }
6191
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006192 timer T := 2.0;
6193 T.start;
6194 alt {
6195 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006196 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006197 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
6198 f_shutdown(__BFILE__, __LINE__);
6199 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006200 [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 {
6201 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
6202 f_shutdown(__BFILE__, __LINE__);
6203 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006204 [] T.timeout {
6205 setverdict(pass);
6206 }
6207 }
6208
6209 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006210 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006211
6212 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6213 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6214 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6215 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6216 f_shutdown(__BFILE__, __LINE__);
6217 }
6218 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6219 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6220 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6221 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6222 }
6223
6224 f_shutdown(__BFILE__, __LINE__, final := true);
6225}
6226
6227/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
6228testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
6229 var PollFnCtx pollctx;
6230 var GprsMS ms;
6231 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006232 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006233 var RlcmacDlBlock dl_block;
6234 var uint32_t sched_fn;
6235 var CtrlMessage rx_ctrl;
6236 var GsmArfcn req_arfcn := 862;
6237 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006238 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006239
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006240 if (use_old_ctrl_iface) {
6241 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6242 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6243 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006244
6245 /* Initialize NS/BSSGP side */
6246 f_init_bssgp();
6247 /* Initialize GPRS MS side */
6248 f_init_gprs_ms();
6249 ms := g_ms[0]; /* We only use first MS in this test */
6250
6251 /* Initialize the PCU interface abstraction */
6252 f_init_raw(testcasename(), info_ind);
6253
6254 /* Make sure we are not affected by full cache from previous tests */
6255 f_pcuvty_flush_neigh_caches();
6256
6257 /* Establish BSSGP connection to the PCU */
6258 f_bssgp_establish();
6259 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6260
6261 /* Send PACKET RESOURCE REQUEST */
6262 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6263 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6264 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6265
6266 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006267 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6268 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006269
6270 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006271 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 +01006272 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6273 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006274 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006275 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6276 f_outbound_nacc_rim_tx_resp(info_ind);
6277 timer T := 1.0;
6278 T.start;
6279 alt {
6280 [] RIM.receive {
6281 setverdict(fail, "Received unexpected RIM message");
6282 f_shutdown(__BFILE__, __LINE__);
6283 }
6284 [] T.timeout {
6285 setverdict(pass);
6286 }
6287 }
6288
6289 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006290 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006291
6292 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6293 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6294 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6295 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6296 f_shutdown(__BFILE__, __LINE__);
6297 }
6298 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6299 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6300 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6301 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6302 }
6303
6304 f_shutdown(__BFILE__, __LINE__, final := true);
6305}
6306
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006307/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
6308testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
6309 var PollFnCtx pollctx;
6310 var GprsMS ms;
6311 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006312 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006313 var RlcmacDlBlock dl_block;
6314 var uint32_t sched_fn;
6315 var CtrlMessage rx_ctrl;
6316 var GsmArfcn req_arfcn := 862;
6317 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006318 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006319
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006320 if (use_old_ctrl_iface) {
6321 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6322 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6323 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006324
6325 /* Initialize NS/BSSGP side */
6326 f_init_bssgp();
6327 /* Initialize GPRS MS side */
6328 f_init_gprs_ms();
6329 ms := g_ms[0]; /* We only use first MS in this test */
6330
6331 /* Initialize the PCU interface abstraction */
6332 f_init_raw(testcasename(), info_ind);
6333
6334 /* Make sure we are not affected by full cache from previous tests */
6335 f_pcuvty_flush_neigh_caches();
6336
6337 /* Establish BSSGP connection to the PCU */
6338 f_bssgp_establish();
6339 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6340
6341 /* Send PACKET RESOURCE REQUEST */
6342 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6343 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6344 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6345
6346 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006347 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6348 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006349
6350 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006351 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 +01006352 /* RIM procedure: */
6353 as_outbound_nacc_rim_resolve(info_ind);
6354
6355 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
6356 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006357 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006358
6359 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
6360 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6361
6362 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6363 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6364 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6365 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6366 f_shutdown(__BFILE__, __LINE__);
6367 }
6368 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6369 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6370 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6371 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6372 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006373
6374 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006375}
6376
6377/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
6378testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
6379 var PollFnCtx pollctx;
6380 var GprsMS ms;
6381 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006382 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006383 var RlcmacDlBlock dl_block;
6384 var uint32_t sched_fn;
6385 var CtrlMessage rx_ctrl;
6386 var GsmArfcn req_arfcn := 862;
6387 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006388 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006389
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006390 if (use_old_ctrl_iface) {
6391 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6392 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6393 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006394
6395 /* Initialize NS/BSSGP side */
6396 f_init_bssgp();
6397 /* Initialize GPRS MS side */
6398 f_init_gprs_ms();
6399 ms := g_ms[0]; /* We only use first MS in this test */
6400
6401 /* Initialize the PCU interface abstraction */
6402 f_init_raw(testcasename(), info_ind);
6403
6404 /* Make sure we are not affected by full cache from previous tests */
6405 f_pcuvty_flush_neigh_caches();
6406
6407 /* Establish BSSGP connection to the PCU */
6408 f_bssgp_establish();
6409 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6410
6411 /* Send PACKET RESOURCE REQUEST */
6412 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6413 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6414 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6415
6416 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006417 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6418 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006419
6420 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006421 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 +01006422 /* RIM procedure: */
6423 as_outbound_nacc_rim_resolve(info_ind);
6424
6425 /* Announce SI back to MS, continue NACC procedure */
6426 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6427
6428 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006429 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006430
6431 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6432 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6433 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6434 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6435 f_shutdown(__BFILE__, __LINE__);
6436 }
6437 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6438 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6439 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6440 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6441 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006442
6443 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006444}
6445
6446/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
6447testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
6448 var PollFnCtx pollctx;
6449 var GprsMS ms;
6450 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006451 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006452 var RlcmacDlBlock dl_block;
6453 var uint32_t sched_fn;
6454 var CtrlMessage rx_ctrl;
6455 var GsmArfcn req_arfcn := 862;
6456 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006457 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006458
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006459 if (use_old_ctrl_iface) {
6460 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6461 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6462 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006463
6464 /* Initialize NS/BSSGP side */
6465 f_init_bssgp();
6466 /* Initialize GPRS MS side */
6467 f_init_gprs_ms();
6468 ms := g_ms[0]; /* We only use first MS in this test */
6469
6470 /* Initialize the PCU interface abstraction */
6471 f_init_raw(testcasename(), info_ind);
6472
6473 /* Make sure we are not affected by full cache from previous tests */
6474 f_pcuvty_flush_neigh_caches();
6475
6476 /* Establish BSSGP connection to the PCU */
6477 f_bssgp_establish();
6478 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6479
6480 /* Send PACKET RESOURCE REQUEST */
6481 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6482 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6483 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6484
6485 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006486 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6487 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006488
6489 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006490 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 +01006491 /* RIM procedure: */
6492 as_outbound_nacc_rim_resolve(info_ind);
6493
6494 /* Announce SI back to MS, continue NACC procedure */
6495 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6496
6497 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6498 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6499 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6500 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6501 f_shutdown(__BFILE__, __LINE__);
6502 }
6503 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006504 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006505
6506 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6507 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6508 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6509 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6510 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006511
6512 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006513}
6514
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006515/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6516 * while waiting for CTRL resolution */
6517testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
6518 var PollFnCtx pollctx;
6519 var GprsMS ms;
6520 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006521 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006522 var RlcmacDlBlock dl_block;
6523 var uint32_t sched_fn;
6524 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006525 var charstring ctrl_var;
6526 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006527 var GsmArfcn req_arfcn := 862;
6528 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006529 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006530
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006531 if (use_old_ctrl_iface) {
6532 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6533 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6534 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006535
6536 /* Initialize NS/BSSGP side */
6537 f_init_bssgp();
6538 /* Initialize GPRS MS side */
6539 f_init_gprs_ms();
6540 ms := g_ms[0]; /* We only use first MS in this test */
6541
6542 /* Initialize the PCU interface abstraction */
6543 f_init_raw(testcasename(), info_ind);
6544
6545 /* Make sure we are not affected by full cache from previous tests */
6546 f_pcuvty_flush_neigh_caches();
6547
6548 /* Establish BSSGP connection to the PCU */
6549 f_bssgp_establish();
6550 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6551
6552 /* Send PACKET RESOURCE REQUEST */
6553 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6554 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6555 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6556
6557 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006558 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6559 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006560
6561 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006562 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006563 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006564 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006565 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006566 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006567 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006568 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6569 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006570 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006571 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006572 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006573 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006574 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006575 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006576 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006577 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 +01006578
6579 /* And finally everything continues as usual with RIN procedure */
6580 as_outbound_nacc_rim_resolve(info_ind);
6581
6582 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006583 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006584
6585 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6586 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6587 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6588 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6589 f_shutdown(__BFILE__, __LINE__);
6590 }
6591 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6592 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6593 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6594 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6595 }
6596
6597 f_shutdown(__BFILE__, __LINE__, final := true);
6598}
6599
6600/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6601 * while waiting for SI resolution */
6602testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
6603 var PollFnCtx pollctx;
6604 var GprsMS ms;
6605 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006606 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006607 var RlcmacDlBlock dl_block;
6608 var uint32_t sched_fn;
6609 var CtrlMessage rx_ctrl;
6610 var GsmArfcn req_arfcn := 862;
6611 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006612 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006613
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006614 if (use_old_ctrl_iface) {
6615 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6616 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6617 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006618
6619 /* Initialize NS/BSSGP side */
6620 f_init_bssgp();
6621 /* Initialize GPRS MS side */
6622 f_init_gprs_ms();
6623 ms := g_ms[0]; /* We only use first MS in this test */
6624
6625 /* Initialize the PCU interface abstraction */
6626 f_init_raw(testcasename(), info_ind);
6627
6628 /* Make sure we are not affected by full cache from previous tests */
6629 f_pcuvty_flush_neigh_caches();
6630
6631 /* Establish BSSGP connection to the PCU */
6632 f_bssgp_establish();
6633 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6634
6635 /* Send PACKET RESOURCE REQUEST */
6636 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6637 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6638 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6639
6640 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006641 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6642 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006643
6644 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006645 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 +01006646 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6647 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006648 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6649 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006650 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6651 f_outbound_nacc_rim_tx_resp(info_ind);
6652
6653 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006654 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 +01006655
6656 /* And finally everything continues as usual with RIN procedure */
6657 as_outbound_nacc_rim_resolve(info_ind);
6658
6659 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006660 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006661
6662 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6663 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6664 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6665 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6666 f_shutdown(__BFILE__, __LINE__);
6667 }
6668 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6669 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6670 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6671 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6672 }
6673
6674 f_shutdown(__BFILE__, __LINE__, final := true);
6675}
6676
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006677/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6678 * while sending Pkt Neigh Data Change */
6679testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6680 var PollFnCtx pollctx;
6681 var GprsMS ms;
6682 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006683 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006684 var RlcmacDlBlock dl_block;
6685 var uint32_t sched_fn;
6686 var CtrlMessage rx_ctrl;
6687 var GsmArfcn req_arfcn := 862;
6688 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006689 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006690
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006691 if (use_old_ctrl_iface) {
6692 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6693 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6694 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006695
6696 /* Initialize NS/BSSGP side */
6697 f_init_bssgp();
6698 /* Initialize GPRS MS side */
6699 f_init_gprs_ms();
6700 ms := g_ms[0]; /* We only use first MS in this test */
6701
6702 /* Initialize the PCU interface abstraction */
6703 f_init_raw(testcasename(), info_ind);
6704
6705 /* Make sure we are not affected by full cache from previous tests */
6706 f_pcuvty_flush_neigh_caches();
6707
6708 /* Establish BSSGP connection to the PCU */
6709 f_bssgp_establish();
6710 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6711
6712 /* Send PACKET RESOURCE REQUEST */
6713 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6714 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6715 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6716
6717 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006718 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6719 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006720
6721 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006722 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 +01006723 /* RIM procedure: */
6724 as_outbound_nacc_rim_resolve(info_ind);
6725
6726 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6727 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006728 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6729 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006730
6731 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006732 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 +01006733 /* RIM procedure: */
6734 as_outbound_nacc_rim_resolve(info_ind);
6735 /* Transmit SI back to MS */
6736 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6737
6738 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6739 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6740 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6741 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6742 f_shutdown(__BFILE__, __LINE__);
6743 }
6744 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6745 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6746 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6747 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6748 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006749
6750 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006751}
6752
6753/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6754testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6755 var PollFnCtx pollctx;
6756 var GprsMS ms;
6757 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006758 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006759 var RlcmacDlBlock dl_block;
6760 var uint32_t sched_fn;
6761 var CtrlMessage rx_ctrl;
6762 var GsmArfcn req_arfcn := 862;
6763 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006764 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006765
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006766 if (use_old_ctrl_iface) {
6767 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6768 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6769 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006770
6771 /* Initialize NS/BSSGP side */
6772 f_init_bssgp();
6773 /* Initialize GPRS MS side */
6774 f_init_gprs_ms();
6775 ms := g_ms[0]; /* We only use first MS in this test */
6776
6777 /* Initialize the PCU interface abstraction */
6778 f_init_raw(testcasename(), info_ind);
6779
6780 /* Make sure we are not affected by full cache from previous tests */
6781 f_pcuvty_flush_neigh_caches();
6782
6783 /* Establish BSSGP connection to the PCU */
6784 f_bssgp_establish();
6785 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6786
6787 /* Send PACKET RESOURCE REQUEST */
6788 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6789 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6790 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6791
6792 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006793 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6794 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006795
6796 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006797 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 +01006798 /* RIM procedure: */
6799 as_outbound_nacc_rim_resolve(info_ind);
6800
6801 /* Announce SI back to MS, continue NACC procedure */
6802 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6803
6804 /* trigger a Pkt Cell Change Notif with different tgt cell */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006805 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6806 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006807
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006808 /* It should trigger RAC_CI resolution to start again: */
6809 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6810
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006811 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6812 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6813
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006814 /* RIM procedure: */
6815 as_outbound_nacc_rim_resolve(info_ind);
6816 /* Transmit SI back to MS */
6817 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6818
6819 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6820 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6821 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6822 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6823 f_shutdown(__BFILE__, __LINE__);
6824 }
6825 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6826 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6827 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6828 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6829 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006830
6831 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006832}
6833
6834/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6835testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6836 var PollFnCtx pollctx;
6837 var GprsMS ms;
6838 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006839 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006840 var RlcmacDlBlock dl_block;
6841 var uint32_t sched_fn;
6842 var CtrlMessage rx_ctrl;
6843 var GsmArfcn req_arfcn := 862;
6844 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006845 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006846
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006847 if (use_old_ctrl_iface) {
6848 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6849 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6850 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006851
6852 /* Initialize NS/BSSGP side */
6853 f_init_bssgp();
6854 /* Initialize GPRS MS side */
6855 f_init_gprs_ms();
6856 ms := g_ms[0]; /* We only use first MS in this test */
6857
6858 /* Initialize the PCU interface abstraction */
6859 f_init_raw(testcasename(), info_ind);
6860
6861 /* Make sure we are not affected by full cache from previous tests */
6862 f_pcuvty_flush_neigh_caches();
6863
6864 /* Establish BSSGP connection to the PCU */
6865 f_bssgp_establish();
6866 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6867
6868 /* Send PACKET RESOURCE REQUEST */
6869 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6870 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6871 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6872
6873 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006874 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6875 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006876
6877 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006878 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 +01006879 /* RIM procedure: */
6880 as_outbound_nacc_rim_resolve(info_ind);
6881
6882 /* Announce SI back to MS, continue NACC procedure */
6883 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6884
6885 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6886 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6887 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6888 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6889 f_shutdown(__BFILE__, __LINE__);
6890 }
6891
6892 /* trigger a Pkt Cell Change Notif with different tgt cell */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006893 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6894 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006895
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006896 /* It should trigger RAC_CI resolution to start again: */
6897 /* When using new PCUIF interface for resolution, we must
6898 * PCUIF.receive() here since that's the first message in the PCUIF
6899 * queue that PCU will have sent. Calling other functions doing
6900 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6901 * due to unexpected message receive. */
6902 if (not use_old_ctrl_iface) {
6903 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6904 }
6905
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006906 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6907 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6908 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6909 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6910 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006911
6912 /* When using CTRL interface, we must schedule the ACK before (see
6913 * above) blocking here waiting for the resoltion, otherwise we'll be
6914 * too late scheduling by the time the resolution is done. */
6915 if (use_old_ctrl_iface) {
6916 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6917 }
6918
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006919 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6920 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6921
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006922 /* RIM procedure: */
6923 as_outbound_nacc_rim_resolve(info_ind);
6924 /* Transmit SI back to MS */
6925 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6926
6927 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6928 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6929 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6930 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6931 f_shutdown(__BFILE__, __LINE__);
6932 }
6933 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6934 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6935 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6936 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6937 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006938
6939 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006940}
6941
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006942/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6943testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6944 var PollFnCtx pollctx;
6945 var GprsMS ms;
6946 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006947 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006948 var RlcmacDlBlock dl_block;
6949 var uint32_t sched_fn, dl_fn;
6950 var CtrlMessage rx_ctrl;
6951 var GsmArfcn req_arfcn := 862;
6952 var uint6_t req_bsic := 43;
6953 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006954 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006955
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006956 if (use_old_ctrl_iface) {
6957 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6958 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6959 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006960
6961 /* Initialize NS/BSSGP side */
6962 f_init_bssgp();
6963 /* Initialize GPRS MS side */
6964 f_init_gprs_ms();
6965 ms := g_ms[0]; /* We only use first MS in this test */
6966
6967 /* Initialize the PCU interface abstraction */
6968 f_init_raw(testcasename(), info_ind);
6969
6970 /* Make sure we are not affected by full cache from previous tests */
6971 f_pcuvty_flush_neigh_caches();
6972
6973 /* Establish BSSGP connection to the PCU */
6974 f_bssgp_establish();
6975 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6976
6977 /* Send PACKET RESOURCE REQUEST */
6978 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6979 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6980 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6981
6982 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006983 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6984 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006985
6986 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006987 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 +01006988 /* RIM procedure: */
6989 as_outbound_nacc_rim_resolve(info_ind);
6990
6991 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6992 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6993 f_sleep(0.1);
6994 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6995 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6996
6997 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6998 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6999 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
7000 * Data with unassigned DL TBF in line above): */
7001 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
7002 /* Continue receiving Pkt Cell Neighbor Data */
7003 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
7004
7005 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
7006 f_rx_rlcmac_dl_block(dl_block, sched_fn);
7007 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
7008 setverdict(fail, "Rx unexpected DL block: ", dl_block);
7009 f_shutdown(__BFILE__, __LINE__);
7010 }
7011 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
7012 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
7013 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
7014 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
7015 }
7016
7017 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
7018 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
7019 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
7020 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
7021 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02007022
7023 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007024}
7025
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007026
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007027function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
7028runs on RAW_PCU_Test_CT
7029{
7030 var template (value) RAN_Information_Request_RIM_Container req_cont;
7031 var template (value) PDU_BSSGP bssgp_rim_pdu;
7032 var template PDU_BSSGP bssgp_rim_pdu_expect;
7033 var template RAN_Information_RIM_Container rim_cont_expect;
7034 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007035
7036 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007037 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 +01007038 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007039 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 +01007040 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02007041 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);
7042 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007043 f_sleep(1.0);
7044
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007045 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007046
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007047 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
7048 ts_RIM_Sequence_Number(1),
7049 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7050 ts_RIM_Protocol_Version_Number(1),
7051 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
7052 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007053 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
7054 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007055
7056 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
7057 tr_RIM_Sequence_Number(1),
7058 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7059 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007060 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 +01007061 omit);
7062
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007063 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
7064 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007065 rim_cont_expect);
7066 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007067 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007068 T.start;
7069 alt {
7070 [] RIM.receive(bssgp_rim_pdu_expect) { }
7071 [] RIM.receive {
7072 setverdict(fail, "Unexpected BSSGP RIM PDU received");
7073 }
7074 [] T.timeout {
7075 setverdict(fail, "No BSSGP RIM PDU received");
7076 mtc.stop;
7077 }
7078 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007079}
7080/* Send a RIM RAN info request to the PCU and verify the response, we expect
7081 * getting the system information back which we have transfered to the PCU via
7082 * PCUIF on startup. */
7083testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
7084 /* Initialize NS/BSSGP side */
7085 f_init_bssgp();
7086
7087 /* Initialize the PCU interface abstraction */
7088 f_init_raw(testcasename());
7089
7090 /* Establish BSSGP connection to the PCU */
7091 f_bssgp_establish();
7092
7093 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
7094 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
7095
7096 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7097 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
7098
7099 f_shutdown(__BFILE__, __LINE__, final := true);
7100}
7101
7102/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
7103 * Routing information, to verify PCU handles that kind of address just fine
7104 */
7105testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
7106 /* Initialize NS/BSSGP side */
7107 f_init_bssgp();
7108
7109 /* Initialize the PCU interface abstraction */
7110 f_init_raw(testcasename());
7111
7112 /* Establish BSSGP connection to the PCU */
7113 f_bssgp_establish();
7114
7115 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
7116 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
7117
7118 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
7119 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007120
7121 f_shutdown(__BFILE__, __LINE__, final := true);
7122}
7123
7124/* Same as above, but in this case we simulate the rare case in which the PCU
7125 * has no system information available. We expect getting a response back but
7126 * with no system information inside. */
7127testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01007128 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007129 var PCUIF_Message pcu_msg;
7130 timer T := 2.0;
7131
7132 /* Initialize NS/BSSGP side */
7133 f_init_bssgp();
7134
7135 /* Initialize the PCU interface abstraction */
7136 f_init_raw(testcasename(), info_ind);
7137
7138 /* Establish BSSGP connection to the PCU */
7139 f_bssgp_establish();
7140
7141 /* Clear sysinfo from the PCU */
7142 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);
7143 BTS.send(si1_data_ind);
7144 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);
7145 BTS.send(si3_data_ind);
7146 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);
7147 BTS.send(si16_data_ind);
7148 f_sleep(1.0);
7149
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01007150 var RIM_Routing_Address dst_addr;
7151 var RIM_Routing_Address src_addr;
7152 var template (value) RAN_Information_Request_RIM_Container req_cont;
7153 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007154 var template PDU_BSSGP bssgp_rim_pdu_expect;
7155 var template RAN_Information_RIM_Container rim_cont_expect;
7156
7157 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 +01007158 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
7159 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007160
7161 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
7162 ts_RIM_Sequence_Number(1),
7163 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7164 ts_RIM_Protocol_Version_Number(1),
7165 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
7166 omit);
7167 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
7168 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7169 req_cont);
7170
7171
7172 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
7173 tr_RIM_Sequence_Number(1),
7174 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7175 tr_RIM_Protocol_Version_Number(1),
7176 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
7177 omit);
7178
7179 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7180 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
7181 rim_cont_expect);
7182 RIM.send(bssgp_rim_pdu);
7183 T.start;
7184 alt {
7185 [] RIM.receive(bssgp_rim_pdu_expect) { }
7186 [] RIM.receive {
7187 setverdict(fail, "Unexpected BSSGP RIM PDU received");
7188 }
7189 [] T.timeout {
7190 setverdict(fail, "No BSSGP RIM PDU received");
7191 mtc.stop;
7192 }
7193 }
7194
7195 f_shutdown(__BFILE__, __LINE__, final := true);
7196}
7197
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007198/* 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 +02007199testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
7200 var PCUIF_info_ind info_ind;
7201 var template (value) TsTrxBtsNum nr;
7202 var RlcmacDlBlock dl_block;
7203 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007204 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007205 timer T;
7206
7207 /* Initialize NS/BSSGP side */
7208 f_init_bssgp();
7209
7210 info_ind := valueof(ts_PCUIF_INFO_default);
7211 /* The 2 first TRX are enabled. */
7212 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
7213 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7214 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
7215
7216 /* Initialize the PCU interface abstraction */
7217 f_init_raw(testcasename(), info_ind);
7218
7219 /* Establish BSSGP connection to the PCU */
7220 f_bssgp_establish();
7221
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007222 for (ts := 0; ts < 2; ts := ts + 1) {
7223 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007224
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007225 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
7226 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
7227 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
7228 T.start(0.5);
7229 alt {
7230 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
7231 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
7232 omit)) -> value data_msg {
7233 setverdict(pass);
7234 T.stop;
7235 }
7236 [] as_rx_fail_dummy(nr);
7237 [] BTS.receive {
7238 setverdict(fail, "Unexpected block from BTS");
7239 f_shutdown(__BFILE__, __LINE__);
7240 }
7241 [] T.timeout {
7242 setverdict(fail, "Expected IDLE block from BTS");
7243 f_shutdown(__BFILE__, __LINE__);
7244 }
7245 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007246 }
7247
7248 f_shutdown(__BFILE__, __LINE__, final := true);
7249}
7250
Oliver Smith3d174882021-09-03 11:38:51 +02007251/* Test stats for available and occupied PDCHs */
7252testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
7253 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
7254 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
7255
7256 /* Initialize NS/BSSGP side */
7257 f_init_bssgp();
7258
Oliver Smithedcded22021-09-14 09:26:55 +02007259 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
7260 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
7261 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
7262 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
7263 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
7264 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02007265
Oliver Smith72d0c692021-09-08 10:03:52 +02007266 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02007267 f_init_gprs_ms(4);
7268
7269 /* Initialize the PCU interface abstraction */
7270 f_init_raw(testcasename(), info_ind);
7271
7272 /* Reset stats */
7273 f_statsd_reset();
7274
7275 /* Establish BSSGP */
7276 f_bssgp_establish();
7277
7278 /* 8 PDCHs available, 0 occupied */
7279 var StatsDExpects expect := {
7280 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007281 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
7282 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7283 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02007284 };
7285 f_statsd_expect(expect);
7286
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007287 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02007288 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007289 f_ms_establish_ul_tbf(g_ms[0]);
7290 f_ms_establish_ul_tbf(g_ms[1]);
7291 f_ms_establish_ul_tbf(g_ms[2]);
7292 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 +02007293
7294 /* 4 PDCHs occupied */
7295 expect := {
7296 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007297 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
7298 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
7299 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02007300 };
7301 f_statsd_expect(expect);
7302
7303 f_shutdown(__BFILE__, __LINE__, final := true);
7304}
7305
Oliver Smithf04762d2021-09-14 17:20:38 +02007306/* Test stats for available and occupied PDCHs, for MS which is not known by
7307 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
7308 * data arrives from SGSN) */
7309function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
7310 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
7311 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
7312
7313 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
7314 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
7315 gprsmultislotclass := '00001'B,
7316 gprsextendeddynalloccap := '0'B
7317 };
7318 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
7319 egprsmultislotclass := '00001'B,
7320 egprsextendeddynalloccap := '0'B
7321 };
7322 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
7323 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
7324 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
7325 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
7326
7327 /* Initialize NS/BSSGP side */
7328 f_init_bssgp();
7329
7330 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
7331 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
7332 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
7333 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
7334 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
7335 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
7336
7337 /* Allocate 1 GprsMS instance */
7338 f_init_gprs_ms(1);
7339
7340 /* Initialize the PCU interface abstraction */
7341 f_init_raw(testcasename(), info_ind);
7342
7343 /* Reset stats */
7344 f_statsd_reset();
7345
7346 /* Establish BSSGP */
7347 f_bssgp_establish();
7348
7349 /* 8 PDCHs available, 0 occupied */
7350 var StatsDExpects expect := {
7351 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7352 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
7353 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7354 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
7355 };
7356 f_statsd_expect(expect);
7357
7358 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
7359 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
7360
7361 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
7362 var octetstring data := f_rnd_octstring(1400);
7363 if (egprs) {
Philipp Maier1ec31b32023-09-22 12:59:10 +02007364 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs, imsi := ts_BSSGP_IMSI(ms.imsi)));
Oliver Smithf04762d2021-09-14 17:20:38 +02007365 } else {
Philipp Maier1ec31b32023-09-22 12:59:10 +02007366 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs, imsi := ts_BSSGP_IMSI(ms.imsi)));
Oliver Smithf04762d2021-09-14 17:20:38 +02007367 }
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02007368 f_ms_exp_dl_tbf_ass_ccch(ms);
Oliver Smithf04762d2021-09-14 17:20:38 +02007369
7370 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
7371 f_sleep(X2002);
7372
7373 /* 1 PDCH occupied */
7374 if (egprs) {
7375 expect := {
7376 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7377 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
7378 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7379 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
7380 };
7381 } else {
7382 expect := {
7383 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7384 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
7385 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
7386 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
7387 };
7388 }
7389 f_statsd_expect(expect);
7390
7391 /* Clean up */
7392 f_shutdown(__BFILE__, __LINE__, final := true);
7393}
7394testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
7395 f_tc_stat_pdch_avail_occ_ms_not_known(false);
7396}
7397testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
7398 f_tc_stat_pdch_avail_occ_ms_not_known(true);
7399}
7400
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007401/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
7402testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
7403 var PCUIF_info_ind info_ind;
7404 var template IARRestOctets rest;
7405 var BIT11 ra11;
7406
7407 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007408
7409 /* Only the first TRX is enabled. */
7410 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
7411 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7412
7413 /* Initialize the PCU interface abstraction */
7414 f_init_raw(testcasename(), info_ind);
7415 f_statsd_reset();
7416
7417 var EGPRSPktChRequest req := {
7418 one_phase := {
7419 tag := '0'B,
7420 multislot_class := '10101'B,
7421 priority := '01'B,
7422 random_bits := '101'B
7423 }
7424 };
7425
7426 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
7427 for (var integer i := 0; i < 7; i := i + 1) {
7428 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
7429 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
7430 }
7431
7432 ra11 := enc_EGPRSPktChRequest2bits(req);
7433 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
7434
7435 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01007436 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007437
7438 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
7439 f_sleep(2.0);
7440 var StatsDExpects expect := {
7441 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
7442 };
7443 f_statsd_expect(expect);
7444
7445 f_shutdown(__BFILE__, __LINE__, final := true);
7446}
7447
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007448control {
7449 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01007450 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007451 execute( TC_ta_ptcch_idle() );
7452 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02007453 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007454 execute( TC_ta_idle_dl_tbf_ass() );
7455 execute( TC_ta_ptcch_ul_multi_tbf() );
7456 execute( TC_cs_lqual_ul_tbf() );
7457 execute( TC_cs_initial_ul() );
7458 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01007459 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01007460 execute( TC_cs_max_dl() );
7461 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01007462 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01007463 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01007464 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01007465 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02007466 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01007467 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02007468 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01007469 execute( TC_x2031_t3191() );
7470 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007471 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01007472 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01007473 execute( TC_t3172_wait_ind_size0() );
7474 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02007475 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02007476 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02007477 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007478 execute( TC_mo_ping_pong() );
7479 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02007480 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007481 execute( TC_mt_ping_pong() );
7482 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007483 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007484 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07007485 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007486 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01007487 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02007488 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02007489 execute( TC_ul_tbf_bsn_wraparound_gprs());
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007490 execute( TC_paging_cs_from_bts() );
7491 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
7492 execute( TC_paging_cs_from_sgsn_sign() );
7493 execute( TC_paging_cs_from_sgsn_ptp() );
7494 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
7495 execute( TC_paging_ps_from_sgsn_sign() );
7496 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01007497 execute( TC_paging_pch_timeout() );
7498
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07007499 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
7500 execute( TC_paging_cs_multi_ms_imsi() );
7501 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02007502 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
7503 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01007504 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
7505 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007506
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007507 execute( TC_ul_tbf_finished_pkt_dl_ass_pch() );
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02007508 execute( TC_ul_tbf_1phase_while_dl_ass_pch() );
7509 execute( TC_ul_tbf_2phase_while_dl_ass_pch() );
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007510
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007511 /* EGPRS specific test cases */
7512 execute( TC_egprs_pkt_chan_req_signalling() );
7513 execute( TC_egprs_pkt_chan_req_one_phase() );
7514 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07007515 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07007516 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07007517 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02007518
7519 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07007520
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007521 /* Immediate Assignment on AGCH/PCH */
7522 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
7523 execute( TC_pcuif_fh_imm_ass_ul() );
7524 execute( TC_pcuif_fh_imm_ass_dl() );
7525 /* Packet Uplink/Downlink Assignment on PACCH */
7526 execute( TC_pcuif_fh_pkt_ass_ul() );
7527 execute( TC_pcuif_fh_pkt_ass_dl() );
7528 execute( TC_multitrx_multims_alloc() );
7529 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
Pau Espin Pedrol85ad3d02023-07-28 15:00:19 +02007530 execute( TC_dl_multislot_tbf_ms_class_unknown() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007531 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
7532 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02007533 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02007534 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01007535 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
7536 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007537
Pau Espin Pedrole1303052020-11-16 11:13:51 +01007538 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07007539
7540 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01007541 execute( TC_nacc_outbound_success() );
Philipp Maiere640d8f2023-06-30 14:43:01 +02007542 execute( TC_nacc_outbound_success_utran() );
7543 execute( TC_nacc_outbound_success_eutran() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01007544 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01007545 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01007546 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01007547 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01007548 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01007549 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
7550 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01007551 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
7552 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
7553 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01007554 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
7555 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01007556 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
7557 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
7558 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007559 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02007560 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
7561 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
7562 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
7563 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007564
7565 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007566 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007567 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007568
7569 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02007570
7571 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02007572 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
7573 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007574 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007575}
7576
Harald Weltea419df22019-03-21 17:23:04 +01007577}