blob: ffad7e602d9994f74cc2124080f7b2e00338af5d [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(
Harald Welte90f19742020-11-06 19:34:40 +0100114 f_PCUIF_AF2addr_type(mp_nsconfig.nsvc[0].provider.ip.address_family), mp_nsconfig.nsvc[0].provider.ip.local_ip)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200115}
116
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100117/* Passed in RAN-INFO message from emulated neighbor using RIM */
118const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
119const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
120const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
121const octetstring si_default := si1_default & si3_default & si13_default;
122
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +0100123const MultislotCap_GPRS mscap_gprs_def := {
124 gprsmultislotclass := '00011'B,
125 gprsextendeddynalloccap := '0'B
126};
127const MultislotCap_EGPRS mscap_egprs_def := {
128 egprsmultislotclass := '00011'B,
129 egprsextendeddynalloccap := '0'B
130};
131template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
132template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
133
134const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
135 gprsmultislotclass := '00011'B,
136 gprsextendeddynalloccap := '0'B
137};
138const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
139 egprsmultislotclass := '00011'B,
140 egprsextendeddynalloccap := '0'B
141};
142template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
143template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
144
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200145type record lqual_range {
146 /* component reference to the IPA_Client component used for RSL */
147 uint8_t low,
148 uint8_t high
149}
150
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100151type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700152 /* PCU interface abstraction component */
153 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700154
Daniel Willmann535aea62020-09-21 13:27:08 +0200155 /* StatsD */
156 var StatsD_Checker_CT vc_STATSD;
157
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200158 /* Connection to the PCUIF component */
159 port RAW_PCU_MSG_PT PCUIF;
160 /* VTY connection to the PCU */
161 port TELNETasp_PT PCUVTY;
162
163 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
164 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
165 {low := 5, high := 8},
166 {low := 7, high := 13},
167 {low := 12,high := 35}};
168 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
169 {low := 5, high := 8},
170 {low := 7, high := 13},
171 {low := 12,high := 15},
172 {low := 14, high := 17},
173 {low := 16, high := 18},
174 {low := 17,high := 20},
175 {low := 19, high := 24},
176 {low := 23,high := 35}};
177 var uint8_t g_cs_initial_dl := 1;
178 var uint8_t g_cs_initial_ul := 1;
179 var uint8_t g_mcs_initial_dl := 1;
180 var uint8_t g_mcs_initial_ul := 1;
181 var uint8_t g_cs_max_dl := 4;
182 var uint8_t g_cs_max_ul := 4;
183 var uint8_t g_mcs_max_dl := 9;
184 var uint8_t g_mcs_max_ul := 9;
185
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200186 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200187
188 /* Guard timeout */
189 timer g_T_guard := 60.0;
190};
191
192private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
193 [] g_T_guard.timeout {
194 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700195 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200196 }
197}
198
199private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
200 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
201 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
202
203 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
204 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
205}
206
207private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
208 var charstring cmd;
209
210 cmd := "cs link-quality-ranges" &
211 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
212 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
213 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
214 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
215 f_vty_config2(PCUVTY, {"pcu"}, cmd);
216
217 cmd := "mcs link-quality-ranges" &
218 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
219 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
220 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
221 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
222 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
223 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
224 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
225 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
226 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
227 f_vty_config2(PCUVTY, {"pcu"}, cmd);
228}
229
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100230private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
231 f_pcuvty_set_neigh_caches(0, 0);
232}
233
234private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
235runs on RAW_PCU_Test_CT {
236 if (neigh_cache_secs == -1) {
237 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
238 } else {
239 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
240 }
241 if (si_cache_secs == -1) {
242 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
243 } else {
244 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
245 }
246}
247
Pau Espin Pedrole8a94442021-11-15 17:05:46 +0100248private function f_pcuvty_set_timer(integer t, integer val)
249runs on RAW_PCU_Test_CT {
250 if (t >= 0) {
251 f_vty_config2(PCUVTY, {"pcu"}, "timer T" & int2str(t) & " " & int2str(val));
252 } else {
253 f_vty_config2(PCUVTY, {"pcu"}, "timer X" & int2str(t * -1) & " " & int2str(val));
254 }
255}
256
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100257private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200258 map(self:PCUVTY, system:PCUVTY);
259 f_vty_set_prompts(PCUVTY);
260 f_vty_transceive(PCUVTY, "enable");
261
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100262 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
263 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200264 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
265 } else {
266 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
267 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200268
269 if (g_force_two_phase_access) {
270 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
271 } else {
272 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
273 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200274}
275
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200276function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200277runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200278 /* Start the guard timer */
279 g_T_guard.start;
280 activate(as_Tguard_RAW());
281
282 /* Init PCU interface component */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100283 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF") alive;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200284 connect(vc_PCUIF:MTC, self:PCUIF);
285 map(vc_PCUIF:PCU, system:PCU);
286
287 /* Create one BTS component (we may want more some day) */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100288 vc_BTS := RAW_PCU_BTS_CT.create("BTS") alive;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200289 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
290 connect(vc_BTS:TC, self:BTS);
291
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100292 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200293
Daniel Willmann535aea62020-09-21 13:27:08 +0200294 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
295 /* This is normally done in the ConnHdlr component, but here
296 * the Test_CT doubles as ConnHdlr */
297 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
298
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200299 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100300 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200301
302 /* Wait until the BTS is ready (SI13 negotiated) */
303 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
304}
305
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700306/* Register TLLI of each allocated GprsMS instance */
307private function f_multi_ms_bssgp_register()
308runs on RAW_PCU_Test_CT {
309 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
310 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
311 }
312}
313
314/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
315private function f_multi_ms_establish_tbf(boolean do_activate := false)
316runs on RAW_PCU_Test_CT {
317 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
318 /* Establish an Uplink TBF */
319 f_ms_establish_ul_tbf(g_ms[i]);
320
321 /* Send a random block, so this TBF becomes "active" */
322 if (do_activate) {
323 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100324 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700325 var octetstring dummy := f_rnd_octstring(12);
326 var RlcmacDlBlock dl_block;
327 var uint32_t poll_fn;
328
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200329 /* Wait until PCU starts requesting for UL block on this TBF: */
330 f_ms_wait_usf(g_ms[i]);
331
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200332 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 +0700333 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
334 }
335 }
336}
337
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100338private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
339 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
340runs on RAW_PCU_Test_CT return PollFnCtx {
341 var PollFnCtx pollctx;
342
343 /* Single block (two phase) packet access */
344 var uint16_t ra := bit2int(chan_req_sb);
345 if (g_force_two_phase_access) {
346 /* If 2phase access is enforced by the network, then let's
347 * request a One phase packet access, we'll receive a single block
348 * anyway
349 */
350 ra := bit2int(chan_req_def);
351 }
352
353 /* Establish an Uplink TBF */
354 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
355 f_ms_establish_ul_tbf(ms);
356
357 /* Make sure we've got an Uplink TBF assignment */
358 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
359 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
360 f_shutdown(__BFILE__, __LINE__);
361 }
362
363 /* Send PACKET RESOURCE REQUEST
364 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
365 */
366 if (istemplatekind(pkt_res_req, "omit")) {
367 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
368 }
369
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200370 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 +0100371 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100372 * overwrite the TS allocation on MS with info from new UL TBF:
373 */
374 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
375 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
376 return pollctx;
377}
378
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200379testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200380 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100381 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200382 timer T;
383
384 /* Initialize NS/BSSGP side */
385 f_init_bssgp();
386
387 /* Initialize the PCU interface abstraction */
388 f_init_raw(testcasename());
389
390 /* Establish BSSGP connection to the PCU */
391 f_bssgp_establish();
392
393 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
394
395 T.start(2.0);
396 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100397 [] 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 +0200398 setverdict(pass);
399 }
400 [] T.timeout {
401 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
402 }
403 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700404
405 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200406}
407
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100408/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
409testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
410 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200411 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100412 var RlcmacDlBlock dl_block;
413 var octetstring data := f_rnd_octstring(10);
414 var uint32_t sched_fn;
415 var uint32_t dl_fn;
416 var GprsMS ms;
417 timer T;
418
419 /* Initialize NS/BSSGP side */
420 f_init_bssgp();
421 /* Initialize GPRS MS side */
422 f_init_gprs_ms();
423 ms := g_ms[0]; /* We only use first MS in this test */
424
425 /* Initialize the PCU interface abstraction */
426 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
427
428 /* Establish BSSGP connection to the PCU */
429 f_bssgp_establish();
430 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
431
432 /* Establish an Uplink TBF */
433 f_ms_establish_ul_tbf(ms);
434
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200435 /* Wait until PCU starts requesting for UL block on this TBF: */
436 f_ms_wait_usf(ms);
437
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100438 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200439 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200440 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 +0100441 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
442 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
443 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
444
445 /* UL block should be received in SGSN */
446 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
447
448 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +0200449 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +0200450 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100451
452 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
453 f_sleep(X2002);
454 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
455
456 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
457 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
458
459 T.start(2.0);
460 alt {
461 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
462 setverdict(pass);
463 }
464 [] T.timeout {
465 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
466 f_shutdown(__BFILE__, __LINE__);
467 }
468 }
469
470 /* Make sure we don't receive data for that TBF since it was released
471 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200472 f_pcuif_rx_data_req_pdtch(data_msg);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100473 if (data_msg.dl_block == omit) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200474 /* IDLE block, expected on new PCU versions */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200475 } else {
476 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100477 f_shutdown(__BFILE__, __LINE__);
478 }
479
480 /* New data arrives, PCU should page the MS since no TBF active exists: */
481 /* Send some more data, it will never reach the MS */
Philipp Maier7f064e62023-09-22 16:38:19 +0200482 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +0200483 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100484
485 f_shutdown(__BFILE__, __LINE__, final := true);
486}
487
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200488/* Test of correct Timing Advance at the time of TBF establishment
489 * (derived from timing offset of the Access Burst). */
490testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200491 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200492
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200493 /* Initialize GPRS MS side */
494 f_init_gprs_ms();
495 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200496 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100497 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200498
499 /* We cannot send too many TBF requests in a short time because
500 * at some point the PCU will fail to allocate a new TBF. */
501 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
502 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200503 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700504 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200505
506 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200507 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700508 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200509 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700510 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700511 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200512 }
513 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700514
515 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200516}
517
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200518/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
519 * sent in response to the first Uplink block after resource allocation. */
520testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
521 var GprsMS ms := valueof(t_GprsMS_def);
522 var PacketUlAckNack ul_ack_nack;
523 var PacketTimingAdvance pkt_ta;
524 var RlcmacDlBlock dl_block;
525 var uint32_t sched_fn;
526
527 /* Initialize NS/BSSGP side */
528 f_init_bssgp();
529
530 /* Initialize the PCU interface abstraction */
531 f_init_raw(testcasename());
532
533 /* Establish BSSGP connection to the PCU */
534 f_bssgp_establish();
535 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
536
537 /* Establish an Uplink TBF */
538 f_ms_establish_ul_tbf(ms);
539
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200540 /* Wait until PCU starts requesting for UL block on this TBF: */
541 f_ms_wait_usf(ms);
542
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200543 /* In a busy network, there can be a significant delay between resource
544 * allocation (Packet Uplink Assignment above) and the actual time when
545 * the MS is allowed to transmit the first Uplink data block. */
546
547 /* Simulate a delay > 0 */
548 ms.ta := 2;
549
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200550 /* We're in One-Phase Access contention resolution, include TLLI */
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200551 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
552 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
553
554 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
555 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
556 pkt_ta := ul_ack_nack.gprs.pkt_ta;
557 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
558 pkt_ta := ul_ack_nack.egprs.pkt_ta;
559 } else {
560 setverdict(fail, "PacketTimingAdvance IE is not present");
561 f_shutdown(__BFILE__, __LINE__);
562 }
563
564 if (not ispresent(pkt_ta.val)) {
565 setverdict(fail, "Timing Advance value is not present");
566 f_shutdown(__BFILE__, __LINE__);
567 } else if (pkt_ta.val != ms.ta) {
568 setverdict(fail, "Timing Advance mismatch: expected ",
569 ms.ta, ", but received ", pkt_ta.val);
570 f_shutdown(__BFILE__, __LINE__);
571 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +0200572
573 f_shutdown(__BFILE__, __LINE__, final := true);
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200574}
575
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200576/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
577 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
578 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
579 * no active TBF exists at the moment of establishment (idle mode). */
580testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100581 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200582
583 /* Initialize NS/BSSGP side */
584 f_init_bssgp();
585
586 /* Initialize the PCU interface abstraction */
587 f_init_raw(testcasename());
588
589 /* Establish BSSGP connection to the PCU */
590 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100591 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200592
593 /* SGSN sends some DL data, PCU will initiate Packet Downlink
594 * Assignment on CCCH (PCH). We don't care about the payload. */
Philipp Maierc49069b2023-09-22 16:32:42 +0200595 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 +0200596 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200597
598 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
599 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
600 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100601 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700602 setverdict(fail, "Timing Advance value doesn't match");
603 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700604
605 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200606}
607
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200608/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200609 * while neither Uplink nor Downlink TBF is established. */
610testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100611 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200612 timer T;
613
614 /* Initialize the PCU interface abstraction */
615 f_init_raw(testcasename());
616
617 /* Sent an RTS.req for PTCCH/D */
618 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
619 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
620 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100621
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200622 T.start(5.0);
623 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200624 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
625 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
626 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200627 }
628 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100629 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
630 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200631 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200632 [] BTS.receive(PCUIF_Message:?) { repeat; }
633 [] T.timeout {
634 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700635 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200636 }
637 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100638 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700639
640 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200641}
642
643/* Test of correct Timing Advance during an active Uplink TBF.
644 *
645 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
646 * are not continuous and there can be long time gaps between them. This happens
647 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
648 * significantly change between such rare Uplink transmissions, so GPRS introduces
649 * additional mechanisms to control Timing Advance, and thus reduce interference
650 * between neighboring TDMA time-slots.
651 *
652 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
653 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
654 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
655 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
656 * among with the initial Timing Advance value. And here PTCCH comes to play.
657 *
658 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
659 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
660 * continuously. To ensure continuous measurements of the signal propagation
661 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
662 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
663 *
664 * The purpose of this test case is to verify the assignment of Timing Advance
665 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
666 * first establishes several Uplink TBFs, but does not transmit any Uplink
667 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
668 * indications to the PCU, checking the correctness of two received PTCCH/D
669 * messages (period of PTCCH/D is two multi-frames).
670 */
671
672/* List of ToA values for Access Bursts to be sent on PTCCH/U,
673 * each ToA (Timing of Arrival) value is in units of 1/4 of
674 * a symbol (i.e. 1 symbol is 4 QTA units). */
675type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
676const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
677 0, 0, 0, 0,
678 0, 0, 0, 0,
679 0, 0, 0, 0,
680 0, 0, 0, 0
681};
682
683private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
684 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
685runs on RAW_PCU_Test_CT {
686 var RAW_PCU_Event event;
687 var integer ss;
688
689 /* Send Access Bursts on PTCCH/U for every TA Index */
690 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
691 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700692 if (ss < 0) { /* Shall not happen */
693 f_shutdown(__BFILE__, __LINE__);
694 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200695
696 log("Sending an Access Burst on PTCCH/U",
697 ", sub-slot=", ss, " (TAI)",
698 ", fn=", event.data.tdma_fn,
699 ", ToA=", toa_map[ss], " (QTA)");
700 /* TODO: do we care about RA and burst format? */
701 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
702 ra := oct2int('3A'O),
703 is_11bit := 0,
704 burst_type := BURST_TYPE_0,
705 fn := event.data.tdma_fn,
706 arfcn := 871,
707 qta := toa_map[ss],
708 sapi := PCU_IF_SAPI_PTCCH));
709 repeat;
710 }
711}
712
713private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
714 template PTCCHDownlinkMsg t_ta_msg)
715runs on RAW_PCU_Test_CT {
716 var PTCCHDownlinkMsg ta_msg;
717 var PCUIF_Message pcu_msg;
718 timer T;
719
720 /* First, send an RTS.req for the upcoming PTCCH/D block */
721 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
722 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
723 arfcn := 871, block_nr := 0));
724 T.start(2.0);
725 alt {
726 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
727 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
728 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
729 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
730 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
731 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
732 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
733 log("Rx PTCCH/D message: ", ta_msg);
734
735 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700736 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200737 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
738 }
739 }
740 [] BTS.receive { repeat; }
741 [] T.timeout {
742 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200743 }
744 }
745}
746
747testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
748 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200749 var GprsMS ms;
750
751 /* Initialize GPRS MS side */
752 f_init_gprs_ms();
753 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200754
755 /* Initialize the PCU interface abstraction */
756 f_init_raw(testcasename());
757
758 /* Enable forwarding of PTCCH/U TDMA events to us */
759 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
760
761 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
762 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200763 /* Establish an Uplink TBF */
764 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200765
766 /* We expect incremental TFI/USF assignment (dynamic allocation) */
767 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200768 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200769 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700770 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200771 }
772
773 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200774 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200775 setverdict(fail, "Failed to match Timing Advance Index for #", i);
776 /* Keep going, the current OsmoPCU does not assign TA Index */
777 }
778 }
779
780 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
781 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
782 for (var integer i := 0; i < 7; i := i + 1) {
783 /* ToA in units of 1/4 of a symbol */
784 toa_map[i] := (i + 1) * 7 * 4;
785 }
786
787 /* Now we have all 7 TBFs established in one-phase access mode,
788 * however we will not be sending any data on them. Instead, we
789 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
790 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
791 *
792 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
793 * time-slots, so at the moment of scheduling a PTCCH/D block
794 * the PCU has odd number of PTCCH/U Access Bursts received. */
795 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
796 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
797 /* Other values are not known (yet) */
798 tai3_ta := ?));
799 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
800 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
801 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
802 /* Other values are out of our interest */
803 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700804
805 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200806}
807
808/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
809 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
810 *
811 * NOTE: the ranges are intentionally overlapping because OsmoPCU
812 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
813private template integer CS1_lqual_dB_range := (-infinity .. 6);
814private template integer CS2_lqual_dB_range := (5 .. 8);
815private template integer CS3_lqual_dB_range := (7 .. 13);
816private template integer CS4_lqual_dB_range := (12 .. infinity);
817
818testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200819 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200820 var GprsMS ms;
821 var uint32_t unused_fn, sched_fn;
822 var uint4_t cv;
823
824 /* Initialize GPRS MS side */
825 f_init_gprs_ms();
826 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200827
828 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100829 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830
831 f_pcuvty_set_allowed_cs_mcs();
832 f_pcuvty_set_link_quality_ranges();
833
834 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200835 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200836
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200837 /* Wait until PCU starts requesting for UL block on this TBF: */
838 f_ms_wait_usf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200839
840 /* The actual / old link quality values. We need to keep track of the old
841 * (basically previous) link quality value, because OsmoPCU actually
842 * changes the coding scheme if not only the actual, but also the old
843 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200844 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200846
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200847 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200848 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200849 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
850 /* 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 +0200851 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 +0200852 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
853 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
854 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200855
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200856 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
857 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200858 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200859 lqual_old := ms.lqual_cb;
860 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200861
862 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200863 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
864 if (i > g_bs_cv_max) {
865 cv := 15;
866 } else {
867 cv := i;
868 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200869
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200870 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
871
872 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
873 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700874 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200875 continue;
876 }
877 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
878 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
879 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
880 f_shutdown(__BFILE__, __LINE__);
881 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200882
883 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
884 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
885
886 /* Match the received Channel Coding Command. Since we are increasing
887 * the link quality value on each iteration and not decreasing, there
888 * is no need to check the both old and current link quality values. */
889 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200890 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200891 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
892 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
893 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
894 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
895 }
896
897 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
898 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200899 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200900 }
901 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700902
903 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200904}
905
906/* Test the max UL CS set by VTY works fine */
907testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200908 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200909 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200910 var uint32_t unused_fn, sched_fn;
911 var GprsMS ms;
912
913 /* Initialize GPRS MS side */
914 f_init_gprs_ms();
915 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200916
917 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100918 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200919
920 /* Set initial UL CS to 3 */
921 g_cs_initial_ul := 3;
922 f_pcuvty_set_allowed_cs_mcs();
923 f_pcuvty_set_link_quality_ranges();
924
925 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200926 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200927
928 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200929 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200930
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +0200931 /* Wait until PCU starts requesting for UL block on this TBF: */
932 f_ms_wait_usf(ms);
933
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200934 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200935 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200936 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
937 /* 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 +0200938 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 +0200939 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
940 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
941 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200942
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200943 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
944 while (true) {
945 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
946 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700947 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200948 continue;
949 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200950
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200951 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
952 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
953 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
954 f_shutdown(__BFILE__, __LINE__);
955 break;
956 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200957
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200958 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200959 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200960 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200961 if (last_ch_coding != CH_CODING_CS3) {
962 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200963 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200964 }
965
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200966 /* Remaining UL blocks are used to make sure regardless of initial
967 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200968 /* 0 dB, make sure we downgrade CS */
969 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200970 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200971 f_ms_tx_ul_data_block_multi(ms, 5);
972 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
973 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
974 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200975
976 if (last_ch_coding != CH_CODING_CS1) {
977 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200978 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200979 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700980
981 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200982}
983
984/* Test the max UL CS set by VTY works fine */
985testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200986 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200987 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200988 var uint32_t unused_fn, sched_fn;
989 var GprsMS ms;
990
991 /* Initialize GPRS MS side */
992 f_init_gprs_ms();
993 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200994
995 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100996 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200997
998 /* Set maximum allowed UL CS to 3 */
999 g_cs_max_ul := 3;
1000 f_pcuvty_set_allowed_cs_mcs();
1001 f_pcuvty_set_link_quality_ranges();
1002
1003 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001004 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001005
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02001006 /* Wait until PCU starts requesting for UL block on this TBF: */
1007 f_ms_wait_usf(ms);
1008
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001009 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02001010 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001011 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1012 /* 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 +02001013 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 +02001014 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1015 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1016 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001017
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001018 ms.lqual_cb := 40*10; /* 40 dB */
1019 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001020
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001021 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1022 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001023
1024 if (last_ch_coding != CH_CODING_CS3) {
1025 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001026 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001027 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001028
1029 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001030}
1031
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001032/* Test the initial DL CS set by VTY works fine */
1033testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1034 var octetstring data := f_rnd_octstring(10);
1035 var CodingScheme exp_dl_cs_mcs;
1036 var RlcmacDlBlock dl_block;
1037 var uint32_t poll_fn;
1038 var GprsMS ms;
1039
1040 /* Initialize NS/BSSGP side */
1041 f_init_bssgp();
1042 /* Initialize GPRS MS side */
1043 f_init_gprs_ms();
1044 ms := g_ms[0]; /* We only use first MS in this test */
1045
1046 /* Initialize the PCU interface abstraction */
1047 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1048
1049 /* Set initial allowed DL CS to 3 */
1050 g_cs_initial_dl := 3;
1051 exp_dl_cs_mcs := CS_3;
1052 /* Set maximum allowed UL CS to 4 */
1053 g_cs_max_dl := 4;
1054 f_pcuvty_set_allowed_cs_mcs();
1055 f_pcuvty_set_link_quality_ranges();
1056
1057 /* Establish BSSGP connection to the PCU */
1058 f_bssgp_establish();
1059 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1060
1061 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001062 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001063 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001064
1065 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1066 f_sleep(X2002);
1067 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1068
1069 /* ACK the DL block */
1070 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1071 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1072 f_dl_block_ack_fn(dl_block, poll_fn));
1073
1074 f_shutdown(__BFILE__, __LINE__, final := true);
1075}
1076
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001077/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001078function 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 +01001079 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001080 var RlcmacDlBlock prev_dl_block, dl_block;
1081 var uint32_t ack_fn;
1082 var uint32_t fn;
1083 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001084 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001085 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001086 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1087 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001088 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001089
1090 if (using_egprs) {
1091 exp_tmp_csmcs := mcs_egprs_any;
1092 bsn_mod := 2048;
1093 } else {
1094 exp_tmp_csmcs := cs_gprs_any;
1095 bsn_mod := 128;
1096 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001097
1098 /* Establish BSSGP connection to the PCU */
1099 f_bssgp_establish();
1100
1101 ms := g_ms[0]; /* We only use first MS in this test */
1102 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1103
1104 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001105 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 +02001106 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001107
1108 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1109 f_sleep(X2002);
1110
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001111 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
1112 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
1113
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001114 for (var integer i := 0; i < 800; i := i + 1) {
1115 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001116
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001117 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001118 /* No more data to receive, done */
1119 break;
1120 }
1121
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001122 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001123
1124 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001125 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001126
1127 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001128 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001129 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001130 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 +01001131 if (tx_data_remain != 0) {
1132 /* Submit more data from time to time to keep the TBF ongoing */
1133 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1134 tx_data_remain := tx_data_remain - 1;
1135 }
1136 }
1137 prev_dl_block := dl_block;
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001138 f_rx_rlcmac_dl_block(dl_block, fn);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001139 }
1140
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001141 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1142 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001143
1144
1145 f_shutdown(__BFILE__, __LINE__, final := true);
1146}
1147
1148/* Verify DL CS above "cs max" set by VTY is never used */
1149testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1150 /* Initialize NS/BSSGP side */
1151 f_init_bssgp();
1152 /* Initialize GPRS MS side */
1153 f_init_gprs_ms();
1154
1155 /* Initialize the PCU interface abstraction */
1156 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1157
1158 /* Set maximum allowed DL CS to 3 */
1159 g_cs_initial_dl := 1;
1160 g_cs_max_dl := 3;
1161 f_pcuvty_set_allowed_cs_mcs();
1162 f_pcuvty_set_link_quality_ranges();
1163
1164 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001165
1166 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001167}
1168
1169/* Check DL CS4 is used in good link conditions if allowed by config */
1170testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1171 /* Initialize NS/BSSGP side */
1172 f_init_bssgp();
1173 /* Initialize GPRS MS side */
1174 f_init_gprs_ms();
1175
1176 /* Initialize the PCU interface abstraction */
1177 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1178
1179 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1180 g_cs_initial_dl := 1;
1181 g_cs_max_dl := 4;
1182 f_pcuvty_set_allowed_cs_mcs();
1183 f_pcuvty_set_link_quality_ranges();
1184
1185 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001186
1187 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001188}
1189
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001190/* Test the initial UL MCS set by VTY works fine */
1191testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1192 var RlcmacDlBlock dl_block;
1193 var PollFnCtx pollctx;
1194 var EgprsChCodingCommand last_ch_coding;
1195 var uint32_t unused_fn, sched_fn;
1196 var GprsMS ms;
1197 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001198
1199 /* Initialize GPRS MS side */
1200 f_init_gprs_ms();
1201 ms := g_ms[0]; /* We only use first MS in this test */
1202
1203 /* Initialize the PCU interface abstraction */
1204 f_init_raw(testcasename());
1205
1206 /* Set initial UL MCS to 3 */
1207 g_mcs_initial_ul := 3;
1208 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1209 f_pcuvty_set_allowed_cs_mcs();
1210 f_pcuvty_set_link_quality_ranges();
1211
1212 /* Take lqual (dB->cB) so that we stay in that MCS */
1213 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1214
1215 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001216 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 +01001217
1218 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1219 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1220 f_shutdown(__BFILE__, __LINE__);
1221 }
1222
1223 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1224 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1225
1226 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1227 while (true) {
1228 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1229 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001230 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001231 continue;
1232 }
1233
1234 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1235 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1236 f_shutdown(__BFILE__, __LINE__);
1237 break;
1238 }
1239
1240 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1241 break;
1242 }
1243 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1244 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1245 f_shutdown(__BFILE__, __LINE__);
1246 }
1247
1248 /* Remaining UL blocks are used to make sure regardless of initial
1249 * lqual, we can go lower at any time
1250 * 0 dB, make sure we downgrade MCS */
1251 ms.lqual_cb := 0;
1252 /* 5 UL blocks, check we are in same initial MCS: */
1253 f_ms_tx_ul_data_block_multi(ms, 5);
1254 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1255 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1256 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1257
1258 if (last_ch_coding != CH_CODING_MCS1) {
1259 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1260 f_shutdown(__BFILE__, __LINE__);
1261 }
1262
1263 f_shutdown(__BFILE__, __LINE__, final := true);
1264}
1265
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001266/* Test the maximum UL MCS set by VTY works fine */
1267testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1268 var RlcmacDlBlock dl_block;
1269 var EgprsChCodingCommand last_ch_coding;
1270 var PollFnCtx pollctx;
1271 var uint32_t unused_fn, sched_fn;
1272 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001273
1274 /* Initialize GPRS MS side */
1275 f_init_gprs_ms();
1276 ms := g_ms[0]; /* We only use first MS in this test */
1277
1278 /* Initialize the PCU interface abstraction */
1279 f_init_raw(testcasename());
1280
1281 /* Set maximum allowed UL MCS to 5 */
1282 g_mcs_max_ul := 5;
1283 f_pcuvty_set_allowed_cs_mcs();
1284 f_pcuvty_set_link_quality_ranges();
1285
1286 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001287 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 +01001288 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1289 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1290
1291 ms.lqual_cb := 40*10; /* 40 dB */
1292 f_ms_tx_ul_data_block_multi(ms, 16);
1293
1294 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1295 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1296
1297 if (last_ch_coding != CH_CODING_MCS5) {
1298 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1299 f_shutdown(__BFILE__, __LINE__);
1300 }
1301
1302 f_shutdown(__BFILE__, __LINE__, final := true);
1303}
1304
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001305/* Test the initial DL CS set by VTY works fine */
1306testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1307 var octetstring data := f_rnd_octstring(10);
1308 var CodingScheme exp_dl_cs_mcs;
1309 var RlcmacDlBlock dl_block;
1310 var uint32_t poll_fn;
1311 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001312
1313 /* Initialize NS/BSSGP side */
1314 f_init_bssgp();
1315 /* Initialize GPRS MS side */
1316 f_init_gprs_ms();
1317 ms := g_ms[0]; /* We only use first MS in this test */
1318
1319 /* Initialize the PCU interface abstraction */
1320 f_init_raw(testcasename());
1321
1322 /* Set initial allowed DL MCS to 3 */
1323 g_mcs_initial_dl := 3;
1324 exp_dl_cs_mcs := MCS_3;
1325 /* Set maximum allowed DL MCS to 4 */
1326 g_mcs_max_dl := 4;
1327 f_pcuvty_set_allowed_cs_mcs();
1328 f_pcuvty_set_link_quality_ranges();
1329
1330 /* Establish BSSGP connection to the PCU */
1331 f_bssgp_establish();
1332 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1333
1334 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001335 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 +02001336 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001337
1338 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1339 f_sleep(X2002);
1340 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1341
1342 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001343 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1344 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 +01001345 f_dl_block_ack_fn(dl_block, poll_fn));
1346
1347 f_shutdown(__BFILE__, __LINE__, final := true);
1348}
1349
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001350/* Verify DL MCS above "mcs max" set by VTY is never used */
1351testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1352 /* Initialize NS/BSSGP side */
1353 f_init_bssgp();
1354 /* Initialize GPRS MS side */
1355 f_init_gprs_ms();
1356
1357 /* Initialize the PCU interface abstraction */
1358 f_init_raw(testcasename());
1359
1360 /* Set maximum allowed DL CS to 3 */
1361 g_mcs_initial_dl := 1;
1362 g_mcs_max_dl := 3;
1363 f_pcuvty_set_allowed_cs_mcs();
1364 f_pcuvty_set_link_quality_ranges();
1365
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001366 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 +02001367
1368 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001369}
1370
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001371/* Verify PCU drops TBF after some time of inactivity. */
1372testcase TC_t3141() runs on RAW_PCU_Test_CT {
1373 var PCUIF_info_ind info_ind;
1374 var template (value) TsTrxBtsNum nr;
1375 var BTS_PDTCH_Block data_msg;
1376 var GprsMS ms;
1377 var uint3_t rx_usf;
1378 timer T_3141 := 1.0;
1379 var boolean ul_tbf_usf_req := false;
1380
1381 /* Initialize NS/BSSGP side */
1382 f_init_bssgp();
1383 /* Initialize GPRS MS side */
1384 f_init_gprs_ms();
1385 ms := g_ms[0]; /* We only use first MS in this test */
1386
1387 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1388 /* Only use 1 PDCH to simplify test: */
1389 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1390 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1391 /* Initialize the PCU interface abstraction */
1392 f_init_raw(testcasename(), info_ind);
1393
1394 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1395
1396 /* Establish BSSGP connection to the PCU */
1397 f_bssgp_establish();
1398 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1399
1400 /* Establish a one-phase access Uplink TBF */
1401 f_ms_establish_ul_tbf(ms);
1402
1403 T_3141.start;
1404
1405 /* Now we wait for PCU to transmit our USF */
1406 nr := ts_TsTrxBtsNum;
1407 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1408 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1409 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1410 block_nr := nr.blk_nr));
1411
1412 alt {
1413 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1414 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1415 ?)) -> value data_msg {
1416 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1417 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1418 f_shutdown(__BFILE__, __LINE__);
1419 }
1420
1421 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1422 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1423 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1424 ul_tbf_usf_req := true;
1425 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))
1426 } else if (rx_usf == USF_UNUSED) {
1427 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1428 if (ul_tbf_usf_req) {
1429 /* TBF was dropped by T3141, success */
1430 setverdict(pass);
1431 break;
1432 } else {
1433 log("PCU never requested USF, unexpected");
1434 f_shutdown(__BFILE__, __LINE__);
1435 }
1436 } /* else: Keep waiting for TBF to be active by network */
1437 } else {
1438 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1439 f_shutdown(__BFILE__, __LINE__);
1440 }
1441
1442 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1443 if (match(data_msg.dl_block,
1444 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1445 tr_UlAckNackGprs(tlli := ?,
1446 acknack_desc := ?,
1447 rel99 := *))))
1448 {
1449 log("Received UL ACK/NACK with TLLI set");
1450 f_shutdown(__BFILE__, __LINE__);
1451 }
1452
1453 nr := ts_TsTrxBtsNum;
1454 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1455 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1456 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1457 block_nr := nr.blk_nr));
1458 repeat;
1459 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001460 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1461 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1462 omit)) {
1463 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1464 our last RTS.req because there's no longer any MS listening on
1465 the TS. */
1466 setverdict(pass);
1467 break;
1468 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001469 [] T_3141.timeout {
1470 log("T_3141 expired but TBF is still active, unexpected");
1471 f_shutdown(__BFILE__, __LINE__);
1472 }
1473 [] BTS.receive {
1474 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1475 * because we never sent the TLLI to the PCU */
1476 setverdict(fail, "Unexpected BTS message");
1477 f_shutdown(__BFILE__, __LINE__);
1478 }
1479 }
1480
1481 f_shutdown(__BFILE__, __LINE__, final := true);
1482}
1483
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001484/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1485 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1486 * T3169. See OS#5033 */
1487testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1488 var PCUIF_info_ind info_ind;
1489 var template (value) TsTrxBtsNum nr;
1490 var BTS_PDTCH_Block data_msg;
1491 var GprsMS ms;
1492 var uint3_t rx_usf;
1493 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1494 var integer n3101 := 0;
1495 timer T_3169 := 1.0;
1496
1497 /* Initialize NS/BSSGP side */
1498 f_init_bssgp();
1499 /* Initialize GPRS MS side */
1500 f_init_gprs_ms();
1501 ms := g_ms[0]; /* We only use first MS in this test */
1502
1503 /* Initialize the PCU interface abstraction */
1504 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1505 info_ind.n3101 := N3101_MAX;
1506 info_ind.t3169 := 1;
1507 f_init_raw(testcasename(), info_ind);
1508
1509 /* Establish BSSGP connection to the PCU */
1510 f_bssgp_establish();
1511 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1512
1513 /* Establish UL TBF */
1514 f_ms_establish_ul_tbf(ms);
1515
1516 /* Now we wait for PCU to transmit our USF */
1517 nr := ts_TsTrxBtsNum;
1518 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1519 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1520 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1521 block_nr := nr.blk_nr));
1522
1523 alt {
1524 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1525 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1526 ?)) -> value data_msg {
1527 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1528 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1529 f_shutdown(__BFILE__, __LINE__);
1530 }
1531
1532 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1533 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1534 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1535 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001536 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1537 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001538 f_shutdown(__BFILE__, __LINE__);
1539 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001540 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001541 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1542 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1543 if (not T_3169.running) {
1544 log("T3169 started");
1545 T_3169.start;
1546 }
1547 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1548 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1549 f_shutdown(__BFILE__, __LINE__);
1550 } else {
1551 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1552 }
1553 nr := ts_TsTrxBtsNum;
1554 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1555 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1556 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1557 block_nr := nr.blk_nr));
1558 repeat;
1559 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001560 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1561 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001562 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001563 [] T_3169.timeout {
1564 log("T_3169 expired");
1565 /* Done in alt */
1566 }
1567 [] BTS.receive {
1568 setverdict(fail, "Unexpected BTS message");
1569 f_shutdown(__BFILE__, __LINE__);
1570 }
1571 }
1572
1573 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1574 /* USFs as per previous TBF since they were freed at expiration time: */
1575 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1576 var uint5_t old_tfi := ms.ul_tbf.tfi;
1577 f_ms_establish_ul_tbf(ms);
1578 if (old_tfi != ms.ul_tbf.tfi) {
1579 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1580 f_shutdown(__BFILE__, __LINE__);
1581 }
1582 for (var integer i := 0; i < 8; i := i +1) {
1583 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1584 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1585 f_shutdown(__BFILE__, __LINE__);
1586 }
1587 }
1588
1589 f_shutdown(__BFILE__, __LINE__, final := true);
1590}
1591
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001592
1593/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1594 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1595 the final UL ACK sent at us. */
1596testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1597 var PCUIF_info_ind info_ind;
1598 var BTS_PDTCH_Block data_msg;
1599 var RlcmacDlBlock dl_block;
1600 var uint32_t sched_fn;
1601 var template (value) TsTrxBtsNum nr;
1602 var template RlcmacDlBlock exp_ul_ack;
1603 var template UlAckNackGprs exp_ul_ack_sub;
1604 var GprsMS ms;
1605 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1606 var integer N3103 := 0;
1607 timer T_3169 := 1.0;
1608
1609 /* Initialize GPRS MS side */
1610 f_init_gprs_ms();
1611 ms := g_ms[0]; /* We only use first MS in this test */
1612
1613 /* Initialize the PCU interface abstraction */
1614 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1615 info_ind.n3103 := N3103_MAX;
1616 info_ind.t3169 := 1;
1617 f_init_raw(testcasename(), info_ind);
1618
1619 /* Establish an Uplink TBF */
1620 f_ms_establish_ul_tbf(ms);
1621
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02001622 /* Wait until PCU starts requesting for UL block on this TBF: */
1623 f_ms_wait_usf(ms);
1624
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001625 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001626 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1627 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1628
1629 nr := ts_TsTrxBtsNum;
1630 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1631 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1632 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1633 block_nr := nr.blk_nr));
1634 alt {
1635 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1636 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1637 exp_ul_ack)) -> value data_msg {
1638 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1639 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1640 f_shutdown(__BFILE__, __LINE__);
1641 }
1642
1643 nr := ts_TsTrxBtsNum;
1644 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1645 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1646 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1647 block_nr := nr.blk_nr));
1648 N3103 := N3103 + 1;
1649 if (N3103 == N3103_MAX) {
1650 /* At this point in time (N3103_MAX reached), PCU is
1651 * moving the TBF to RELEASE state so no data/ctrl for
1652 * it is tx'ed, hence the dummy blocks: */
1653 T_3169.start;
1654 }
1655 repeat;
1656 }
1657 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1658 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1659 exp_ul_ack)) -> value data_msg {
1660 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1661 f_shutdown(__BFILE__, __LINE__);
1662 }
1663 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001664 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001665 [T_3169.running] T_3169.timeout {
1666 log("T_3169 timeout");
1667 /* Done in alt, wait for pending RTS initiated previously in
1668 * above case before continuing (expect /* Dummy block): */
1669 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1670 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001671 tr_RLCMAC_DL_DUMMY_CTRL));
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001672 }
1673 [] BTS.receive {
1674 setverdict(fail, "Unexpected BTS message");
1675 f_shutdown(__BFILE__, __LINE__);
1676 }
1677 }
1678
1679 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1680 * USFs as per previous TBF since they were freed at expiration time: */
1681 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1682 var uint5_t old_tfi := ms.ul_tbf.tfi;
1683 f_ms_establish_ul_tbf(ms);
1684 if (old_tfi != ms.ul_tbf.tfi) {
1685 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1686 f_shutdown(__BFILE__, __LINE__);
1687 }
1688 for (var integer i := 0; i < 8; i := i +1) {
1689 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1690 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1691 f_shutdown(__BFILE__, __LINE__);
1692 }
1693 }
1694
1695 f_shutdown(__BFILE__, __LINE__, final := true);
1696}
1697
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001698/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1699 * point the TBF is no longer available. In order to get to start of T3191, we
1700 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1701 * until TBF release procedure starts after draining DL queue. */
1702testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1703 var PCUIF_info_ind info_ind;
1704 var RlcmacDlBlock dl_block;
1705 var octetstring data1 := f_rnd_octstring(200);
1706 var octetstring data2 := f_rnd_octstring(10);
1707 var uint32_t dl_fn;
1708 var template (value) TsTrxBtsNum nr;
1709 var BTS_PDTCH_Block data_msg;
1710 var GprsMS ms;
1711
1712 /* Initialize NS/BSSGP side */
1713 f_init_bssgp();
1714 /* Initialize GPRS MS side */
1715 f_init_gprs_ms();
1716 ms := g_ms[0]; /* We only use first MS in this test */
1717
1718 /* Initialize the PCU interface abstraction */
1719 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1720 /* Set timer to 1 sec (default 5) to speedup test: */
1721 info_ind.t3191 := 1;
1722 f_init_raw(testcasename(), info_ind);
1723
1724 /* Establish BSSGP connection to the PCU */
1725 f_bssgp_establish();
1726 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1727
1728 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001729 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001730 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001731
1732 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1733 f_sleep(X2002);
1734
1735 while (true) {
1736 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1737
1738 /* Keep Ack/Nack description updated (except for last BSN) */
1739 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1740
1741 if (f_dl_block_rrbp_valid(dl_block)) {
1742 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1743 f_dl_block_ack_fn(dl_block, dl_fn));
1744 break;
1745 }
1746 }
1747
1748 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1749 nr := ts_TsTrxBtsNum;
1750 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1751 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1752 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1753 block_nr := nr.blk_nr));
1754 alt {
1755 [] as_ms_rx_ignore_dummy(ms, nr);
1756 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1757 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1758 ?)) -> value data_msg {
1759 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1760 log("Received FINAL_ACK");
1761 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1762 break;
1763 }
1764 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1765 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1766 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1767 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1768 }
1769 nr := ts_TsTrxBtsNum;
1770 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1771 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1772 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1773 block_nr := nr.blk_nr));
1774 repeat;
1775 }
1776 [] BTS.receive {
1777 setverdict(fail, "Unexpected BTS message");
1778 f_shutdown(__BFILE__, __LINE__);
1779 }
1780 }
1781
1782 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1783 to time out. We simply sleep instead of requesting blocks because
1784 otherwise retransmissions would keep restarting the timer. */
1785 f_sleep(int2float(info_ind.t3191));
1786
1787 /* The TBF should be freed now, so new data should trigger an Assignment: */
Philipp Maier7f064e62023-09-22 16:38:19 +02001788 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001789 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001790
1791 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1792 f_sleep(X2002);
1793 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1794 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1795 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1796 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1797 f_dl_block_ack_fn(dl_block, dl_fn));
1798
1799 f_shutdown(__BFILE__, __LINE__, final := true);
1800}
1801
1802/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1803testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1804 var PCUIF_info_ind info_ind;
1805 var RlcmacDlBlock dl_block;
1806 var octetstring data1 := f_rnd_octstring(1400);
1807 var octetstring data2 := f_rnd_octstring(10);
1808 var uint32_t dl_fn;
1809 var GprsMS ms;
1810
1811 /* Initialize NS/BSSGP side */
1812 f_init_bssgp();
1813 /* Initialize GPRS MS side */
1814 f_init_gprs_ms();
1815 ms := g_ms[0]; /* We only use first MS in this test */
1816
1817 /* Initialize the PCU interface abstraction */
1818 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1819 /* Set timer to 1 sec (default 5) to speedup test: */
1820 info_ind.t3191 := 1;
1821 f_init_raw(testcasename(), info_ind);
1822
1823 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1824
1825 /* Establish BSSGP connection to the PCU */
1826 f_bssgp_establish();
1827 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1828
1829 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001830 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001831 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001832
1833 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1834 f_sleep(X2002);
1835
1836 /* Send enough DL data to at least be able to DL ACK once (excl the
1837 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1838 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1839 while (true) {
1840 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1841
1842 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1843 log("Received FINAL_ACK");
1844 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1845 break;
1846 }
1847
1848 /* Keep Ack/Nack description updated (except for last BSN) */
1849 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1850
1851 if (f_dl_block_rrbp_valid(dl_block)) {
1852 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1853 f_dl_block_ack_fn(dl_block, dl_fn));
1854 }
1855 }
1856
1857 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1858 to time out. We simply sleep instead of requesting blocks because
1859 otherwise retransmissions would keep restarting the timer. */
1860 f_sleep(int2float(info_ind.t3191));
1861
1862 /* The TBF should be freed now, so new data should trigger an Assignment: */
Philipp Maier7f064e62023-09-22 16:38:19 +02001863 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001864 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001865
1866 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1867 f_sleep(X2002);
1868 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1869 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1870 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1871 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1872 f_dl_block_ack_fn(dl_block, dl_fn));
1873
1874 f_shutdown(__BFILE__, __LINE__, final := true);
1875}
1876
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001877/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1878 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1879 * T3193) after DL TBF release */
1880testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001881 var RlcmacDlBlock dl_block;
1882 var octetstring data := f_rnd_octstring(10);
1883 var boolean ok;
1884 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001885 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001886 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001887 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1888
1889 /* Initialize NS/BSSGP side */
1890 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001891 /* Initialize GPRS MS side */
1892 f_init_gprs_ms();
1893 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001894
1895 /* Initialize the PCU interface abstraction */
1896 f_init_raw(testcasename());
1897
Pau Espin Pedrol1c6a9e42023-06-20 11:54:56 +02001898 /* Disable "idle DL TBF alive" timer, to make the test easier and avoid
1899 * having to keep receiving dummy LLC blocks for a while until the last
1900 * block with FBI=1 is set. This way the first and only DL block is already
1901 * the FBI one. */
1902 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1903
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001904 /* Establish BSSGP connection to the PCU */
1905 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001906 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001907
1908 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001909 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001910 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001911
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001912 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1913 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001914 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol1c6a9e42023-06-20 11:54:56 +02001915 if (dl_block.data.mac_hdr.hdr_ext.fbi == false) {
1916 setverdict(fail, "Expected DL data block with FBI=1 but got FBI=0");
1917 f_shutdown(__BFILE__, __LINE__);
1918 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001919
1920 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001921 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1922 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1923 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001924
1925 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001926 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001927 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001928 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001929 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001930
1931 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001932
1933 /* 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 +07001934 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001935 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1936 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1937 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001938
1939 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001940}
1941
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001942/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1943 freed and no longer available. Trigger it by sending DL blocks and never DL
1944 ACKing the data (which are requested through RRBP) */
1945testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1946 var PCUIF_info_ind info_ind;
1947 var RlcmacDlBlock dl_block;
1948 var octetstring data1 := f_rnd_octstring(1000);
1949 var octetstring data2 := f_rnd_octstring(10);
1950 var uint32_t dl_fn;
1951 var template (value) TsTrxBtsNum nr;
1952 var BTS_PDTCH_Block data_msg;
1953 var GprsMS ms;
1954 const integer N3105_MAX := 2;
1955 var integer N3105 := 0;
1956 timer T_3195 := 1.0;
1957 var integer num_poll_recv := 0;
1958
1959 /* Initialize NS/BSSGP side */
1960 f_init_bssgp();
1961 /* Initialize GPRS MS side */
1962 f_init_gprs_ms();
1963 ms := g_ms[0]; /* We only use first MS in this test */
1964
1965 /* Initialize the PCU interface abstraction */
1966 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1967 /* Speedup test: */
1968 info_ind.n3105 := N3105_MAX;
1969 info_ind.t3195 := 1;
1970 f_init_raw(testcasename(), info_ind);
1971
1972 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1973 * MS and retransmitted after the TBF is released and later on created
1974 * (because the MS is reused) */
1975 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1976
1977 /* Establish BSSGP connection to the PCU */
1978 f_bssgp_establish();
1979 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1980
1981 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02001982 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02001983 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001984
1985 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1986 f_sleep(X2002);
1987
1988 /* Now we go on receiving DL data and not answering RRBP: */
1989 nr := ts_TsTrxBtsNum;
1990 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1991 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1992 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1993 block_nr := nr.blk_nr));
1994 alt {
1995 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1996 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1997 tr_RLCMAC_DATA)) -> value data_msg {
1998 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1999 if (num_poll_recv == 0) {
2000 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
2001 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
2002 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2003 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
2004 } else {
2005 log("Ignoring RRBP ", num_poll_recv);
2006 N3105 := N3105 + 1;
2007 }
2008 num_poll_recv := num_poll_recv + 1;
2009 }
2010
2011 nr := ts_TsTrxBtsNum;
2012 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2013 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2014 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2015 block_nr := nr.blk_nr));
2016 repeat;
2017 }
2018 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002019 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002020 */
2021 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2022 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002023 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002024 if (not T_3195.running) {
2025 T_3195.start;
2026 /* We even send some new data, nothing should be sent to MS */
2027 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2028 }
2029 nr := ts_TsTrxBtsNum;
2030 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2031 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2032 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2033 block_nr := nr.blk_nr));
2034 repeat;
2035 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01002036 /* We may already receive idle blocks before our own TTCN3 timer
2037 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002038 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002039 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002040 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002041 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002042 * above case before continuing (expect empty block): */
Pau Espin Pedrolaedacf32023-09-26 19:29:38 +02002043 alt {
2044 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002045 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrolaedacf32023-09-26 19:29:38 +02002046 omit)); /* DONE, continue after altstep. */
2047 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2048 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2049 tr_RLCMAC_DL_DUMMY_CTRL)) {
2050 setverdict(fail, "Rx unexpected DUMMY message, expected empty data block");
2051 f_shutdown(__BFILE__, __LINE__);
2052 }
2053 }
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002054 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002055 [] BTS.receive {
2056 setverdict(fail, "Unexpected BTS message");
2057 f_shutdown(__BFILE__, __LINE__);
2058 }
2059 }
2060
2061 /* after T_3195 timeout, TBF is released */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002062 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002063 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002064
2065 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2066 f_sleep(X2002);
2067 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2068
2069 /* ACK the DL block */
2070 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2071 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2072 f_dl_block_ack_fn(dl_block, dl_fn));
2073
2074 f_shutdown(__BFILE__, __LINE__, final := true);
2075}
2076
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002077/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2078function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2079 var PCUIF_info_ind info_ind;
2080 var template IARRestOctets rest;
2081 var BIT11 ra11;
2082 var GprsMS ms;
2083 var octetstring data := f_rnd_octstring(10);
2084 var RlcmacDlBlock dl_block;
2085 var template RlcmacDlBlock rej_tmpl;
2086 var uint32_t dl_fn;
2087 var uint32_t sched_fn;
2088 var uint8_t wait_ind_val;
2089
2090 /* Initialize NS/BSSGP side */
2091 f_init_bssgp();
2092 /* Initialize GPRS MS side */
2093 f_init_gprs_ms();
2094 ms := g_ms[0]; /* We only use first MS in this test */
2095
2096 info_ind := valueof(ts_PCUIF_INFO_default);
2097
2098 /* Only the first TRX is enabled. */
2099 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2100 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2101
2102 /* Initialize the PCU interface abstraction */
2103 f_init_raw(testcasename(), info_ind);
2104
2105 f_pcuvty_set_timer(3172, t3172_ms);
2106
2107 /* Establish BSSGP connection to the PCU */
2108 f_bssgp_establish();
2109 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2110
2111 var EGPRSPktChRequest req := {
2112 one_phase := {
2113 tag := '0'B,
2114 multislot_class := '10101'B,
2115 priority := '01'B,
2116 random_bits := '101'B
2117 }
2118 };
2119
2120 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2121 for (var integer i := 0; i < 7; i := i + 1) {
2122 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2123 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2124 }
2125
2126 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002127 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002128 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002129
2130 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2131 f_sleep(X2002);
2132 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2133
2134 /* ACK the DL block */
2135 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2136 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2137 f_dl_block_ack_fn(dl_block, dl_fn));
2138
2139 /* Since all USF are taken, we should receive a Reject: */
2140
2141 if (wait_ind_size == '0'B) {
2142 wait_ind_val := t3172_ms / 1000;
2143 } else {
2144 wait_ind_val := t3172_ms / 20;
2145 }
2146 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2147 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2148 wait_ind_val,
2149 wait_ind_size)));
2150 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2151 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2152 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2153 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2154 block_nr := nr.blk_nr));
2155 alt {
2156 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2157 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2158 rej_tmpl));
2159 [] BTS.receive {
2160 setverdict(fail, "Unexpected BTS message");
2161 f_shutdown(__BFILE__, __LINE__);
2162 }
2163 }
2164 f_shutdown(__BFILE__, __LINE__, final := true);
2165}
2166testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2167 /* size=0 means value is provided in seconds. Due to value being 8
2168 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2169 * = 5100. Hence, values above it should use size=0 to be able to
2170 * provide values in range. Let's use 6 seconds, 6000ms
2171 */
2172 f_TC_t3172(6000, '0'B);
2173}
2174testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2175 f_TC_t3172(3000, '1'B);
2176}
2177
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002178/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2179testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002180 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002181 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002182 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002183 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002184
2185 /* Initialize NS/BSSGP side */
2186 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002187 /* Initialize GPRS MS side */
2188 f_init_gprs_ms();
2189 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002190
2191 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002192 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002193
2194 /* Establish BSSGP connection to the PCU */
2195 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002196 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002197
2198 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002199 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002200
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002201 /* Wait until PCU starts requesting for UL block on this TBF: */
2202 f_ms_wait_usf(ms);
2203
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002204 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002205 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002206 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002207 /* 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 +02002208 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 +02002209 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2210 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002211 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002212
2213 /* Send enough blocks to test whole procedure: Until Nth block
2214 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2215 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002216 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002217 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2218 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002219 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002220
2221 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002222 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 +07002223
2224 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002225}
2226
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002227/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2228testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2229 var RlcmacDlBlock dl_block;
2230 var uint32_t dl_fn, sched_fn;
2231 var octetstring payload;
2232 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002233 var template (value) LlcBlockHdr blk_hdr;
2234 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002235 var integer blk_len;
2236 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002237 var GprsMS ms;
2238
2239 /* Initialize NS/BSSGP side */
2240 f_init_bssgp();
2241 /* Initialize GPRS MS side */
2242 f_init_gprs_ms();
2243 ms := g_ms[0]; /* We only use first MS in this test */
2244
2245 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002246 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002247
2248 /* Establish BSSGP connection to the PCU */
2249 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002250 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002251
2252 /* Establish an Uplink TBF */
2253 f_ms_establish_ul_tbf(ms);
2254
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002255 /* Wait until PCU starts requesting for UL block on this TBF: */
2256 f_ms_wait_usf(ms);
2257
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002258 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002259 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002260 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002261 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2262 more := false, e := true);
2263 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002264 /* 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 +01002265 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2266 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002267 cv := 15,
2268 bsn := ms.ul_tbf.bsn,
2269 blocks := blocks,
2270 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002271 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002272 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002273
2274 /* ACK and check it was received fine */
2275 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2276 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2277 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2278 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002279 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 +02002280
2281 /* Test sending LLC PDUS of incrementing size */
2282 var integer max_size := 49;
2283 for (var integer i := 1; i <= max_size; i := i + 1) {
2284 var integer cv;
2285 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2286 log("Sending DATA.ind with LLC payload size ", i);
2287 if (i < max_size - g_bs_cv_max) {
2288 cv := 15;
2289 } else {
2290 cv := max_size - i;
2291 }
2292
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002293 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2294 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002295 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002296 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2297 more := false, e := true);
2298 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002299 /* 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 +01002300 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2301 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002302 cv := cv,
2303 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002304 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002305 f_ultbf_inc_bsn(ms.ul_tbf);
2306 f_ms_tx_ul_block(ms, ul_data);
2307
2308 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002309 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 +02002310
2311 /* we will receive UL ACK/NACK from time to time, handle it. */
2312 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002313 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002314 continue;
2315 }
2316 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2317 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2318 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2319 f_shutdown(__BFILE__, __LINE__);
2320 }
2321
2322 log("Rx Packet Uplink ACK / NACK");
2323 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2324 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2325 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2326 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002327
2328 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002329}
2330
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002331function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2332 var octetstring payload;
2333 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002334 var template (value) LlcBlockHdr blk_hdr;
2335 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002336 var integer block_len, max_valid_data_len;
2337 timer T;
2338
2339 block_len := f_rlcmac_cs_mcs2block_len(cs);
2340 /* We need to send with TLLI since we are in One-Phase Access Contenion
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002341 * resolution), so that's -4 bytes of data, -3 for headers, -1 for LI
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002342 * indicator, -1 for spare bits octet at the end */
2343 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2344 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 +07002345 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2346 more := false, e := true);
2347 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002348 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2349 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002350 cv := cv,
2351 bsn := ms.ul_tbf.bsn,
2352 blocks := blocks,
2353 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002354 f_ultbf_inc_bsn(ms.ul_tbf);
2355 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2356
2357 T.start(0.5);
2358 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002359 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002360 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2361 f_shutdown(__BFILE__, __LINE__);
2362 }
2363 [] T.timeout {
2364 setverdict(pass);
2365 }
2366 }
2367}
2368/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2369 blocks intentionally contain last byte of data placed in last byte of RLC
2370 containing padding/spare bits, which is incorrect. Spare bits exist and are
2371 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2372 discounting padding in octet" */
2373testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2374 var GprsMS ms;
2375 var integer block_len, max_valid_data_len;
2376
2377 /* Initialize NS/BSSGP side */
2378 f_init_bssgp();
2379 /* Initialize GPRS MS side */
2380 f_init_gprs_ms();
2381 ms := g_ms[0]; /* We only use first MS in this test */
2382
2383 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002384 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002385
2386 /* Establish BSSGP connection to the PCU */
2387 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002388 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002389
2390 /* Establish an Uplink TBF */
2391 f_ms_establish_ul_tbf(ms);
2392
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002393 /* Wait until PCU starts requesting for UL block on this TBF: */
2394 f_ms_wait_usf(ms);
2395
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002396 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2397 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2398 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2399
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002400 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002401}
2402
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002403/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2404 * answered, so TBFs for uplink and later for downlink are created.
2405 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002406private 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 +02002407 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002408 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002409 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002410 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002411 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002412
2413 /* Initialize NS/BSSGP side */
2414 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002415 /* Initialize GPRS MS side */
2416 f_init_gprs_ms();
2417 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002418
2419 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002420 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002421
2422 /* Establish BSSGP connection to the PCU */
2423 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002424 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002425
2426 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002427 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002428
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002429 /* Wait until PCU starts requesting for UL block on this TBF: */
2430 f_ms_wait_usf(ms);
2431
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002432 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002433 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002434 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 +02002435 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2436 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002437 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002438
2439 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002440 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002441
2442 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002443 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002444 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002445
2446 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2447 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002448 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002449
2450 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002451 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2452 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2453 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002454
2455 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002456}
2457
2458/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2459 * answered, so TBFs for uplink and later for downlink are created.
2460 */
2461testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002462 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002463 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002464}
2465
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002466/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2467 * answered, so TBFs for uplink and later for downlink are created.
2468 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002469private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2470 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002471 template (present) CodingScheme exp_ul_cs_mcs := ?,
2472 template (present) CodingScheme exp_dl_cs_mcs := ?)
2473runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002474 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002475 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002476 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002477 var uint32_t sched_fn;
2478 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002479 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002480 var GprsMS ms;
2481
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002482 /* Initialize NS/BSSGP side */
2483 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002484 /* Initialize GPRS MS side */
2485 f_init_gprs_ms();
2486 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002487
2488 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002489 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002490
2491 /* Establish BSSGP connection to the PCU */
2492 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002493 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002494
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002495 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2496 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 +02002497
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002498 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2499 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 +02002500 f_shutdown(__BFILE__, __LINE__);
2501 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002502
2503 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2504 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002505 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002506
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002507 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002508 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 +02002509
2510 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002511 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002512
2513 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002514 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002515 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2516 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002517 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002518 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002519 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002520
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002521 /* PCU acks the UL data after having received CV=0) */
2522 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2523
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002524 /* 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 +02002525 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 +02002526
2527 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002528 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2529 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 +02002530 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002531
2532 f_shutdown(__BFILE__, __LINE__, final := true);
2533}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002534
2535testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002536 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2537 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002538
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002539 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 +01002540
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002541 var StatsDExpects expect := {
2542 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2543 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2544 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2545 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2546 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2547 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2548 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2549 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2550 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2551 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2552 };
2553 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002554
2555 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002556}
2557
2558testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002559 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2560 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002561
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002562 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 +01002563
2564 var StatsDExpects expect := {
2565 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2566 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2567 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2568 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2569 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2570 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2571 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2572 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2573 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2574 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2575 };
2576 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002577
2578 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002579}
2580
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002581testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2582 /* Configure PCU to force two phase access */
2583 g_force_two_phase_access := true;
2584
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002585 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002586 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002587
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002588 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 +01002589
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002590 var StatsDExpects expect := {
2591 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2592 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2593 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2594 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2595 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2596 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2597 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2598 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2599 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2600 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2601 };
2602 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002603
2604 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002605}
2606
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002607/* Test scenario where SGSN wants to send some data against MS and it is
2608 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2609 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002610private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2611 template (present) CodingScheme exp_cs_mcs := ?)
2612runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002613 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002614 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002615 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002616 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002617 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002618
2619 /* Initialize NS/BSSGP side */
2620 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002621 /* Initialize GPRS MS side */
2622 f_init_gprs_ms();
2623 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002624
2625 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002626 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002627
2628 /* Establish BSSGP connection to the PCU */
2629 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002630 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002631
2632 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002633 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 +02002634 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002635
2636 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2637 f_sleep(X2002);
Pau Espin Pedrol3f2b5e42022-11-29 14:54:34 +01002638 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2639 dl_fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
2640
2641 f_rlcmac_dl_block_exp_data(dl_block, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002642
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002643 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002644 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2645 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 +02002646 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002647
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002648 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002649 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002650
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002651 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002652 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002653 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002654 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2655 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002656 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002657
2658 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002659 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002660
2661 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002662}
2663
2664testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002665 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002666 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2667}
2668
2669/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2670/* information about the MS */
2671testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002672 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002673 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002674}
2675
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002676/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2677 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2678 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2679 * be transferred).
2680 */
2681testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002682 var RlcmacDlBlock dl_block;
2683 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002684 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002685 var octetstring total_payload;
2686 var octetstring payload;
2687 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002688 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002689 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002690 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002691
2692 /* Initialize NS/BSSGP side */
2693 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002694 /* Initialize GPRS MS side */
2695 f_init_gprs_ms();
2696 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002697
2698 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002699 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002700
2701 /* Establish BSSGP connection to the PCU */
2702 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002703 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002704
2705 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002706 f_ms_establish_ul_tbf(ms);
2707 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002708
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002709 /* Wait until PCU starts requesting for UL block on this TBF: */
2710 f_ms_wait_usf(ms);
2711
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002712 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002713 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002714 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 +02002715 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 +02002716
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002717 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2718 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002719 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002720 total_payload := payload;
2721
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002722 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2723
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002724 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002725 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002726 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002727 total_payload := total_payload & payload;
2728
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002729 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002730 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002731 total_payload := total_payload & payload;
2732
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002733 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002734 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 +02002735 total_payload := total_payload & lost_payload;
2736
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002737 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002738 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002739 total_payload := total_payload & payload;
2740
2741 /* 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 +02002742 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002743
2744 /* On CV=0, we'll receive a UL ACK asking about missing block */
2745 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2746 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002747 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2748 tfi := tfi,
2749 cv := 15,
2750 bsn := 3,
2751 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002752 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002753
2754 /* Now final ack is recieved */
2755 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2756 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002757 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002758
2759 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002760 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 +07002761
2762 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002763}
2764
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002765/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2766 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2767 * timeout occurs (specified by sent RRBP on DL block). */
2768testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002769 var RlcmacDlBlock dl_block;
2770 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002771 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002772 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002773
2774 /* Initialize NS/BSSGP side */
2775 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002776 /* Initialize GPRS MS side */
2777 f_init_gprs_ms();
2778 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002779
2780 /* Initialize the PCU interface abstraction */
2781 f_init_raw(testcasename());
2782
2783 /* Establish BSSGP connection to the PCU */
2784 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002785 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002786
2787 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002788 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002789 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002790
2791 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2792 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002793 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002794
2795 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2796 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2797 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002798 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002799
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002800 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2801 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002802 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002803
2804 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002805 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2806 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2807 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002808
2809 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002810}
2811
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002812/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2813testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2814 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2815 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002816 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002817 var RlcmacDlBlock dl_block;
2818 var uint32_t ack_fn;
2819 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002820 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002821 timer T := 5.0;
2822
2823 /* Initialize NS/BSSGP side */
2824 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002825 /* Initialize GPRS MS side */
2826 f_init_gprs_ms();
2827 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002828
2829 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002830 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002831
Daniel Willmann535aea62020-09-21 13:27:08 +02002832 f_statsd_reset();
2833
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002834 /* Establish BSSGP connection to the PCU */
2835 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002836 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002837
2838 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02002839 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02002840 f_ms_exp_dl_tbf_ass_ccch(ms);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002841
2842 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2843 f_sleep(X2002);
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002844 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2845 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002846
2847 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002848 f_rlcmac_dl_block_exp_data(dl_block, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002849 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002850
2851 /* TDMA frame number on which we are supposed to send the ACK */
2852 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2853
2854 /* SGSN sends more blocks during the indicated RRBP */
2855 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2856 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002857 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002858
2859 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2860
2861 /* Make sure this block has the same TFI as was assigned
2862 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002863 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002864 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2865 dl_block.data.mac_hdr.hdr_ext.tfi);
2866 f_shutdown(__BFILE__, __LINE__);
2867 }
2868
2869 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002870 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002871
2872 /* Break if this is the end of RRBP */
2873 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002874 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002875 break;
2876 }
2877 }
2878
2879 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002880 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 +07002881
2882 /* Make sure that the next block (after the Ack) is dummy */
2883 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2884
Daniel Willmann535aea62020-09-21 13:27:08 +02002885 var StatsDExpects expect := {
2886 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2887 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2888 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2889 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2890 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002891 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002892 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2893 };
2894 f_statsd_expect(expect);
2895
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002896 f_shutdown(__BFILE__, __LINE__, final := true);
2897}
2898
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002899/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2900 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2901 * Check "3GPP TS 44.060" Annex B. */
2902testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2903 var RlcmacDlBlock dl_block;
2904 var octetstring dataA := f_rnd_octstring(20);
2905 var octetstring dataB := f_rnd_octstring(13);
2906 var octetstring dataC := f_rnd_octstring(3);
2907 var octetstring dataD := f_rnd_octstring(12);
2908 var uint32_t sched_fn;
2909 var GprsMS ms;
2910 var template (value) RlcmacUlBlock ul_data;
2911
2912 /* Initialize NS/BSSGP side */
2913 f_init_bssgp();
2914 /* Initialize GPRS MS side */
2915 f_init_gprs_ms();
2916 ms := g_ms[0]; /* We only use first MS in this test */
2917
2918 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002919 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002920
2921 /* Establish BSSGP connection to the PCU */
2922 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002923 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002924
2925 /* Establish an Uplink TBF */
2926 f_ms_establish_ul_tbf(ms);
2927
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02002928 /* Wait until PCU starts requesting for UL block on this TBF: */
2929 f_ms_wait_usf(ms);
2930
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002931 /* Summary of what's transmitted:
2932 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2933 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2934 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2935 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2936 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2937 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2938 */
2939
2940 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002941 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2942 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002943 cv := 3,
2944 bsn := ms.ul_tbf.bsn,
2945 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2946 tlli := ms.tlli);
2947 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2948 * RLCMAC block being sent. */
2949 ul_data.data.mac_hdr.e := true;
2950 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002951 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002952
2953 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002954 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2955 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002956 cv := 2,
2957 bsn := ms.ul_tbf.bsn,
2958 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2959 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2960 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2961 },
2962 tlli := ms.tlli);
2963 f_ultbf_inc_bsn(ms.ul_tbf);
2964 f_ms_tx_ul_block(ms, ul_data);
2965
2966 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002967 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 +02002968
2969 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002970 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2971 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002972 cv := 1,
2973 bsn := ms.ul_tbf.bsn,
2974 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2975 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2976 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2977 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2978 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2979 },
2980 tlli := ms.tlli);
2981 f_ultbf_inc_bsn(ms.ul_tbf);
2982 f_ms_tx_ul_block(ms, ul_data);
2983
2984 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002985 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2986 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 +02002987
2988 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002989 ul_data := t_RLCMAC_UL_DATA_TLLI(
2990 cs := CS_1,
2991 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002992 cv := 0,
2993 bsn := ms.ul_tbf.bsn,
2994 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2995 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2996 },
2997 tlli := ms.tlli);
2998 f_ultbf_inc_bsn(ms.ul_tbf);
2999 f_ms_tx_ul_block(ms, ul_data);
3000
3001 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003002 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 +02003003
3004 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3005 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3006 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3007
3008 f_shutdown(__BFILE__, __LINE__, final := true);
3009}
3010
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003011/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
3012 * ACK/NACK is not answered */
3013testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
3014 var RlcmacDlBlock dl_block;
3015 var octetstring data1 := f_rnd_octstring(200);
3016 var octetstring data2 := f_rnd_octstring(10);
3017 var uint32_t dl_fn;
3018 var GprsMS ms;
3019 var template (value) TsTrxBtsNum nr;
3020 var BTS_PDTCH_Block data_msg;
3021
3022 /* Initialize NS/BSSGP side */
3023 f_init_bssgp();
3024 /* Initialize GPRS MS side */
3025 f_init_gprs_ms();
3026 ms := g_ms[0]; /* We only use first MS in this test */
3027
3028 /* Initialize the PCU interface abstraction */
3029 f_init_raw(testcasename())
3030
3031 /* Establish BSSGP connection to the PCU */
3032 f_bssgp_establish();
3033 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3034
3035 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02003036 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003037 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003038
3039 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3040 f_sleep(X2002);
3041
3042 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
3043 while (true) {
3044 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3045
3046 /* Keep Ack/Nack description updated (except for last BSN) */
3047 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3048
3049 if (f_dl_block_rrbp_valid(dl_block)) {
3050 /* Don't transmit DL ACK here on purpose ignore it */
3051 break;
3052 }
3053 }
3054
3055 /* PCU starts whole process again */
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003056 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003057
3058 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3059 f_sleep(X2002);
3060
3061 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
3062 /* DL data), after that we receive only DUMMY blocks so we are done */
3063 var boolean data_received := false;
3064 nr := ts_TsTrxBtsNum;
3065 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3066 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3067 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3068 block_nr := nr.blk_nr));
3069 alt {
3070 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3071 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003072 tr_RLCMAC_DL_DUMMY_CTRL)) { /* done */ }
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003073 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3074 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3075 tr_RLCMAC_DATA)) -> value data_msg {
3076 data_received := true;
3077 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3078 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3079 log("Received FINAL_ACK");
3080 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3081 }
3082 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3083 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3084 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3085 }
3086 nr := ts_TsTrxBtsNum;
3087 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3088 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3089 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3090 block_nr := nr.blk_nr));
3091 repeat;
3092 }
3093 [] BTS.receive {
3094 setverdict(fail, "Unexpected BTS message");
3095 f_shutdown(__BFILE__, __LINE__);
3096 }
3097 }
3098
3099 f_shutdown(__BFILE__, __LINE__, final := true);
3100}
3101
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003102/* OS#5508: Verify scheduling of LLC frames with SAPI=1 (GMM) takes precedence
3103 * over SAPI2/7/8 which in turn take prececende over others */
3104testcase TC_dl_llc_sapi_priority() runs on RAW_PCU_Test_CT {
3105 var octetstring data_sapi1 := f_pad_oct('01'O, 19, 'ff'O);
3106 var octetstring data_sapi2 := f_pad_oct('02'O, 19, 'ff'O);
3107 var octetstring data_sapi7 := f_pad_oct('07'O, 19, 'ff'O);
3108 var octetstring data_sapi8 := f_pad_oct('08'O, 19, 'ff'O);
3109 var octetstring data_sapi_other := f_pad_oct('03'O, 19, 'ff'O);
3110 var RlcmacDlBlock dl_block;
3111 var uint32_t dl_fn;
3112 var GprsMS ms;
3113 var integer state := 1;
3114
3115 /* Initialize NS/BSSGP side */
3116 f_init_bssgp();
3117 /* Initialize GPRS MS side */
3118 f_init_gprs_ms();
3119 ms := g_ms[0]; /* We only use first MS in this test */
3120
3121 /* Initialize the PCU interface abstraction */
3122 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3123
3124 /* Lock to CS1 to keep same DL RLCMAC data block size: */
3125 g_cs_initial_dl := 1;
3126 g_mcs_max_dl := 1;
3127 f_pcuvty_set_allowed_cs_mcs();
3128
3129 /* Establish BSSGP connection to the PCU */
3130 f_bssgp_establish();
3131 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3132
3133 /* SGSN sends some low prio DL data, PCU will page on CCCH (PCH) */
3134 for (var integer i := 0; i < 10; i := i + 1) {
Philipp Maier1ec31b32023-09-22 12:59:10 +02003135 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 +02003136 }
Philipp Maier7f064e62023-09-22 16:38:19 +02003137 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi2, imsi := ts_BSSGP_IMSI(ms.imsi)));
3138 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi7, imsi := ts_BSSGP_IMSI(ms.imsi)));
3139 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi8, imsi := ts_BSSGP_IMSI(ms.imsi)));
3140 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi1, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02003141 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003142
3143 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3144 f_sleep(X2002);
3145
3146 while (state != 0) {
3147 var OCT1 rx_sapi;
3148 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3149 rx_sapi := dl_block.data.blocks[0].payload[0];
3150
3151 select (state) {
3152 case(1) { /* We expect the first GMM LLC frame here (SAPI=1, highest prio) */
3153 if (rx_sapi != '01'O) {
3154 setverdict(fail, "Wrong prio: Expected LLC SAPI 1 (GMM) but got ", rx_sapi);
3155 f_shutdown(__BFILE__, __LINE__);
3156 }
3157 state := 2;
3158 }
3159 case(2) { /* We expect the second LLC frame here (SAPI=2, middle prio) */
3160 if (rx_sapi != '02'O) {
3161 setverdict(fail, "Wrong prio: Expected LLC SAPI 2 but got ", rx_sapi);
3162 f_shutdown(__BFILE__, __LINE__);
3163 }
3164 state := 7;
3165 }
3166 case(7) { /* We expect the third LLC frame here (SAPI=7, middle prio) */
3167 if (rx_sapi != '07'O) {
3168 setverdict(fail, "Wrong prio: Expected LLC SAPI 7 but got ", rx_sapi);
3169 f_shutdown(__BFILE__, __LINE__);
3170 }
3171 state := 8;
3172 }
3173 case(8) { /* We expect the fourth LLC frame here (SAPI=8, middle prio) */
3174 if (rx_sapi != '08'O) {
3175 setverdict(fail, "Wrong prio: Expected LLC SAPI 8 but got ", rx_sapi);
3176 f_shutdown(__BFILE__, __LINE__);
3177 }
3178 state := 3;
3179 }
3180 case(3) { /* We expect the other LLC frame here (SAPI=3, lower prio) */
3181 if (rx_sapi != '03'O) {
3182 setverdict(fail, "Wrong prio: Expected LLC SAPI 3 but got ", rx_sapi);
3183 f_shutdown(__BFILE__, __LINE__);
3184 }
3185 state := 0; /* Done, break */
3186 }
3187 }
3188 /* Keep Ack/Nack description updated (except for last BSN) */
3189 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3190
3191 if (f_dl_block_rrbp_valid(dl_block)) {
3192 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3193 f_dl_block_ack_fn(dl_block, dl_fn));
3194 }
3195 }
3196
3197 f_shutdown(__BFILE__, __LINE__, final := true);
3198}
3199
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003200/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3201testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003202 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003203 var octetstring data := f_rnd_octstring(10);
3204 var PacketDlAssign dl_tbf_ass;
3205 var RlcmacDlBlock dl_block;
3206 var uint32_t poll_fn;
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003207 var uint32_t dl_fn;
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003208 var uint32_t sched_fn;
3209 var GprsMS ms;
3210 timer T := 5.0;
3211
3212 /* Initialize NS/BSSGP side */
3213 f_init_bssgp();
3214 /* Initialize GPRS MS side */
3215 f_init_gprs_ms();
3216 ms := g_ms[0]; /* We only use first MS in this test */
3217
3218 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003219 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3220 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003221
3222 /* Initialize the PCU interface abstraction */
3223 f_init_raw(testcasename(), info_ind);
3224
3225 /* Establish BSSGP connection to the PCU */
3226 f_bssgp_establish();
3227 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3228
3229 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3230 through PDCH (no multiblock assignment possible through PCH) */
3231 f_ms_establish_ul_tbf(ms);
3232
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003233 /* Wait until PCU starts requesting for UL block on this TBF: */
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003234 dl_fn := f_ms_wait_usf(ms, nr := f_ms_tx_TsTrxBtsNum(ms));
3235 sched_fn := f_next_pdch_block(dl_fn);
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003236
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003237 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003238 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol1de8df72023-07-28 16:23:48 +02003239 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := sched_fn,
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003240 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003241 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3242 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3243
3244 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3245 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3246 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3247 gprsextendeddynalloccap := '0'B
3248 };
3249 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3250 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3251 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3252 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3253 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3254 f_shutdown(__BFILE__, __LINE__);
3255 }
3256 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3257
3258 f_shutdown(__BFILE__, __LINE__, final := true);
3259}
3260
Pau Espin Pedrol85ad3d02023-07-28 15:00:19 +02003261/* Test DL TBF assignment over PACCH if Multislot class is unknown both at PCU
3262 * and SGSN (eg. because MS started 1-phase access and SGSN answered back).
3263 * Since the msclass is unknown, it shouldn't assign multiple timeslots since
3264 * the MS may not support it. Related OS#6118. */
3265testcase TC_dl_multislot_tbf_ms_class_unknown() runs on RAW_PCU_Test_CT
3266{
3267 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3268 var RlcmacDlBlock dl_block;
3269 var octetstring payload;
3270 var template (value) LlcBlockHdr blk_hdr;
3271 var template (value) LlcBlocks blocks;
3272 var uint32_t sched_fn;
3273 var uint32_t dl_fn;
3274 var template RlcmacDlBlock acknack_tmpl;
3275 var GprsMS ms;
3276 var octetstring data := f_rnd_octstring(10);
3277
3278 /* Initialize NS/BSSGP side */
3279 f_init_bssgp();
3280
3281 /* Only 1 TRX with 8 PDCH */
3282 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3283 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
3284
3285 /* Initialize GPRS MS side */
3286 f_init_gprs_ms();
3287 ms := g_ms[0]; /* We only use first MS in this test */
3288
3289 /* Initialize the PCU interface abstraction */
3290 f_init_raw(testcasename(), info_ind);
3291
3292 /* Establish BSSGP connection to the PCU */
3293 f_bssgp_establish();
3294 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3295
3296 /* Establish an Uplink TBF. 1 TS is assigned over AGCH. */
3297 f_ms_establish_ul_tbf(ms);
3298
3299 /* Wait until PCU starts requesting for UL block on this TBF: */
3300 dl_fn := f_ms_wait_usf(ms, nr := f_ms_tx_TsTrxBtsNum(ms));
3301 sched_fn := f_next_pdch_block(dl_fn);
3302
3303 /* Send one UL block (with TLLI since we are in One-Phase Access
3304 * contention resolution) and make sure it is ACKED fine. */
3305 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
3306 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
3307 more := false, e := true);
3308 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
3309 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
3310 f_ms_tx_ul_data_blocks_gprs(ms, blocks, cv := 15, with_tlli := true, fn := sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3311
3312 /* UL block should be received in SGSN */
3313 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3314
3315 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3316 tr_UlAckNackGprs(ms.tlli,
3317 tr_AckNackDescription(final_ack := '0'B)))
3318 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl, nr := f_ms_tx_TsTrxBtsNum(ms));
3319
3320 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap := omit));
3321 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3322 if (f_dltbf_num_slots(ms.dl_tbf) != 1) {
3323 setverdict(fail, "Expected 1 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3324 f_shutdown(__BFILE__, __LINE__);
3325 }
3326
3327 f_shutdown(__BFILE__, __LINE__, final := true);
3328}
3329
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003330testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003331 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003332 var RlcmacDlBlock dl_block;
3333 var octetstring data := f_rnd_octstring(10);
3334 var PollFnCtx pollctx;
3335 var uint32_t sched_fn;
3336 var GprsMS ms;
3337
3338 var MultislotCap_GPRS mscap_gprs := {
3339 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3340 gprsextendeddynalloccap := '0'B
3341 };
3342 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3343
3344
3345 /* Initialize NS/BSSGP side */
3346 f_init_bssgp();
3347 /* Initialize GPRS MS side */
3348 f_init_gprs_ms();
3349 ms := g_ms[0]; /* We only use first MS in this test */
3350
3351 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003352 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3353 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003354
3355 /* Initialize the PCU interface abstraction */
3356 f_init_raw(testcasename(), info_ind);
3357
3358 /* Establish BSSGP connection to the PCU */
3359 f_bssgp_establish();
3360 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3361
3362 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3363 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3364
3365 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3366 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3367
3368 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3369 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3370 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3371 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3372 f_shutdown(__BFILE__, __LINE__);
3373 }
3374 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3375
3376 f_shutdown(__BFILE__, __LINE__, final := true);
3377}
3378
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003379testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3380 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3381 var RlcmacDlBlock dl_block;
3382 var octetstring data := f_rnd_octstring(10);
3383 var PollFnCtx pollctx;
3384 var uint32_t sched_fn;
3385 var GprsMS ms;
3386
3387 var MultislotCap_GPRS mscap_gprs := {
3388 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3389 gprsextendeddynalloccap := '0'B
3390 };
3391 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3392
3393
3394 /* Initialize NS/BSSGP side */
3395 f_init_bssgp();
3396 /* Initialize GPRS MS side */
3397 f_init_gprs_ms();
3398 ms := g_ms[0]; /* We only use first MS in this test */
3399
3400 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003401 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3402 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003403
3404 /* Initialize the PCU interface abstraction */
3405 f_init_raw(testcasename(), info_ind);
3406
3407 /* Establish BSSGP connection to the PCU */
3408 f_bssgp_establish();
3409 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3410
3411 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3412 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3413
3414 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3415 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3416 f_shutdown(__BFILE__, __LINE__);
3417 }
3418
3419 f_shutdown(__BFILE__, __LINE__, final := true);
3420}
3421
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003422/* Test scenario where MS wants to request a new TBF once the current one is
3423 * ending, by means of sending a Packet Resource Request on ul slot provided by
3424 * last Pkt Ul ACK's RRBP.
3425 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3426testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003427 var RlcmacDlBlock dl_block;
3428 var octetstring data := f_rnd_octstring(10);
3429 var uint32_t sched_fn;
3430 var uint32_t dl_fn;
3431 var template RlcmacDlBlock acknack_tmpl;
3432 var GprsMS ms;
3433
3434 /* Initialize NS/BSSGP side */
3435 f_init_bssgp();
3436 /* Initialize GPRS MS side */
3437 f_init_gprs_ms();
3438 ms := g_ms[0]; /* We only use first MS in this test */
3439
3440 /* Initialize the PCU interface abstraction */
3441 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003442 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003443
3444 /* Establish BSSGP connection to the PCU */
3445 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003446 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003447
3448 /* Establish an Uplink TBF */
3449 f_ms_establish_ul_tbf(ms);
3450
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003451 /* Wait until PCU starts requesting for UL block on this TBF: */
3452 f_ms_wait_usf(ms);
3453
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003454 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003455 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003456 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 +02003457
3458 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003459 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003460
3461 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3462 tr_UlAckNackGprs(ms.tlli,
3463 tr_AckNackDescription(final_ack := '1'B),
3464 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3465 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3466
3467 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3468
3469 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003470 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 +07003471 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003472 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3473 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3474
3475 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3476 and make sure it is ACKED fine */
3477 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3478
3479 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003480 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003481
3482 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3483 /* ACK the ACK */
3484 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3485
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003486 var StatsDExpects expect := {
3487 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3488 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3489 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3490 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3491 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3492 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3493 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3494 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3495 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3496 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3497 };
3498 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003499
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003500 f_shutdown(__BFILE__, __LINE__, final := true);
3501}
3502
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003503/* Test scenario where MS wants to request a new TBF once the current one is
3504 * ending, by means of sending a Packet Resource Request on ul slot provided by
3505 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3506 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003507testcase TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() runs on RAW_PCU_Test_CT {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003508 var PCUIF_info_ind info_ind;
3509 var RlcmacDlBlock dl_block;
3510 var octetstring data := f_rnd_octstring(10);
3511 var uint32_t sched_fn;
3512 var uint32_t dl_fn;
3513 var template (value) TsTrxBtsNum nr;
3514 var BTS_PDTCH_Block data_msg;
3515 var template RlcmacDlBlock acknack_tmpl;
3516 var GprsMS ms;
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003517 var integer cnt_rrbp := 0;
3518 var integer cnt_dummy_after_timeout := 0;
3519 /* Maximum T3168 value = 8 * 500 ms = 4s => * 4 retrans = 16s */
3520 timer T_3168 := 16.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003521
3522 /* Initialize NS/BSSGP side */
3523 f_init_bssgp();
3524 /* Initialize GPRS MS side */
3525 f_init_gprs_ms();
3526 ms := g_ms[0]; /* We only use first MS in this test */
3527
3528 /* Initialize the PCU interface abstraction */
3529 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003530 /* TODO: Speedup test by sending a PCU_IF_SAPI_BCCH SI13 with T3168=0 (500ms) */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003531 f_init_raw(testcasename(), info_ind);
3532
3533 /* Establish BSSGP connection to the PCU */
3534 f_bssgp_establish();
3535 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3536
3537 /* Establish an Uplink TBF */
3538 f_ms_establish_ul_tbf(ms);
3539
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003540 /* Wait until PCU starts requesting for UL block on this TBF: */
3541 f_ms_wait_usf(ms);
3542
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003543 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003544 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003545 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3546
3547 /* UL block should be received in SGSN */
3548 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3549
3550 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3551 tr_UlAckNackGprs(ms.tlli,
3552 tr_AckNackDescription(final_ack := '1'B),
3553 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3554 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3555
3556 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3557
3558 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003559 T_3168.start;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003560 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3561
3562 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3563 /* Now we go on receiving DL data and not answering RRBP: */
3564 nr := ts_TsTrxBtsNum;
3565 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3566 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3567 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3568 block_nr := nr.blk_nr));
3569 alt {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003570 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003571 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3572 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003573 /* We should not be receiving PKT UL ASS anymore after T3168 timeout */
3574 if (not T_3168.running) {
3575 setverdict(fail, log2str("Unexpected PKT UL ASS after T3168 timeout: ", data_msg));
3576 f_shutdown(__BFILE__, __LINE__);
3577 }
3578
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003579 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003580 log("Ignoring RRBP ", cnt_rrbp);
3581 cnt_rrbp := cnt_rrbp + 1;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003582 }
3583 nr := ts_TsTrxBtsNum;
3584 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3585 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3586 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3587 block_nr := nr.blk_nr));
3588 repeat;
3589 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003590 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003591 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003592 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003593 nr := ts_TsTrxBtsNum;
3594 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3595 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3596 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3597 block_nr := nr.blk_nr));
3598 repeat;
3599 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003600 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003601 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3602 omit)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003603
3604 /* T3168 expired and we are not receiving blocks anymore, meaning PCU released the TBF. */
3605 break;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003606 }
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003607 [] BTS.receive {
3608 setverdict(fail, "Unexpected BTS message");
3609 f_shutdown(__BFILE__, __LINE__);
3610 }
3611 }
3612
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003613 /* Check that we received at least a few PKT UL ASS before T3168 expiration */
3614 if (cnt_rrbp <= 3) {
3615 setverdict(fail, log2str("Received only ", cnt_rrbp, " before T3168 timeout!"));
3616 f_shutdown(__BFILE__, __LINE__);
3617 }
3618
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003619 f_shutdown(__BFILE__, __LINE__, final := true);
3620}
3621
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003622/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3623 * transmitted on ul slot provided by its DL TBF.
3624 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3625function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3626 var GprsMS ms;
3627 var octetstring data := f_rnd_octstring(10);
3628 var RlcmacDlBlock dl_block;
3629 var template RlcmacDlBlock rej_tmpl;
3630 var uint32_t dl_fn;
3631 var uint32_t sched_fn;
3632 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3633
3634 if (use_egprs == true) {
3635 racap_tmpl := bssgp_ms_racap_egprs_def;
3636 } else {
3637 racap_tmpl := bssgp_ms_racap_gprs_def;
3638 }
3639
3640 /* Initialize NS/BSSGP side */
3641 f_init_bssgp();
3642 /* Initialize GPRS MS side */
3643 f_init_gprs_ms();
3644 ms := g_ms[0]; /* We only use first MS in this test */
3645 /* Initialize the PCU interface abstraction */
3646 f_init_raw(testcasename());
3647
3648 /* Establish BSSGP connection to the PCU */
3649 f_bssgp_establish();
3650 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3651
3652 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02003653 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 +02003654 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003655
3656 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3657 f_sleep(X2002);
3658 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3659
3660 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3661 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3662 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3663 f_dl_block_ack_fn(dl_block, dl_fn));
3664
3665 /* We should receive a Pkt Ul ASS */
3666 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3667 f_shutdown(__BFILE__, __LINE__, final := true);
3668}
3669testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3670 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3671}
3672testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3673 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3674}
3675
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003676/* Test UL data blocks BSN 0..127 and then continue again at BSN 0... up to 300
3677 * BSNs in total to test several wrap arounds. */
3678testcase TC_ul_tbf_bsn_wraparound_gprs() runs on RAW_PCU_Test_CT
3679{
3680 var PCUIF_info_ind info_ind;
3681 var RlcmacDlBlock dl_block;
3682 var octetstring payload;
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003683 var template (value) LlcBlockHdr blk_hdr;
3684 var template (value) LlcBlocks blocks;
3685 var uint32_t sched_fn;
3686 var uint32_t dl_fn;
3687 var template (value) TsTrxBtsNum nr;
3688 var BTS_PDTCH_Block data_msg;
3689 var template RlcmacDlBlock acknack_tmpl;
3690 var GprsMS ms;
3691 var integer blocks_sent := 0;
3692 var integer blocks_received := 0;
3693 const integer target_bsn_set := 300;
3694
3695 /* Initialize NS/BSSGP side */
3696 f_init_bssgp();
3697 /* Initialize GPRS MS side */
3698 f_init_gprs_ms();
3699 ms := g_ms[0]; /* We only use first MS in this test */
3700
3701 /* Initialize the PCU interface abstraction */
3702 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3703 f_init_raw(testcasename(), info_ind);
3704
3705 /* Establish BSSGP connection to the PCU */
3706 f_bssgp_establish();
3707 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3708
3709 /* Establish an Uplink TBF */
3710 f_ms_establish_ul_tbf(ms);
3711
3712 /* Wait until PCU starts requesting for UL block on this TBF: */
3713 dl_fn := f_ms_wait_usf(ms);
3714 sched_fn := f_next_pdch_block(dl_fn);
3715
3716 /* Send one UL block (with TLLI since we are in One-Phase Access
3717 contention resolution) and make sure it is ACKED fine. */
3718 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
3719 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
3720 more := false, e := true);
3721 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
3722 /* 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 +02003723 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 +02003724 blocks_sent := blocks_sent + 1;
3725
3726 /* UL block should be received in SGSN */
3727 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3728
3729 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3730 tr_UlAckNackGprs(ms.tlli,
3731 tr_AckNackDescription(final_ack := '0'B)))
3732 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3733
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003734 nr := f_ms_tx_TsTrxBtsNum(ms);
3735 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3736 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3737 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3738 block_nr := nr.blk_nr));
3739 alt {
3740 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3741 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3742 tr_RLCMAC_UL_ACK_NACK_GPRS)) -> value data_msg {
3743
3744 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3745 var uint32_t ack_fn := f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn)
3746 log("ACKING FN ", data_msg.raw.fn, " on FN ", ack_fn);
3747 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), ack_fn);
3748 }
Pau Espin Pedrolbd849cc2023-07-28 14:54:46 +02003749 f_ms_tx_ul_data_blocks_gprs(ms, blocks);
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003750 blocks_sent := blocks_sent + 1;
3751
3752 if (blocks_sent == target_bsn_set) {
3753 break;
3754 }
3755
3756 nr := f_ms_tx_TsTrxBtsNum(ms);
3757 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3758 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3759 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3760 block_nr := nr.blk_nr));
3761 repeat;
3762 }
3763 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3764 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3765 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
3766
Pau Espin Pedrolbd849cc2023-07-28 14:54:46 +02003767 f_ms_tx_ul_data_blocks_gprs(ms, blocks);
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02003768 blocks_sent := blocks_sent + 1;
3769
3770 if (blocks_sent == target_bsn_set) {
3771 break;
3772 }
3773
3774 nr := f_ms_tx_TsTrxBtsNum(ms);
3775 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3776 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3777 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3778 block_nr := nr.blk_nr));
3779 repeat;
3780 }
3781 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3782 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3783 omit)) -> value data_msg {
3784 nr := f_ms_tx_TsTrxBtsNum(ms);
3785 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3786 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3787 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3788 block_nr := nr.blk_nr));
3789 repeat;
3790 }
3791 [] BTS.receive {
3792 setverdict(fail, "Unexpected BTS message");
3793 f_shutdown(__BFILE__, __LINE__);
3794 }
3795 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id)) {
3796 blocks_received := blocks_received + 1;
3797 repeat;
3798 }
3799 }
3800
3801 /* Validate most part of them were accepted and forwarded: */
3802 if (blocks_received < target_bsn_set * 95 / 100) {
3803 setverdict(fail, "Forwarded ", blocks_received, " out of ", target_bsn_set, " transmitted");
3804 f_shutdown(__BFILE__, __LINE__);
3805 }
3806 log("Forwarded ", blocks_received, " out of ", target_bsn_set, " transmitted");
3807
3808 f_shutdown(__BFILE__, __LINE__, final := true);
3809}
3810
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003811/* Test CS paging over the BTS<->PCU socket.
3812 * 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.
3813 * Paging should be send on the PACCH.
3814 *
3815 * 1. Send a Paging Request over PCU socket.
3816 * 2. Send a Ready-To-Send message over PCU socket
3817 * 3. Expect a Paging Frame
3818 */
3819testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003820 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003821 var MobileIdentityLV mi;
3822 var octetstring mi_enc_lv;
3823 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003824 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003825
3826 /* Initialize NS/BSSGP side */
3827 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003828 /* Initialize GPRS MS side */
3829 f_init_gprs_ms();
3830 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003831
3832 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003833 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003834
3835 /* Establish BSSGP connection to the PCU */
3836 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003837 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003838
3839 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003840 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003841
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003842 /* Wait until PCU starts requesting for UL block on this TBF: */
3843 f_ms_wait_usf(ms);
3844
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003845 /* build mobile Identity */
3846 mi := valueof(ts_MI_IMSI_LV(imsi));
3847 mi_enc_lv := enc_MobileIdentityLV(mi);
3848 /* Send paging request */
3849 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3850 sapi :=PCU_IF_SAPI_PDTCH));
3851
3852 /* Receive it on BTS side towards MS */
3853 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3854
3855 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003856 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3857 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3858 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3859 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003860
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003861 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003862}
3863
3864/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3865 */
3866private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3867runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003868 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003869 var hexstring imsi := f_gen_imsi(42);
3870 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003871 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003872
3873 /* Initialize NS/BSSGP side */
3874 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003875 /* Initialize GPRS MS side */
3876 f_init_gprs_ms();
3877 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003878
3879 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003880 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003881
3882 /* Establish BSSGP connection to the PCU */
3883 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003884 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003885
3886 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003887 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003888
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02003889 /* Wait until PCU starts requesting for UL block on this TBF: */
3890 f_ms_wait_usf(ms);
3891
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003892 /* Send paging request with or without TMSI */
3893 if (use_ptmsi) {
3894 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3895 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3896 } else {
3897 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3898 }
3899
Pau Espin Pedrol00fec582022-11-29 16:03:13 +01003900 /* Now receive it on BTS side towards MS.
3901 * Skip any dummy blocks in case the PCUIF req arrives before the BSSP CS_PAGING:
3902 */
3903 f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
3904
3905 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
3906 setverdict(fail, "Failed to match Packet Paging Request: ",
3907 dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
3908 f_shutdown(__BFILE__, __LINE__);
3909 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003910
3911 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003912 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003913 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003914 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3915 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3916 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003917 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003918 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3919 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3920 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003921 }
3922
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003923 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003924}
3925
3926testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3927 f_tc_paging_cs_from_sgsn(0, true);
3928}
3929
3930testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3931 f_tc_paging_cs_from_sgsn(0);
3932}
3933
3934testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003935 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003936}
3937
3938/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3939 */
3940private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3941runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003942 var integer imsi_suff_tx := 423;
3943 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003944 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003945
3946 /* Initialize NS/BSSGP side */
3947 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003948 /* Initialize GPRS MS side */
3949 f_init_gprs_ms();
3950 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003951
Oliver Smith61b4e732021-07-22 08:14:29 +02003952 f_statsd_reset();
3953
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003954 /* Establish BSSGP connection to the PCU */
3955 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003956 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003957
3958 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3959 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3960 if (use_ptmsi) {
3961 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3962 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3963 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3964 } else {
3965 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3966 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3967 }
3968
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003969 var StatsDExpects expect := {
3970 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3971 /* After the PCU receives the paging request from SGSN,
3972 * and it doesn't have any errors, PCU sends it to the
3973 * BTS to do paging over PCH. */
3974 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3975 };
3976 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003977}
3978
3979testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3980 /* Initialize the PCU interface abstraction */
3981 f_init_raw(testcasename());
3982
3983 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003984
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003985 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003986}
3987
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003988testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003989 /* Initialize the PCU interface abstraction */
3990 f_init_raw(testcasename());
3991
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003992 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003993
3994 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003995}
3996
3997testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003998 /* Initialize the PCU interface abstraction */
3999 f_init_raw(testcasename());
4000
Harald Welte5339b2e2020-10-04 22:52:56 +02004001 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02004002
4003 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004004}
4005
Oliver Smithe1a77c42021-07-28 13:36:09 +02004006testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
4007 /* Initialize the PCU interface abstraction */
4008 f_init_raw(testcasename());
4009
4010 /* Set T3113 to 1s to shorten the test duration */
4011 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
4012
4013 /* Reset stats and send paging PS request */
4014 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
4015
4016 /* Verify that counter increases when T3113 times out (MS did not start
4017 * TBF to respond to paging). */
4018 f_sleep(1.2);
4019 var StatsDExpects expect := {
4020 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
4021 };
4022 f_statsd_expect(expect);
4023
4024 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
4025 f_shutdown(__BFILE__, __LINE__, final := true);
4026}
4027
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004028/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
4029testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
4030 var RlcmacDlBlock dl_block;
4031 var octetstring data := f_rnd_octstring(10);
4032 var uint32_t sched_fn;
4033 var uint32_t dl_fn;
4034 var GprsMS ms;
4035
4036 /* Initialize NS/BSSGP side */
4037 f_init_bssgp();
4038 /* Initialize GPRS MS side */
4039 f_init_gprs_ms();
4040 ms := g_ms[0]; /* We only use first MS in this test */
4041
4042 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004043 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004044
Daniel Willmann535aea62020-09-21 13:27:08 +02004045 f_statsd_reset();
4046
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004047 /* Establish BSSGP connection to the PCU */
4048 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004049 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004050
4051 /* Establish an Uplink TBF */
4052 f_ms_establish_ul_tbf(ms);
4053
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004054 /* Wait until PCU starts requesting for UL block on this TBF: */
4055 f_ms_wait_usf(ms);
4056
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004057 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004058 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 +02004059 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4060 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4061 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4062
4063 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02004064 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004065
4066 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4067 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004068 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004069
4070 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
4071 f_sleep(X2002);
4072 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4073
4074 /* ACK the DL block */
4075 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
4076 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
4077 f_dl_block_ack_fn(dl_block, dl_fn));
4078
Daniel Willmann535aea62020-09-21 13:27:08 +02004079 var StatsDExpects expect := {
4080 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
4081 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
4082 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
4083 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01004084 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01004085 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02004086 };
4087 f_statsd_expect(expect);
4088
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004089 f_shutdown(__BFILE__, __LINE__, final := true);
4090}
4091
4092/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
4093testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
4094 var RlcmacDlBlock dl_block;
4095 var octetstring data := f_rnd_octstring(10);
4096 var uint32_t sched_fn;
4097 var uint32_t dl_fn;
4098 var GprsMS ms;
4099
4100 /* Initialize NS/BSSGP side */
4101 f_init_bssgp();
4102 /* Initialize GPRS MS side */
4103 f_init_gprs_ms();
4104 ms := g_ms[0]; /* We only use first MS in this test */
4105
4106 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004107 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004108
4109 /* Establish BSSGP connection to the PCU */
4110 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004111 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004112
4113 /* Establish an Uplink TBF */
4114 f_ms_establish_ul_tbf(ms);
4115
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004116 /* Wait until PCU starts requesting for UL block on this TBF: */
4117 f_ms_wait_usf(ms);
4118
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004119 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004120 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 +02004121 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4122 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4123 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4124
4125 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02004126 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004127
4128 /* Now SGSN sends some DL data with an invalid IMSI */
4129 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
4130
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01004131 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004132
4133 /* TODO: make sure no data is sent over PCU -> MS */
4134
4135 f_shutdown(__BFILE__, __LINE__, final := true);
4136}
4137
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004138private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
4139 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
4140 var octetstring data := f_rnd_octstring(6);
4141 var RlcmacDlBlock dl_block;
4142 var GprsMS ms;
4143 var uint32_t fn;
4144
4145 /* Initialize NS/BSSGP side */
4146 f_init_bssgp();
4147 /* Initialize GPRS MS side */
4148 f_init_gprs_ms();
4149 ms := g_ms[0]; /* We only use first MS in this test */
4150
4151 /* Initialize the PCU interface abstraction */
4152 f_init_raw(testcasename());
4153
4154 /* Establish BSSGP connection to the PCU */
4155 f_bssgp_establish();
4156 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4157
4158 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004159 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 +02004160 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004161
4162 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
4163 f_sleep(X2002);
4164
4165 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
4166 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
4167
4168 if (ischosen(dl_block.data_egprs)) {
4169 if (lengthof(dl_block.data_egprs.blocks) != 2) {
4170 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
4171 f_shutdown(__BFILE__, __LINE__);
4172 }
4173 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
4174 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
4175 f_shutdown(__BFILE__, __LINE__);
4176 }
4177 if (not match(dl_block.data_egprs.blocks[1].payload,
4178 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
4179 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
4180 f_shutdown(__BFILE__, __LINE__);
4181 }
4182 } else if (lengthof(dl_block.data.blocks) > 1) {
4183 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
4184 f_shutdown(__BFILE__, __LINE__);
4185 }
4186
4187 f_shutdown(__BFILE__, __LINE__, final := true);
4188}
4189
4190/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
4191 * containing llc data. See OS#4849 */
4192testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
4193 f_tc_dl_data_no_llc_ui_dummy(omit);
4194}
4195
4196/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
4197 * containing llc data. See OS#4849 */
4198testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004199 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004200}
4201
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004202/* Scenario: MS creates one phase access, does contention resolution CV>0 and
4203 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
4204 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
4205 * has to assign a DL TBF (through PCH because of FINISHED state, TS 44.060 9.3.3.3.2).
4206 * Make sure the assignment is not done until we receive the PKT CTRL ACK from the MS
4207 * (at that time we know the MS is listening on PCH again). OS#5700.
4208 */
4209testcase TC_ul_tbf_finished_pkt_dl_ass_pch() runs on RAW_PCU_Test_CT {
4210 var RlcmacDlBlock dl_block;
4211 var octetstring data := f_rnd_octstring(10);
4212 var uint32_t sched_fn;
4213 var uint32_t dl_fn;
4214 var GprsMS ms;
4215 timer T;
4216 var octetstring payload;
4217
4218 /* Initialize NS/BSSGP side */
4219 f_init_bssgp();
4220 /* Initialize GPRS MS side */
4221 f_init_gprs_ms();
4222 ms := g_ms[0]; /* We only use first MS in this test */
4223
4224 /* Initialize the PCU interface abstraction */
4225 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4226
4227 /* Establish BSSGP connection to the PCU */
4228 f_bssgp_establish();
4229 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4230
4231 /* Establish an Uplink TBF */
4232 f_ms_establish_ul_tbf(ms);
4233
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004234 /* Wait until PCU starts requesting for UL block on this TBF: */
4235 f_ms_wait_usf(ms);
4236
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004237 /* Send one UL block (with TLLI since we are in One-Phase Access
4238 contention resolution) and make sure it is ACKED fine. */
4239 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4240 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4241 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4242
4243 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4244 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4245 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4246 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4247
4248 /* 1 UL block should be received in SGSN */
4249 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4250 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004251 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004252
4253 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4254 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004255 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02004256 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
4257 f_sleep(X2002);
4258 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4259
4260 f_shutdown(__BFILE__, __LINE__, final := true);
4261}
4262
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004263/* Scenario: MS creates a UL TBF and
4264 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
4265 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
4266 * has to assign a DL TBF on PCH. While the network is waiting for the MS to
4267 * move to PDCH before transmitting DL data (timer X2002), the MS finds out it
4268 * needs to send new UL data and hence sends a RACH request to create a new UL
4269 * TBF.
4270 * Make sure the the MS is assigned a DL TBF through PACCH in that case even if
4271 * no new DL data is received from the SGSN. OS#5700.
4272 * This test validates the specific case where the 2nd UL TBF is done through
4273 * 1phase-access.
4274 */
4275testcase TC_ul_tbf_1phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4276 var RlcmacDlBlock dl_block;
4277 var octetstring data := f_rnd_octstring(10);
4278 var uint32_t sched_fn;
4279 var uint32_t poll_fn;
4280 var uint32_t dl_fn;
4281 var GprsMS ms;
4282 timer T;
4283 var octetstring payload;
4284
4285 /* Initialize NS/BSSGP side */
4286 f_init_bssgp();
4287 /* Initialize GPRS MS side */
4288 f_init_gprs_ms();
4289 ms := g_ms[0]; /* We only use first MS in this test */
4290
4291 /* Initialize the PCU interface abstraction */
4292 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4293
4294 /* Establish BSSGP connection to the PCU */
4295 f_bssgp_establish();
4296 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4297
4298 /* Establish an Uplink TBF */
4299 f_ms_establish_ul_tbf(ms);
4300
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004301 /* Wait until PCU starts requesting for UL block on this TBF: */
4302 f_ms_wait_usf(ms);
4303
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004304 /* Send one UL block (with TLLI since we are in One-Phase Access
4305 contention resolution) and make sure it is ACKED fine. */
4306 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4307 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4308 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4309
4310 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4311 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4312 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4313 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4314
4315 /* 1 UL block should be received in SGSN */
4316 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4317 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004318 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004319
4320 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4321 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004322 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004323
4324 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4325 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4326 f_ms_establish_ul_tbf(ms);
4327
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004328 /* Wait until PCU starts requesting for UL block on this TBF: */
4329 dl_fn := f_ms_wait_usf(ms);
4330
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004331 /* Send one UL block (with TLLI since we are in One-Phase Access
4332 * contention resolution) and make sure it is ACKED fine. */
4333 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004334 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4335
4336 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4337 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4338
4339 /* The PCU considers the MS to have gone over Contention Resolution
4340 * after having sent the first UL ACK/NACK to it, hence next it will try to
4341 * assign the DL-TBF to send the data it received from the SGSN previously: */
4342 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4343 /* the MS ACKs the PKT_DL_ASS: */
4344 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4345
4346 /* We should finally receive the DL-data that was received previously from the SGSN: */
4347 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4348
4349 f_shutdown(__BFILE__, __LINE__, final := true);
4350}
4351
4352/* Same as TC_ul_tbf_2phase_while_dl_ass_pch, but this test validates the
4353 * specific case where the 2nd UL TBF is done through 2phase-access. */
4354testcase TC_ul_tbf_2phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4355 var RlcmacDlBlock dl_block;
4356 var octetstring data := f_rnd_octstring(10);
4357 var uint32_t sched_fn;
4358 var uint32_t poll_fn;
4359 var uint32_t dl_fn;
4360 var GprsMS ms;
4361 timer T;
4362 var octetstring payload;
4363 var PollFnCtx pollctx;
4364
4365 /* Initialize NS/BSSGP side */
4366 f_init_bssgp();
4367 /* Initialize GPRS MS side */
4368 f_init_gprs_ms();
4369 ms := g_ms[0]; /* We only use first MS in this test */
4370
4371 /* Initialize the PCU interface abstraction */
4372 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4373
4374 /* Establish BSSGP connection to the PCU */
4375 f_bssgp_establish();
4376 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4377
4378 /* Establish an Uplink TBF */
4379 f_ms_establish_ul_tbf(ms);
4380
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004381 /* Wait until PCU starts requesting for UL block on this TBF: */
4382 f_ms_wait_usf(ms);
4383
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004384 /* Send one UL block (with TLLI since we are in One-Phase Access
4385 contention resolution) and make sure it is ACKED fine. */
4386 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4387 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4388 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4389
4390 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4391 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4392 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4393 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4394
4395 /* 1 UL block should be received in SGSN */
4396 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4397 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Philipp Maier1ec31b32023-09-22 12:59:10 +02004398 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004399
4400 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4401 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02004402 f_ms_exp_dl_tbf_ass_ccch(ms);
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02004403
4404 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4405 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4406 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4407
4408 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4409 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4410
4411 /* Now that MS seized the UL-TBF, PCU sends DL-TBF Assignment on PACCH */
4412 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4413 /* the MS ACKs the PKT_DL_ASS: */
4414 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4415
4416 /* We should finally receive the DL-data that was received previously from the SGSN: */
4417 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4418
4419 f_shutdown(__BFILE__, __LINE__, final := true);
4420}
4421
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004422private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004423 template GsmRrMessage t_imm_ass := ?,
4424 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004425runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004426 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004427 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004428
4429 ra11 := enc_EGPRSPktChRequest2uint(req);
4430 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
4431
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07004432 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004433 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004434 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004435 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004436 }
4437
4438 setverdict(pass);
4439}
4440
4441testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
4442 var template GsmRrMessage imm_ass;
4443 var template IaRestOctets rest;
4444 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004445 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004446
4447 /* Initialize the PCU interface abstraction */
4448 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004449 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004450
4451 var EGPRSPktChRequest req := {
4452 /* NOTE: other fields are set in the loop */
4453 signalling := { tag := '110011'B }
4454 };
4455
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004456 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004457 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4458 req.signalling.random_bits := ext_ra;
4459
4460 /* For signalling, do we expect Multiblock UL TBF Assignment? */
4461 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4462 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4463 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4464
4465 f_TC_egprs_pkt_chan_req(req, imm_ass);
4466 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004467
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004468 var StatsDExpects expect := {
4469 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4470 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4471 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4472 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4473 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4474 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4475 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4476 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4477 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4478 };
4479 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004480
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004481 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004482}
4483
4484testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
4485 var template GsmRrMessage imm_ass;
4486 var template IaRestOctets rest;
4487 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004488 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004489
4490 /* Initialize the PCU interface abstraction */
4491 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004492 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004493
4494 var EGPRSPktChRequest req := {
4495 /* NOTE: other fields are set in the loop */
4496 one_phase := { tag := '0'B }
4497 };
4498
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004499 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004500 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4501 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
4502 var BIT2 priority := substr(ext_ra, 0, 2);
4503 var BIT3 rand := substr(ext_ra, 2, 3);
4504
4505 req.one_phase.multislot_class := mslot_class;
4506 req.one_phase.priority := priority;
4507 req.one_phase.random_bits := rand;
4508
4509 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
4510 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
4511 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4512 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4513
4514 f_TC_egprs_pkt_chan_req(req, imm_ass);
4515 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004516
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004517 var StatsDExpects expect := {
4518 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4519 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4520 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4521 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4522 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4523 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4524 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4525 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4526 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4527 };
4528 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004529
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004530 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004531}
4532
4533testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4534 var template GsmRrMessage imm_ass;
4535 var template IaRestOctets rest;
4536 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004537 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004538
4539 /* Initialize the PCU interface abstraction */
4540 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004541 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004542
4543 var EGPRSPktChRequest req := {
4544 /* NOTE: other fields are set in the loop */
4545 two_phase := { tag := '110000'B }
4546 };
4547
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004548 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004549 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4550 var BIT2 priority := substr(ext_ra, 0, 2);
4551 var BIT3 rand := substr(ext_ra, 2, 3);
4552
4553 req.two_phase.priority := priority;
4554 req.two_phase.random_bits := rand;
4555
4556 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4557 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4558 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4559 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4560
4561 f_TC_egprs_pkt_chan_req(req, imm_ass);
4562 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004563
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004564 var StatsDExpects expect := {
4565 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4566 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4567 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4568 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4569 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4570 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4571 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4572 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4573 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4574 };
4575 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004576
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004577 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004578}
4579
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004580private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4581 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004582 PCUIF_BurstType bt := BURST_TYPE_1,
4583 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004584runs on RAW_PCU_Test_CT {
4585 var template ReqRefWaitInd tr_ref;
4586 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004587
4588 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4589 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4590 ra := bit2int(ra11), is_11bit := 1,
4591 burst_type := bt, fn := fn,
4592 arfcn := 871));
4593
4594 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004595 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004596
4597 /* Just to have a short-name reference to the actual message */
4598 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4599
4600 /* Make sure that Request Reference list contains at least one entry
4601 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004602 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004603 if (not match(iar.payload, { *, tr_ref, * })) {
4604 setverdict(fail, "Request Reference list does not match");
4605 f_shutdown(__BFILE__, __LINE__);
4606 }
4607
4608 /* Match Feature Indicator (must indicate PS domain) */
4609 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4610 setverdict(fail, "Feature Indicator does not match");
4611 f_shutdown(__BFILE__, __LINE__);
4612 }
4613
4614 /* Match IAR Rest Octets */
4615 if (not match(iar.rest_octets, rest)) {
4616 setverdict(fail, "IAR Rest Octets does not match: ",
4617 iar.rest_octets, " vs expected ", rest);
4618 f_shutdown(__BFILE__, __LINE__);
4619 }
4620
4621 setverdict(pass);
4622}
4623
4624/* Verify the contents of RR Immediate Assignment Reject message and its
4625 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4626testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4627 var template IARRestOctets rest;
4628 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004629 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004630
4631 /* Initialize the PCU interface abstraction */
4632 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004633 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004634
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004635 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004636 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4637 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4638
4639 /* Intentionally incorrect message (see table 11.2.5a.2) */
4640 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4641 }
4642
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004643 var StatsDExpects expect := {
4644 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4645 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4646 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4647 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4648 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4649 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4650 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4651 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4652 };
4653 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004654
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004655 f_shutdown(__BFILE__, __LINE__, final := true);
4656}
4657
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004658/* At the moment, the IUT does not support any emergency services. Make sure
4659 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4660testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4661 var template IARRestOctets rest;
4662 var BIT5 ext_ra;
4663 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004664 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004665
4666 /* Initialize the PCU interface abstraction */
4667 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004668 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004669
4670 var EGPRSPktChRequest req := {
4671 /* NOTE: other fields are set in the loop */
4672 emergency := { tag := '110111'B }
4673 };
4674
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004675 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004676 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4677 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4678
4679 req.emergency.random_bits := ext_ra;
4680 ra11 := enc_EGPRSPktChRequest2bits(req);
4681
4682 /* Intentionally incorrect message (see table 11.2.5a.2) */
4683 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4684 }
4685
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004686 var StatsDExpects expect := {
4687 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4688 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4689 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4690 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4691 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4692 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4693 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4694 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4695 };
4696 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004697
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004698 f_shutdown(__BFILE__, __LINE__, final := true);
4699}
4700
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004701/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4702testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004703 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004704 var template IARRestOctets rest;
4705 var BIT11 ra11;
4706
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004707 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004708 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004709
4710 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004711 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4712 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004713
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004714 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004715 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004716 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004717
4718 var EGPRSPktChRequest req := {
4719 one_phase := {
4720 tag := '0'B,
4721 multislot_class := '10101'B,
4722 priority := '01'B,
4723 random_bits := '101'B
4724 }
4725 };
4726
4727 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4728 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4729 for (var integer i := 0; i < 7; i := i + 1) {
4730 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4731 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4732 }
4733
4734 ra11 := enc_EGPRSPktChRequest2bits(req);
4735 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4736
4737 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004738 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004739
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004740 var StatsDExpects expect := {
4741 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4742 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4743 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4744 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4745 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4746 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4747 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4748 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4749 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4750 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4751 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4752 };
4753 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004754
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004755 f_shutdown(__BFILE__, __LINE__, final := true);
4756}
4757
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004758/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004759private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004760return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004761 /* Pick a random MA length in range 2 .. max_ma_len */
4762 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4763
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004764 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4765 hsn := f_rnd_int(63),
4766 maio := f_rnd_int(63),
4767 ma := f_rnd_bitstring(ma_len));
4768}
4769
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004770private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4771 in GsmRrMessage rr_msg)
4772{
4773 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004774 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004775
4776 var template PacketChannelDescription tr_pkt_chan_desc := {
4777 channel_Type_spare := ?,
4778 tn := ?,
4779 tsc := ts.tsc,
4780 presence := '1'B,
4781 zero := omit,
4782 one := {
4783 maio := ts.maio,
4784 hsn := ts.hsn
4785 }
4786 };
4787
4788 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4789 setverdict(fail, "Packet Channel Description does not match: ",
4790 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4791 }
4792
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004793 /* Mobile Allocation is expected to be octet-aligned */
4794 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4795 var template MobileAllocationLV tr_ma := {
4796 len := ma_oct_len, /* in bytes */
4797 ma := substr(ts.ma, 0, ma_oct_len * 8)
4798 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004799
4800 if (not match(ia.mobile_allocation, tr_ma)) {
4801 setverdict(fail, "Mobile Allocation does not match: ",
4802 ia.mobile_allocation, " vs ", tr_ma);
4803 }
4804
4805 setverdict(pass);
4806}
4807
4808/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4809testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004810 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004811 var GprsMS ms := valueof(t_GprsMS_def);
4812
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004813 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004814 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004815
4816 /* Initialize the PCU interface abstraction */
4817 f_init_raw(testcasename(), info_ind);
4818
4819 /* EGPRS Packet Channel Request (cause=Signalling) */
4820 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4821
4822 /* Establish an Uplink EGPRS TBF */
4823 f_ms_establish_ul_tbf(ms);
4824
4825 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4826 f_shutdown(__BFILE__, __LINE__, final := true);
4827}
4828
4829/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4830testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004831 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004832 var GprsMS ms := valueof(t_GprsMS_def);
4833
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004834 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004835 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004836
4837 /* Initialize the PCU interface abstraction */
4838 f_init_raw(testcasename(), info_ind);
4839
4840 /* Establish an Uplink TBF */
4841 f_ms_establish_ul_tbf(ms);
4842
4843 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4844 f_shutdown(__BFILE__, __LINE__, final := true);
4845}
4846
4847/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4848testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004849 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004850 var GprsMS ms := valueof(t_GprsMS_def);
4851
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004852 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004853 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004854
4855 /* Initialize NS/BSSGP side */
4856 f_init_bssgp();
4857
4858 /* Initialize the PCU interface abstraction */
4859 f_init_raw(testcasename(), info_ind);
4860
4861 /* Establish BSSGP connection to the PCU */
4862 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004863 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004864
4865 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4866 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
Philipp Maier4222f472023-08-22 17:28:00 +02004867
4868 /* The PCU will send an IMMEDIATE ASSIGNMENT message on the AGCH. It
4869 * should be noted that IMMEDIATE ASSIGNMENT messages for DL TBFs are
4870 * commonly sent on the PCH. However in this case the IMSI is not
4871 * known to the PCU and hence no paging group can be calculated. The
4872 * PCU is then forced to use the AGCH.
4873 *
4874 * As a background information to this it should be noted that this
4875 * works because the IMSI is commonly unknown during a GMM ATTACH
4876 * REQUEST. In this phase the MS is in non-DRX mode, which means that
4877 * it listens on all CCCH blocks (PCH and AGCH)
4878 *
4879 * See also: 3gpp TS 44.060, section 5.5.1.5 and
4880 * 3gpp TS 45.002, section 6.5.3, 6.5.6
4881 */
4882 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_AGCH_2);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004883
4884 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4885 f_shutdown(__BFILE__, __LINE__, final := true);
4886}
4887
4888private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4889 in FrequencyParameters fp)
4890{
4891 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004892 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004893
4894 /* Table 12.8.1: Frequency Parameters information elements */
4895 var template FrequencyParameters tr_fp := {
4896 tsc := ts.tsc,
4897 presence := '10'B, /* Direct encoding 1 */
4898 arfcn := omit,
4899 indirect := omit,
4900 direct1 := {
4901 maio := ts.maio,
4902 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4903 mobile_allocation := {
4904 hsn := ts.hsn,
4905 rfl_number_list_present := '0'B,
4906 rfl_number_list := omit,
4907 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004908 ma_length := ts.ma_bit_len,
4909 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004910 }
4911 },
4912 direct2 := omit
4913 };
4914
4915 if (not match(fp, tr_fp)) {
4916 setverdict(fail, "Frequency Parameters IE does not match: ",
4917 fp, " vs ", tr_fp);
4918 }
4919
4920 setverdict(pass);
4921}
4922
4923/* Make sure that Packet Uplink Assignment contains hopping parameters */
4924testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004925 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004926 var GprsMS ms := valueof(t_GprsMS_def);
4927 var uint32_t poll_fn;
4928
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004929 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004930 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004931
4932 /* Initialize the PCU interface abstraction */
4933 f_init_raw(testcasename(), info_ind);
4934
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004935 /* Single block (two phase) packet access */
4936 var uint16_t ra := bit2int(chan_req_sb);
4937 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4938
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004939 /* Establish an Uplink TBF */
4940 f_ms_establish_ul_tbf(ms);
4941
4942 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004943 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4944 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004945
4946 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004947 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4948 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004949
4950 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4951 var template (omit) FrequencyParameters fp;
4952 if (ua.is_egprs == '1'B) {
4953 fp := ua.egprs.freq_par;
4954 } else {
4955 fp := ua.gprs.freq_par;
4956 }
4957
4958 /* This is an optional IE, so it's worth to check its presence */
4959 if (istemplatekind(fp, "omit")) {
4960 setverdict(fail, "Frequency Parameters IE is not present");
4961 f_shutdown(__BFILE__, __LINE__);
4962 }
4963
4964 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4965 f_shutdown(__BFILE__, __LINE__, final := true);
4966}
4967
4968/* Make sure that Packet Downlink Assignment contains hopping parameters */
4969testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004970 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004971 var octetstring data := f_rnd_octstring(10);
4972 var GprsMS ms := valueof(t_GprsMS_def);
4973 var RlcmacDlBlock dl_block;
4974 var uint32_t poll_fn;
4975
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004976 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004977 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004978
4979 /* Initialize NS/BSSGP side */
4980 f_init_bssgp();
4981
4982 /* Initialize the PCU interface abstraction */
4983 f_init_raw(testcasename(), info_ind);
4984
4985 /* Establish BSSGP connection to the PCU */
4986 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004987 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004988
4989 /* Establish an Uplink TBF */
4990 f_ms_establish_ul_tbf(ms);
4991
Pau Espin Pedrol7e50fa22023-06-26 16:50:22 +02004992 /* Wait until PCU starts requesting for UL block on this TBF: */
4993 f_ms_wait_usf(ms);
4994
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004995 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004996 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 +07004997
4998 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4999 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
5000 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
5001
5002 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
5003 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
5004
5005 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01005006 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
5007 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07005008
5009 /* This is an optional IE, so it's worth to check its presence */
5010 if (not ispresent(da.freq_par)) {
5011 setverdict(fail, "Frequency Parameters IE is not present");
5012 f_shutdown(__BFILE__, __LINE__);
5013 }
5014
5015 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
5016 f_shutdown(__BFILE__, __LINE__, final := true);
5017}
5018
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005019/* Check if the IUT handles subsequent INFO.ind messages */
5020testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01005021 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01005022 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005023
5024 /* Initialize the PCU interface abstraction */
5025 f_init_raw(testcasename(), info_ind);
5026
5027 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
5028 for (var integer i := 0; i < 16; i := i + 1) {
5029 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01005030 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005031 }
5032
5033 f_shutdown(__BFILE__, __LINE__, final := true);
5034}
5035
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005036/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
5037testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
5038 var PCUIF_info_ind info_ind;
5039 var integer i;
5040 const integer num_ms := 8;
5041
5042 /* Initialize NS/BSSGP side */
5043 f_init_bssgp();
5044 /* Initialize GPRS MS side */
5045 f_init_gprs_ms(num_ms);
5046
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01005047 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005048 /* Only the 3 first TRX are enabled. The enabled ones all have same
5049 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005050 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
5051 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
5052 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
5053 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005054
5055 /* Initialize the PCU interface abstraction */
5056 f_init_raw(testcasename(), info_ind);
5057
5058 /* Establish BSSGP connection to the PCU */
5059 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07005060 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005061
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07005062 /* Establish an Uplink TBF for each GprsMS instance */
5063 f_multi_ms_establish_tbf(do_activate := false);
5064
5065 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005066 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005067 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01005068 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005069 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02005070 f_shutdown(__BFILE__, __LINE__);
5071 }
5072 }
5073
5074 f_shutdown(__BFILE__, __LINE__, final := true);
5075}
5076
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005077/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
5078 * downgraded to CS1-4 so that GPRS can read the USF).
5079 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
5080 */
5081testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
5082 var PCUIF_info_ind info_ind;
5083 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
5084 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005085 var uint32_t sched_fn, dl_fn, ack_fn;
5086 var octetstring data := f_rnd_octstring(10);
5087 var RlcmacDlBlock dl_block;
5088 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005089 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005090 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
5091 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
5092
5093 /* Initialize NS/BSSGP side */
5094 f_init_bssgp();
5095 /* Initialize GPRS MS side */
5096 f_init_gprs_ms(num_ms);
5097
5098 info_ind := valueof(ts_PCUIF_INFO_default);
5099 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005100 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
5101 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005102
5103 /* Initialize the PCU interface abstraction */
5104 f_init_raw(testcasename(), info_ind);
5105
5106 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
5107 g_mcs_initial_dl := 5;
5108 g_mcs_max_dl := 5;
5109 f_pcuvty_set_allowed_cs_mcs();
5110
5111 /* Establish BSSGP connection to the PCU */
5112 f_bssgp_establish();
5113 f_multi_ms_bssgp_register();
5114
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005115 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005116 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 +01005117 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
5118 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
5119 f_shutdown(__BFILE__, __LINE__);
5120 }
5121 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5122 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
5123
5124 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005125 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 +01005126 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
5127 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
5128 f_shutdown(__BFILE__, __LINE__);
5129 }
5130 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5131 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
5132
5133 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
5134 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5135 f_sleep(0.1);
5136 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
5137 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
5138 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
5139 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
5140 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
5141 /* ACK the DL block */
5142 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
5143 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
5144 f_dl_block_ack_fn(dl_block, dl_fn));
5145
5146 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
5147 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5148 f_sleep(0.1);
5149 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
5150 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
5151 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
5152 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
5153 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
5154 /* ACK the DL block */
5155 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
5156 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
5157 f_dl_block_ack_fn(dl_block, dl_fn));
5158
5159 data := f_rnd_octstring(1400);
5160 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5161 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5162
5163 for (var integer i := 0; i < 800; i := i + 1) {
5164 f_rx_rlcmac_dl_block(dl_block, dl_fn);
5165
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005166 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005167 /* No more data to receive, done */
5168 break;
5169 }
5170
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005171 usf_ms := -1;
5172
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005173 if (ischosen(dl_block.ctrl)) {
5174 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
5175 f_shutdown(__BFILE__, __LINE__);
5176 } else if (ischosen(dl_block.data_egprs)) {
5177 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
5178 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
5179 f_shutdown(__BFILE__, __LINE__);
5180 }
5181 tgt_ms := 1;
5182 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
5183 if (dl_block.data_egprs.mcs > MCS_4) {
5184 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
5185 f_shutdown(__BFILE__, __LINE__);
5186 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005187 usf_ms := 0;
5188 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005189 } else {
5190 if (dl_block.data_egprs.mcs <= MCS_4) {
5191 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
5192 f_shutdown(__BFILE__, __LINE__);
5193 }
5194 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005195 usf_ms := 1;
5196 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005197 }
5198 }
5199 } else {
5200 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
5201 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
5202 f_shutdown(__BFILE__, __LINE__);
5203 }
5204 tgt_ms := 0;
5205 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 +01005206 usf_ms := 0;
5207 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005208 } 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 +01005209 usf_ms := 1;
5210 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005211 }
5212 }
5213
5214 /* Keep Ack/Nack description updated */
5215 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
5216
5217 /* TDMA frame number on which we are supposed to send the ACK */
5218 if (f_dl_block_rrbp_valid(dl_block)) {
5219 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
5220 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);
5221 if (tx_data_remain != 0) {
5222 /* Submit more data from time to time to keep the TBF ongoing */
5223 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
5224 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
5225 tx_data_remain := tx_data_remain - 1;
5226 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005227 } else if (tx_data_remain != 0) {
5228 /* keep sending UL blocks when requested by USF to avoid
5229 * UL TBF timeout and hence stop receival of USFs */
5230 if (usf_ms != -1) {
5231 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
5232 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005233 }
5234 }
5235
5236 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 +01005237 /* He we check that DL blocks scheduled at GPRS can still request UL
5238 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
5239 * condition also ensures the downgrade to <=MCS4 condition is tested
5240 * above */
5241 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
5242 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005243 f_shutdown(__BFILE__, __LINE__);
5244 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01005245 /* Here check for some level of fairness between them (at least ~40%): */
5246 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
5247 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
5248 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
5249 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
5250 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
5251 f_shutdown(__BFILE__, __LINE__);
5252 }
5253 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
5254 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
5255 f_shutdown(__BFILE__, __LINE__);
5256 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005257
5258 f_shutdown(__BFILE__, __LINE__, final := true);
5259}
5260
5261
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005262private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
5263 boolean exp_imsi, boolean exp_tmsi)
5264runs on RAW_PCU_Test_CT {
5265 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
5266 var integer pending := lengthof(g_ms);
5267 var RlcmacDlBlock dl_block;
5268 var boolean f1, f2;
5269
5270 while (pending > 0) {
5271 var uint32_t poll_fn;
5272
5273 /* Obtain a Downlink block and make sure it is a paging request */
5274 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
5275 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
5276 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5277 break;
5278 }
5279
5280 /* This should not happen in general, but who knows... */
5281 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
5282 if (not ispresent(req.repeated_pageinfo)) {
5283 setverdict(fail, "Repeated Page Info IE is absent?!?");
5284 break;
5285 }
5286
5287 /* A single message may contain several MIs depending on their type */
5288 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5289 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
5290 ps_domain := false);
5291 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
5292 ps_domain := false);
5293 if (not f1 and not f2)
5294 { continue; }
5295
5296 /* Detect duplicate MIs */
5297 if (mask[i] == '1'B) {
5298 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
5299 continue;
5300 }
5301
5302 mask[i] := '1'B;
5303 }
5304
5305 pending := pending - lengthof(req.repeated_pageinfo);
5306 }
5307
5308 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
5309 if (mask[i] != '1'B) {
5310 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
5311 log("===== mask := ", mask);
5312 }
5313 }
5314
5315 /* All messages must have been received by now, expect a dummy block */
5316 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
5317}
5318
5319private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
5320runs on RAW_PCU_Test_CT {
5321 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5322 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5323
5324 /* Initialize NS/BSSGP side */
5325 f_init_bssgp();
5326
5327 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005328 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005329
5330 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
5331 f_init_gprs_ms(7 * 8);
5332
5333 /* Initialize the PCU interface abstraction */
5334 f_init_raw(testcasename(), info_ind);
5335
5336 /* Establish BSSGP connection to the PCU */
5337 f_bssgp_establish();
5338 f_multi_ms_bssgp_register();
5339
5340 /* Establish an Uplink TBF for each GprsMS instance */
5341 f_multi_ms_establish_tbf(do_activate := true);
5342}
5343
5344testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
5345 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5346
5347 /* Common part: send INFO.ind, establish TBFs... */
5348 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5349
5350 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
5351 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5352 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5353 }
5354
5355 /* FIXME: work around a race condition between PCUIF and BSSGP */
5356 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5357
5358 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5359 * The IUT is expected to page on all PDCH slots of all transceivers. */
5360 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5361 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5362 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
5363 }
5364
5365 f_shutdown(__BFILE__, __LINE__, final := true);
5366}
5367
5368testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
5369 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5370
5371 /* Common part: send INFO.ind, establish TBFs... */
5372 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5373
5374 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
5375 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5376 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5377 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5378 }
5379
5380 /* FIXME: work around a race condition between PCUIF and BSSGP */
5381 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5382
5383 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5384 * The IUT is expected to page on all PDCH slots of all transceivers. */
5385 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5386 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5387 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
5388 }
5389
5390 f_shutdown(__BFILE__, __LINE__, final := true);
5391}
5392
5393testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
5394 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5395
5396 /* Common part: send INFO.ind, establish TBFs... */
5397 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5398
5399 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
5400 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5401 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5402 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
5403 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5404 } else {
5405 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5406 }
5407 }
5408
5409 /* FIXME: work around a race condition between PCUIF and BSSGP */
5410 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5411
5412 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5413 * The IUT is expected to page on all PDCH slots of all transceivers. */
5414 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5415 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5416 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
5417 }
5418
5419 f_shutdown(__BFILE__, __LINE__, final := true);
5420}
5421
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005422private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005423runs on RAW_PCU_Test_CT return RlcmacDlBlock {
5424 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005425 var integer i := 0;
5426 while (true) {
5427 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005428 if (not match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005429 break;
5430 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005431 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005432 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5433 f_shutdown(__BFILE__, __LINE__);
5434 }
5435 i := i + 1;
5436 }
5437 return dl_block;
5438}
5439
Vadim Yanitskiy03f74d42023-02-10 09:22:42 +07005440private const GsmMcc c_BssgpCellMcc := '623'H; /* MCC: Central African Republic */
5441private const GsmMnc c_BssgpCellMnc := '03'H; /* MNC: Celca (Socatel) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005442private template (value) BssgpCellId ts_BssgpCellIdDstAddr_default := {
5443 ra_id := {
5444 lai := {
5445 mcc_mnc := f_build_BcdMccMnc(c_BssgpCellMcc, c_BssgpCellMnc),
5446 lac := 423
5447 },
5448 rac := 2
5449 },
5450 cell_id := 5
5451}
5452
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005453private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
5454runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005455 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5456 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5457 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 +01005458 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005459 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005460 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005461 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5462 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5463 var template (value) RAN_Information_RIM_Container res_cont :=
5464 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5465 ts_RIM_Sequence_Number(2),
5466 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5467 ts_RIM_Protocol_Version_Number(1),
5468 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
5469 omit);
5470 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5471 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5472 res_cont));
5473}
5474
5475altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
5476runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005477 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5478 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5479 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 +01005480 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005481 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005482 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005483 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5484 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5485 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5486 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5487 tr_RAN_Information_Request_RIM_Container)) {
5488 if (do_answer) {
5489 f_outbound_nacc_rim_tx_resp(info_ind);
5490 }
5491 if (do_repeat) {
5492 repeat;
5493 }
5494 }
5495}
5496
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005497private function f_ctrl_rx_nacc_rac_ci_req(out CtrlMessage ctrl_req,
5498 PCUIF_info_ind info_ind,
5499 GsmArfcn req_arfcn,
5500 uint6_t req_bsic)
5501runs on RAW_PCU_Test_CT {
5502 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5503 int2str(info_ind.lac) & "." &
5504 int2str(info_ind.cell_id) & "." &
5505 int2str(req_arfcn) & "." &
5506 int2str(req_bsic);
5507 f_ipa_ctrl_wait_link_up();
5508 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value ctrl_req;
5509}
5510
5511private function f_ctrl_tx_nacc_rac_ci_rsp(in CtrlMessage ctrl_req)
5512runs on RAW_PCU_Test_CT {
5513 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5514 IPA_CTRL.send(ts_CtrlMsgGetRepl(ctrl_req.cmd.id,
5515 ctrl_req.cmd.variable,
5516 hex2str(c_BssgpCellMcc) & "-" &
5517 hex2str(c_BssgpCellMnc) & "-" &
5518 int2str(addr.ra_id.lai.lac) & "-" &
5519 int2str(addr.ra_id.rac) & "-" &
5520 int2str(addr.cell_id)));
5521}
5522
5523private function f_pcuif_rx_nacc_rac_ci_req(out PCUIF_Message addr_req,
5524 PCUIF_info_ind info_ind,
5525 GsmArfcn req_arfcn,
5526 uint6_t req_bsic)
5527runs on RAW_PCU_Test_CT {
5528 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id,
5529 req_arfcn, req_bsic)) -> value addr_req;
5530}
5531
5532private function f_pcuif_tx_nacc_rac_ci_rsp(in PCUIF_Message addr_req)
5533runs on RAW_PCU_Test_CT {
5534 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5535 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, addr_req.u.container.u.neigh_addr_req, 0,
5536 str2int(hex2str(c_BssgpCellMcc)),
5537 str2int(hex2str(c_BssgpCellMnc)),
5538 lengthof(c_BssgpCellMnc) - 2,
5539 addr.ra_id.lai.lac,
5540 addr.ra_id.rac,
5541 addr.cell_id));
5542}
5543
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005544private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
5545 boolean answer := true, boolean use_old_ctrl_iface := false)
5546runs on RAW_PCU_Test_CT {
5547 if (use_old_ctrl_iface == true) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005548 var CtrlMessage ctrl_req;
5549 f_ctrl_rx_nacc_rac_ci_req(ctrl_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005550 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005551 f_ctrl_tx_nacc_rac_ci_rsp(ctrl_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005552 }
5553 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005554 var PCUIF_Message pcuif_req;
5555 f_pcuif_rx_nacc_rac_ci_req(pcuif_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005556 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005557 f_pcuif_tx_nacc_rac_ci_rsp(pcuif_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005558 }
5559 }
5560}
5561
Philipp Maiere640d8f2023-06-30 14:43:01 +02005562private function f_outbound_nacc_success_no_si(inout GprsMS ms, PCUIF_info_ind info_ind,
5563 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5564 boolean skip_final_ctrl_ack := false,
5565 boolean use_old_ctrl_iface := false,
5566 template (value) RlcmacUlCtrlMsg cell_chg_notif)
5567runs on RAW_PCU_Test_CT {
5568 var template RlcmacDlCtrlMsg cell_chg_cont;
5569 var RlcmacDlBlock dl_block;
5570 var uint32_t sched_fn;
5571
5572 /* Start NACC from MS side */
5573 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chg_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5574
5575 /* Obtain a Downlink block and make sure it is a PacketCellChangeContine. We also make sure that this
5576 * PacketCellChangeContine message does not contain any ARFCN/BSIC. */
5577 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5578 cell_chg_cont := tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE
5579 cell_chg_cont.u.cell_chg_continue.arfcn_bsic_presence := '0'B
5580 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, cell_chg_cont))) {
5581 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5582 f_shutdown(__BFILE__, __LINE__);
5583 }
5584
5585 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5586 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
5587 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5588 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5589 }
5590}
5591
5592/* Start NACC from MS side, propose an UTRAN cell */
5593private function f_outbound_nacc_success_utran(inout GprsMS ms, PCUIF_info_ind info_ind,
5594 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5595 boolean skip_final_ctrl_ack := false,
5596 boolean use_old_ctrl_iface := false)
5597runs on RAW_PCU_Test_CT {
5598 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
5599 var uint14_t req_uarfcn := 1234;
5600 var uint10_t req_scrambling_code := 456;
5601
5602 /* Start NACC from MS side */
5603 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF_UTRAN(ms.ul_tbf.tfi, req_uarfcn, req_scrambling_code);
5604 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);
5605}
5606
5607/* Start NACC from MS side, propose an E-UTRAN cell */
5608private function f_outbound_nacc_success_eutran(inout GprsMS ms, PCUIF_info_ind info_ind,
5609 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5610 boolean skip_final_ctrl_ack := false,
5611 boolean use_old_ctrl_iface := false)
5612runs on RAW_PCU_Test_CT {
5613 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
5614 var uint16_t req_earfcn := 1234;
5615 var uint9_t phys_layer_cell_id := 456;
5616
5617 /* Start NACC from MS side */
5618 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF_EUTRAN(ms.ul_tbf.tfi, req_earfcn, phys_layer_cell_id);
5619 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);
5620}
5621
Philipp Maier58c08332023-06-30 13:26:42 +02005622/* Start NACC from MS side, propose a GERAN cell */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005623private function f_outbound_nacc_success_geran(inout GprsMS ms, PCUIF_info_ind info_ind,
5624 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
5625 boolean skip_final_ctrl_ack := false,
5626 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005627runs on RAW_PCU_Test_CT {
Philipp Maier7d187ae2023-06-20 14:38:24 +02005628 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Philipp Maier58c08332023-06-30 13:26:42 +02005629 var template RlcmacDlCtrlMsg cell_chg_cont;
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005630 var RlcmacDlBlock dl_block;
5631 var uint32_t sched_fn;
5632 var GsmArfcn req_arfcn := 862;
5633 var uint6_t req_bsic := 43;
5634
5635 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005636 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5637 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 +01005638
5639 if (exp_rac_ci_query == true) {
5640 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005641 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 +01005642 }
5643
5644 if (exp_si_query == true) {
5645 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005646 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005647 }
5648
5649 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005650 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005651
Philipp Maier58c08332023-06-30 13:26:42 +02005652 /* Obtain a Downlink block and make sure it is a PacketCellChangeContinue, also verify that
5653 * the PacketCellChangeContinue message contains the ARFCN and BSIC which was proposed in
5654 * the PacketCellChangeNotification before. */
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005655 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Philipp Maier58c08332023-06-30 13:26:42 +02005656 cell_chg_cont := tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE
5657 cell_chg_cont.u.cell_chg_continue.arfcn_bsic_presence := '1'B
5658 cell_chg_cont.u.cell_chg_continue.arfcn := req_arfcn;
5659 cell_chg_cont.u.cell_chg_continue.bsic := req_bsic;
5660 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, cell_chg_cont))) {
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005661 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5662 f_shutdown(__BFILE__, __LINE__);
5663 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005664 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005665 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005666 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5667 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5668 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005669}
5670
Philipp Maiere640d8f2023-06-30 14:43:01 +02005671type enumerated f_TC_nacc_outbound_success_ran_type {
5672 NACC_RAN_GERAN,
5673 NACC_RAN_UTRAN,
5674 NACC_RAN_EUTRAN
5675}
5676
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005677/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005678function 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 +01005679 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005680 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005681 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005682 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005683
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005684 if (use_old_ctrl_iface) {
5685 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5686 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5687 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005688
5689 /* Initialize NS/BSSGP side */
5690 f_init_bssgp();
5691 /* Initialize GPRS MS side */
5692 f_init_gprs_ms();
5693 ms := g_ms[0]; /* We only use first MS in this test */
5694
5695 /* Initialize the PCU interface abstraction */
5696 f_init_raw(testcasename(), info_ind);
5697
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005698 /* Make sure we are not affected by full cache from previous tests */
5699 f_pcuvty_flush_neigh_caches();
5700
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005701 /* Establish BSSGP connection to the PCU */
5702 f_bssgp_establish();
5703 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5704
5705 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005706 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 +01005707 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5708 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5709
5710 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005711 if (ran_type == NACC_RAN_GERAN) {
5712 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5713 } else if (ran_type == NACC_RAN_UTRAN) {
5714 f_outbound_nacc_success_utran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5715 } else if (ran_type == NACC_RAN_EUTRAN) {
5716 f_outbound_nacc_success_eutran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
5717 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005718
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005719 f_shutdown(__BFILE__, __LINE__, final := true);
5720}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005721
Philipp Maiere640d8f2023-06-30 14:43:01 +02005722testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
5723 f_TC_nacc_outbound_success(NACC_RAN_GERAN);
5724}
5725
5726testcase TC_nacc_outbound_success_utran() runs on RAW_PCU_Test_CT {
5727 f_TC_nacc_outbound_success(NACC_RAN_UTRAN);
5728}
5729
5730testcase TC_nacc_outbound_success_eutran() runs on RAW_PCU_Test_CT {
5731 f_TC_nacc_outbound_success(NACC_RAN_EUTRAN);
5732}
5733
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005734/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5735testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5736 var PollFnCtx pollctx;
5737 var GprsMS ms;
5738 var RlcmacDlBlock dl_block;
5739 var uint32_t sched_fn;
5740 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005741 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005742
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005743 if (use_old_ctrl_iface) {
5744 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5745 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5746 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005747
5748 /* Initialize NS/BSSGP side */
5749 f_init_bssgp();
5750 /* Initialize GPRS MS side */
5751 f_init_gprs_ms();
5752 ms := g_ms[0]; /* We only use first MS in this test */
5753
5754 /* Initialize the PCU interface abstraction */
5755 f_init_raw(testcasename(), info_ind);
5756
5757 /* Make sure we are not affected by full cache from previous tests */
5758 f_pcuvty_flush_neigh_caches();
5759
5760 /* Establish BSSGP connection to the PCU */
5761 f_bssgp_establish();
5762 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5763
5764 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005765 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 +01005766 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5767 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5768
5769 /* Start NACC from MS side, avoid sending final CTRL ACK */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005770 f_outbound_nacc_success_geran(ms, info_ind, skip_final_ctrl_ack := true,
5771 use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005772
5773 /* Wait until we receive something non-dummy */
5774 dl_block := f_skip_dummy(0, sched_fn);
5775 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5776 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5777 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5778 }
5779 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5780 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5781 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5782 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5783 }
5784
5785 f_shutdown(__BFILE__, __LINE__, final := true);
5786}
5787
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005788/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5789testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5790 var PollFnCtx pollctx;
5791 var GprsMS ms;
5792 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02005793 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005794 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005795
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005796 if (use_old_ctrl_iface) {
5797 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5798 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5799 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005800
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005801 /* Initialize NS/BSSGP side */
5802 f_init_bssgp();
5803 /* Initialize GPRS MS side */
5804 f_init_gprs_ms();
5805 ms := g_ms[0]; /* We only use first MS in this test */
5806
5807 /* Initialize the PCU interface abstraction */
5808 f_init_raw(testcasename(), info_ind);
5809
5810 /* Make sure we are not affected by full cache from previous tests */
5811 f_pcuvty_flush_neigh_caches();
5812 /* Set timeout values for caches so that entries will be in cache during second try */
5813 f_pcuvty_set_neigh_caches(10, 10);
5814
5815 /* Establish BSSGP connection to the PCU */
5816 f_bssgp_establish();
5817 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5818
5819 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005820 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 +01005821 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5822 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5823
5824 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005825 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005826
5827 /* 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 +02005828 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 +01005829
5830 f_shutdown(__BFILE__, __LINE__, final := true);
5831}
5832
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005833/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5834 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5835 */
5836testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5837 var PollFnCtx pollctx;
5838 var GprsMS ms;
5839 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02005840 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005841 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005842
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005843 if (use_old_ctrl_iface) {
5844 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5845 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5846 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005847
5848 /* Initialize NS/BSSGP side */
5849 f_init_bssgp();
5850 /* Initialize GPRS MS side */
5851 f_init_gprs_ms();
5852 ms := g_ms[0]; /* We only use first MS in this test */
5853
5854 /* Initialize the PCU interface abstraction */
5855 f_init_raw(testcasename(), info_ind);
5856
5857 /* Make sure we are not affected by full cache from previous tests */
5858 f_pcuvty_flush_neigh_caches();
5859 /* Set timeout values for caches so that entries will be erased before the second try */
5860 f_pcuvty_set_neigh_caches(1, 1);
5861
5862 /* Establish BSSGP connection to the PCU */
5863 f_bssgp_establish();
5864 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5865
5866 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005867 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 +01005868 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5869 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5870
5871 /* Start NACC from MS side */
Philipp Maiere640d8f2023-06-30 14:43:01 +02005872 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005873
5874 /* CTRL client should have disconnected from us */
5875 f_ipa_ctrl_wait_link_down();
5876 /* wait for cache entries to time out */
5877 f_sleep(2.0);
5878 /* 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 +02005879 f_outbound_nacc_success_geran(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005880
5881 f_shutdown(__BFILE__, __LINE__, final := true);
5882}
5883
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005884/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005885testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5886 var RlcmacDlBlock dl_block;
5887 var PollFnCtx pollctx;
5888 var uint32_t sched_fn;
5889 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02005890 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005891 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005892 var GsmArfcn req_arfcn := 862;
5893 var uint6_t req_bsic := 43;
5894
5895 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5896 * resolution CTRL port, to trigger Conn Refused by socket:
5897 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5898 */
5899
5900 /* Initialize NS/BSSGP side */
5901 f_init_bssgp();
5902 /* Initialize GPRS MS side */
5903 f_init_gprs_ms();
5904 ms := g_ms[0]; /* We only use first MS in this test */
5905
5906 /* Initialize the PCU interface abstraction */
5907 f_init_raw(testcasename(), info_ind);
5908
5909 /* Make sure we are not affected by full cache from previous tests */
5910 f_pcuvty_flush_neigh_caches();
5911
5912 /* Establish BSSGP connection to the PCU */
5913 f_bssgp_establish();
5914 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5915
5916 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005917 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 +01005918 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5919 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5920
5921 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005922 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5923 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 +01005924
5925 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005926 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005927 /* Make sure it is a Pkt Cell Chg Continue */
5928 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5929 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5930 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005931 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5932 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5933 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5934 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5935 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005936
5937 f_shutdown(__BFILE__, __LINE__, final := true);
5938}
5939
5940/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005941testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5942 var RlcmacDlBlock dl_block;
5943 var PollFnCtx pollctx;
5944 var uint32_t sched_fn;
5945 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02005946 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005947 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005948 var GsmArfcn req_arfcn := 862;
5949 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005950 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005951
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005952 if (use_old_ctrl_iface) {
5953 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5954 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5955 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005956
5957 /* Initialize NS/BSSGP side */
5958 f_init_bssgp();
5959 /* Initialize GPRS MS side */
5960 f_init_gprs_ms();
5961 ms := g_ms[0]; /* We only use first MS in this test */
5962
5963 /* Initialize the PCU interface abstraction */
5964 f_init_raw(testcasename(), info_ind);
5965
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005966 /* Make sure we are not affected by full cache from previous tests */
5967 f_pcuvty_flush_neigh_caches();
5968
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005969 /* Establish BSSGP connection to the PCU */
5970 f_bssgp_establish();
5971 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5972
5973 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005974 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 +01005975 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5976 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5977
5978 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02005979 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5980 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 +01005981
5982 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005983 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005984 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 +01005985
5986 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005987 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005988 /* Make sure it is a Pkt Cell Chg Continue */
5989 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5990 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5991 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005992 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5993 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5994 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5995 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5996 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005997
5998 f_shutdown(__BFILE__, __LINE__, final := true);
5999}
6000
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006001/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
6002testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
6003 var RlcmacDlBlock dl_block;
6004 var PollFnCtx pollctx;
6005 var uint32_t sched_fn;
6006 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02006007 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006008 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006009 var GsmArfcn req_arfcn := 862;
6010 var uint6_t req_bsic := 43;
6011
6012 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6013 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6014
6015 /* Initialize NS/BSSGP side */
6016 f_init_bssgp();
6017 /* Initialize GPRS MS side */
6018 f_init_gprs_ms();
6019 ms := g_ms[0]; /* We only use first MS in this test */
6020
6021 /* Initialize the PCU interface abstraction */
6022 f_init_raw(testcasename(), info_ind);
6023
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006024 /* Make sure we are not affected by full cache from previous tests */
6025 f_pcuvty_flush_neigh_caches();
6026
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006027 /* Establish BSSGP connection to the PCU */
6028 f_bssgp_establish();
6029 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6030
6031 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01006032 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 +01006033 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6034 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6035
6036 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006037 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6038 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 +01006039
6040 /* osmo-pcu should now ask for resolution: */
6041 f_ipa_ctrl_wait_link_up();
6042 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
6043 int2str(info_ind.lac) & "." &
6044 int2str(info_ind.cell_id) & "." &
6045 int2str(req_arfcn) & "." &
6046 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006047 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006048 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
6049
6050 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006051 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006052 /* Make sure it is a Pkt Cell Chg Continue */
6053 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6054 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6055 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006056 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6057 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6058 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6059 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6060 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006061
6062 f_shutdown(__BFILE__, __LINE__, final := true);
6063}
6064
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006065/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
6066testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
6067 var RlcmacDlBlock dl_block;
6068 var PollFnCtx pollctx;
6069 var uint32_t sched_fn;
6070 var GprsMS ms;
Philipp Maier7d187ae2023-06-20 14:38:24 +02006071 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006072 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006073 var GsmArfcn req_arfcn := 862;
6074 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006075 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006076
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006077 if (use_old_ctrl_iface) {
6078 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6079 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6080 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006081
6082 /* Initialize NS/BSSGP side */
6083 f_init_bssgp();
6084 /* Initialize GPRS MS side */
6085 f_init_gprs_ms();
6086 ms := g_ms[0]; /* We only use first MS in this test */
6087
6088 /* Initialize the PCU interface abstraction */
6089 f_init_raw(testcasename(), info_ind);
6090
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006091 /* Make sure we are not affected by full cache from previous tests */
6092 f_pcuvty_flush_neigh_caches();
6093
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006094 /* Establish BSSGP connection to the PCU */
6095 f_bssgp_establish();
6096 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6097
6098 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01006099 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 +01006100 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6101 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6102
6103 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006104 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6105 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 +01006106
6107 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006108 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 +01006109
6110 /* RIM procedure: */
Vadim Yanitskiyd8aa5e82023-02-12 17:11:42 +07006111 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006112 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
6113
6114 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006115 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006116 /* Make sure it is a Pkt Cell Chg Continue */
6117 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6118 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6119 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01006120 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6121 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6122 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6123 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6124 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006125
6126 f_shutdown(__BFILE__, __LINE__, final := true);
6127}
6128
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006129/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
6130testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
6131 var PollFnCtx pollctx;
6132 var GprsMS ms;
6133 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006134 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006135 var RlcmacDlBlock dl_block;
6136 var uint32_t sched_fn;
6137 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006138 var charstring ctrl_var;
6139 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006140 var GsmArfcn req_arfcn := 862;
6141 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006142 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006143
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006144 if (use_old_ctrl_iface) {
6145 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6146 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6147 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006148
6149 /* Initialize NS/BSSGP side */
6150 f_init_bssgp();
6151 /* Initialize GPRS MS side */
6152 f_init_gprs_ms();
6153 ms := g_ms[0]; /* We only use first MS in this test */
6154
6155 /* Initialize the PCU interface abstraction */
6156 f_init_raw(testcasename(), info_ind);
6157
6158 /* Make sure we are not affected by full cache from previous tests */
6159 f_pcuvty_flush_neigh_caches();
6160
6161 /* Establish BSSGP connection to the PCU */
6162 f_bssgp_establish();
6163 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6164
6165 /* Send PACKET RESOURCE REQUEST */
6166 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6167 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6168 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6169
6170 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006171 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6172 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 +01006173
6174 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006175 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006176 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006177 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006178 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006179 }
6180
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006181 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006182 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 +01006183 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006184
6185 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006186 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006187 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006188 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006189 }
6190
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006191 timer T := 2.0;
6192 T.start;
6193 alt {
6194 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006195 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006196 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
6197 f_shutdown(__BFILE__, __LINE__);
6198 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006199 [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 {
6200 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
6201 f_shutdown(__BFILE__, __LINE__);
6202 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006203 [] T.timeout {
6204 setverdict(pass);
6205 }
6206 }
6207
6208 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006209 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006210
6211 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6212 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6213 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6214 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6215 f_shutdown(__BFILE__, __LINE__);
6216 }
6217 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6218 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6219 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6220 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6221 }
6222
6223 f_shutdown(__BFILE__, __LINE__, final := true);
6224}
6225
6226/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
6227testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
6228 var PollFnCtx pollctx;
6229 var GprsMS ms;
6230 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006231 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006232 var RlcmacDlBlock dl_block;
6233 var uint32_t sched_fn;
6234 var CtrlMessage rx_ctrl;
6235 var GsmArfcn req_arfcn := 862;
6236 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006237 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006238
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006239 if (use_old_ctrl_iface) {
6240 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6241 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6242 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006243
6244 /* Initialize NS/BSSGP side */
6245 f_init_bssgp();
6246 /* Initialize GPRS MS side */
6247 f_init_gprs_ms();
6248 ms := g_ms[0]; /* We only use first MS in this test */
6249
6250 /* Initialize the PCU interface abstraction */
6251 f_init_raw(testcasename(), info_ind);
6252
6253 /* Make sure we are not affected by full cache from previous tests */
6254 f_pcuvty_flush_neigh_caches();
6255
6256 /* Establish BSSGP connection to the PCU */
6257 f_bssgp_establish();
6258 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6259
6260 /* Send PACKET RESOURCE REQUEST */
6261 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6262 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6263 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6264
6265 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006266 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6267 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 +01006268
6269 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006270 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 +01006271 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6272 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006273 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 +01006274 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6275 f_outbound_nacc_rim_tx_resp(info_ind);
6276 timer T := 1.0;
6277 T.start;
6278 alt {
6279 [] RIM.receive {
6280 setverdict(fail, "Received unexpected RIM message");
6281 f_shutdown(__BFILE__, __LINE__);
6282 }
6283 [] T.timeout {
6284 setverdict(pass);
6285 }
6286 }
6287
6288 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006289 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006290
6291 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6292 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6293 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6294 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6295 f_shutdown(__BFILE__, __LINE__);
6296 }
6297 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6298 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6299 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6300 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6301 }
6302
6303 f_shutdown(__BFILE__, __LINE__, final := true);
6304}
6305
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006306/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
6307testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
6308 var PollFnCtx pollctx;
6309 var GprsMS ms;
6310 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006311 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006312 var RlcmacDlBlock dl_block;
6313 var uint32_t sched_fn;
6314 var CtrlMessage rx_ctrl;
6315 var GsmArfcn req_arfcn := 862;
6316 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006317 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006318
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006319 if (use_old_ctrl_iface) {
6320 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6321 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6322 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006323
6324 /* Initialize NS/BSSGP side */
6325 f_init_bssgp();
6326 /* Initialize GPRS MS side */
6327 f_init_gprs_ms();
6328 ms := g_ms[0]; /* We only use first MS in this test */
6329
6330 /* Initialize the PCU interface abstraction */
6331 f_init_raw(testcasename(), info_ind);
6332
6333 /* Make sure we are not affected by full cache from previous tests */
6334 f_pcuvty_flush_neigh_caches();
6335
6336 /* Establish BSSGP connection to the PCU */
6337 f_bssgp_establish();
6338 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6339
6340 /* Send PACKET RESOURCE REQUEST */
6341 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6342 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6343 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6344
6345 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006346 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6347 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 +01006348
6349 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006350 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 +01006351 /* RIM procedure: */
6352 as_outbound_nacc_rim_resolve(info_ind);
6353
6354 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
6355 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006356 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 +01006357
6358 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
6359 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6360
6361 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6362 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6363 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6364 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6365 f_shutdown(__BFILE__, __LINE__);
6366 }
6367 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6368 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6369 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6370 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6371 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006372
6373 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006374}
6375
6376/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
6377testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
6378 var PollFnCtx pollctx;
6379 var GprsMS ms;
6380 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006381 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006382 var RlcmacDlBlock dl_block;
6383 var uint32_t sched_fn;
6384 var CtrlMessage rx_ctrl;
6385 var GsmArfcn req_arfcn := 862;
6386 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006387 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006388
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006389 if (use_old_ctrl_iface) {
6390 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6391 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6392 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006393
6394 /* Initialize NS/BSSGP side */
6395 f_init_bssgp();
6396 /* Initialize GPRS MS side */
6397 f_init_gprs_ms();
6398 ms := g_ms[0]; /* We only use first MS in this test */
6399
6400 /* Initialize the PCU interface abstraction */
6401 f_init_raw(testcasename(), info_ind);
6402
6403 /* Make sure we are not affected by full cache from previous tests */
6404 f_pcuvty_flush_neigh_caches();
6405
6406 /* Establish BSSGP connection to the PCU */
6407 f_bssgp_establish();
6408 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6409
6410 /* Send PACKET RESOURCE REQUEST */
6411 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6412 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6413 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6414
6415 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006416 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6417 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 +01006418
6419 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006420 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 +01006421 /* RIM procedure: */
6422 as_outbound_nacc_rim_resolve(info_ind);
6423
6424 /* Announce SI back to MS, continue NACC procedure */
6425 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6426
6427 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006428 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 +01006429
6430 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6431 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6432 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6433 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6434 f_shutdown(__BFILE__, __LINE__);
6435 }
6436 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6437 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6438 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6439 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6440 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006441
6442 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006443}
6444
6445/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
6446testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
6447 var PollFnCtx pollctx;
6448 var GprsMS ms;
6449 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006450 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006451 var RlcmacDlBlock dl_block;
6452 var uint32_t sched_fn;
6453 var CtrlMessage rx_ctrl;
6454 var GsmArfcn req_arfcn := 862;
6455 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006456 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006457
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006458 if (use_old_ctrl_iface) {
6459 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6460 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6461 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006462
6463 /* Initialize NS/BSSGP side */
6464 f_init_bssgp();
6465 /* Initialize GPRS MS side */
6466 f_init_gprs_ms();
6467 ms := g_ms[0]; /* We only use first MS in this test */
6468
6469 /* Initialize the PCU interface abstraction */
6470 f_init_raw(testcasename(), info_ind);
6471
6472 /* Make sure we are not affected by full cache from previous tests */
6473 f_pcuvty_flush_neigh_caches();
6474
6475 /* Establish BSSGP connection to the PCU */
6476 f_bssgp_establish();
6477 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6478
6479 /* Send PACKET RESOURCE REQUEST */
6480 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6481 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6482 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6483
6484 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006485 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6486 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 +01006487
6488 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006489 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 +01006490 /* RIM procedure: */
6491 as_outbound_nacc_rim_resolve(info_ind);
6492
6493 /* Announce SI back to MS, continue NACC procedure */
6494 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6495
6496 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6497 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6498 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6499 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6500 f_shutdown(__BFILE__, __LINE__);
6501 }
6502 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006503 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 +01006504
6505 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6506 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6507 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6508 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6509 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006510
6511 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006512}
6513
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006514/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6515 * while waiting for CTRL resolution */
6516testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
6517 var PollFnCtx pollctx;
6518 var GprsMS ms;
6519 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006520 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006521 var RlcmacDlBlock dl_block;
6522 var uint32_t sched_fn;
6523 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006524 var charstring ctrl_var;
6525 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006526 var GsmArfcn req_arfcn := 862;
6527 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006528 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006529
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006530 if (use_old_ctrl_iface) {
6531 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6532 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6533 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006534
6535 /* Initialize NS/BSSGP side */
6536 f_init_bssgp();
6537 /* Initialize GPRS MS side */
6538 f_init_gprs_ms();
6539 ms := g_ms[0]; /* We only use first MS in this test */
6540
6541 /* Initialize the PCU interface abstraction */
6542 f_init_raw(testcasename(), info_ind);
6543
6544 /* Make sure we are not affected by full cache from previous tests */
6545 f_pcuvty_flush_neigh_caches();
6546
6547 /* Establish BSSGP connection to the PCU */
6548 f_bssgp_establish();
6549 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6550
6551 /* Send PACKET RESOURCE REQUEST */
6552 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6553 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6554 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6555
6556 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006557 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6558 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 +01006559
6560 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006561 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006562 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006563 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006564 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006565 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006566 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006567 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6568 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 +01006569 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006570 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006571 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006572 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006573 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006574 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006575 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006576 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 +01006577
6578 /* And finally everything continues as usual with RIN procedure */
6579 as_outbound_nacc_rim_resolve(info_ind);
6580
6581 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006582 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006583
6584 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6585 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6586 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6587 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6588 f_shutdown(__BFILE__, __LINE__);
6589 }
6590 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6591 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6592 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6593 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6594 }
6595
6596 f_shutdown(__BFILE__, __LINE__, final := true);
6597}
6598
6599/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6600 * while waiting for SI resolution */
6601testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
6602 var PollFnCtx pollctx;
6603 var GprsMS ms;
6604 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006605 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006606 var RlcmacDlBlock dl_block;
6607 var uint32_t sched_fn;
6608 var CtrlMessage rx_ctrl;
6609 var GsmArfcn req_arfcn := 862;
6610 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006611 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006612
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006613 if (use_old_ctrl_iface) {
6614 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6615 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6616 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006617
6618 /* Initialize NS/BSSGP side */
6619 f_init_bssgp();
6620 /* Initialize GPRS MS side */
6621 f_init_gprs_ms();
6622 ms := g_ms[0]; /* We only use first MS in this test */
6623
6624 /* Initialize the PCU interface abstraction */
6625 f_init_raw(testcasename(), info_ind);
6626
6627 /* Make sure we are not affected by full cache from previous tests */
6628 f_pcuvty_flush_neigh_caches();
6629
6630 /* Establish BSSGP connection to the PCU */
6631 f_bssgp_establish();
6632 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6633
6634 /* Send PACKET RESOURCE REQUEST */
6635 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6636 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6637 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6638
6639 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006640 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6641 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 +01006642
6643 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006644 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 +01006645 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6646 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006647 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6648 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 +01006649 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6650 f_outbound_nacc_rim_tx_resp(info_ind);
6651
6652 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006653 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 +01006654
6655 /* And finally everything continues as usual with RIN procedure */
6656 as_outbound_nacc_rim_resolve(info_ind);
6657
6658 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006659 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006660
6661 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6662 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6663 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6664 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6665 f_shutdown(__BFILE__, __LINE__);
6666 }
6667 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6668 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6669 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6670 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6671 }
6672
6673 f_shutdown(__BFILE__, __LINE__, final := true);
6674}
6675
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006676/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6677 * while sending Pkt Neigh Data Change */
6678testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6679 var PollFnCtx pollctx;
6680 var GprsMS ms;
6681 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006682 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006683 var RlcmacDlBlock dl_block;
6684 var uint32_t sched_fn;
6685 var CtrlMessage rx_ctrl;
6686 var GsmArfcn req_arfcn := 862;
6687 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006688 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006689
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006690 if (use_old_ctrl_iface) {
6691 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6692 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6693 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006694
6695 /* Initialize NS/BSSGP side */
6696 f_init_bssgp();
6697 /* Initialize GPRS MS side */
6698 f_init_gprs_ms();
6699 ms := g_ms[0]; /* We only use first MS in this test */
6700
6701 /* Initialize the PCU interface abstraction */
6702 f_init_raw(testcasename(), info_ind);
6703
6704 /* Make sure we are not affected by full cache from previous tests */
6705 f_pcuvty_flush_neigh_caches();
6706
6707 /* Establish BSSGP connection to the PCU */
6708 f_bssgp_establish();
6709 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6710
6711 /* Send PACKET RESOURCE REQUEST */
6712 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6713 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6714 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6715
6716 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006717 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6718 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 +01006719
6720 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006721 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 +01006722 /* RIM procedure: */
6723 as_outbound_nacc_rim_resolve(info_ind);
6724
6725 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6726 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006727 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6728 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 +01006729
6730 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006731 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 +01006732 /* RIM procedure: */
6733 as_outbound_nacc_rim_resolve(info_ind);
6734 /* Transmit SI back to MS */
6735 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6736
6737 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6738 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6739 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6740 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6741 f_shutdown(__BFILE__, __LINE__);
6742 }
6743 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6744 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6745 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6746 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6747 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006748
6749 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006750}
6751
6752/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6753testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6754 var PollFnCtx pollctx;
6755 var GprsMS ms;
6756 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006757 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006758 var RlcmacDlBlock dl_block;
6759 var uint32_t sched_fn;
6760 var CtrlMessage rx_ctrl;
6761 var GsmArfcn req_arfcn := 862;
6762 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006763 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006764
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006765 if (use_old_ctrl_iface) {
6766 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6767 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6768 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006769
6770 /* Initialize NS/BSSGP side */
6771 f_init_bssgp();
6772 /* Initialize GPRS MS side */
6773 f_init_gprs_ms();
6774 ms := g_ms[0]; /* We only use first MS in this test */
6775
6776 /* Initialize the PCU interface abstraction */
6777 f_init_raw(testcasename(), info_ind);
6778
6779 /* Make sure we are not affected by full cache from previous tests */
6780 f_pcuvty_flush_neigh_caches();
6781
6782 /* Establish BSSGP connection to the PCU */
6783 f_bssgp_establish();
6784 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6785
6786 /* Send PACKET RESOURCE REQUEST */
6787 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6788 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6789 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6790
6791 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006792 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6793 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 +01006794
6795 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006796 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 +01006797 /* RIM procedure: */
6798 as_outbound_nacc_rim_resolve(info_ind);
6799
6800 /* Announce SI back to MS, continue NACC procedure */
6801 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6802
6803 /* trigger a Pkt Cell Change Notif with different tgt cell */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006804 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6805 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 +01006806
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006807 /* It should trigger RAC_CI resolution to start again: */
6808 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6809
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006810 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6811 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6812
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006813 /* RIM procedure: */
6814 as_outbound_nacc_rim_resolve(info_ind);
6815 /* Transmit SI back to MS */
6816 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6817
6818 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6819 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6820 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6821 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6822 f_shutdown(__BFILE__, __LINE__);
6823 }
6824 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6825 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6826 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6827 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6828 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006829
6830 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006831}
6832
6833/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6834testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6835 var PollFnCtx pollctx;
6836 var GprsMS ms;
6837 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006838 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006839 var RlcmacDlBlock dl_block;
6840 var uint32_t sched_fn;
6841 var CtrlMessage rx_ctrl;
6842 var GsmArfcn req_arfcn := 862;
6843 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006844 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006845
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006846 if (use_old_ctrl_iface) {
6847 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6848 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6849 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006850
6851 /* Initialize NS/BSSGP side */
6852 f_init_bssgp();
6853 /* Initialize GPRS MS side */
6854 f_init_gprs_ms();
6855 ms := g_ms[0]; /* We only use first MS in this test */
6856
6857 /* Initialize the PCU interface abstraction */
6858 f_init_raw(testcasename(), info_ind);
6859
6860 /* Make sure we are not affected by full cache from previous tests */
6861 f_pcuvty_flush_neigh_caches();
6862
6863 /* Establish BSSGP connection to the PCU */
6864 f_bssgp_establish();
6865 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6866
6867 /* Send PACKET RESOURCE REQUEST */
6868 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6869 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6870 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6871
6872 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006873 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6874 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 +01006875
6876 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006877 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 +01006878 /* RIM procedure: */
6879 as_outbound_nacc_rim_resolve(info_ind);
6880
6881 /* Announce SI back to MS, continue NACC procedure */
6882 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6883
6884 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6885 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6886 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6887 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6888 f_shutdown(__BFILE__, __LINE__);
6889 }
6890
6891 /* trigger a Pkt Cell Change Notif with different tgt cell */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006892 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6893 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 +01006894
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006895 /* It should trigger RAC_CI resolution to start again: */
6896 /* When using new PCUIF interface for resolution, we must
6897 * PCUIF.receive() here since that's the first message in the PCUIF
6898 * queue that PCU will have sent. Calling other functions doing
6899 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6900 * due to unexpected message receive. */
6901 if (not use_old_ctrl_iface) {
6902 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6903 }
6904
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006905 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6906 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6907 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6908 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6909 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006910
6911 /* When using CTRL interface, we must schedule the ACK before (see
6912 * above) blocking here waiting for the resoltion, otherwise we'll be
6913 * too late scheduling by the time the resolution is done. */
6914 if (use_old_ctrl_iface) {
6915 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6916 }
6917
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006918 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6919 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6920
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006921 /* RIM procedure: */
6922 as_outbound_nacc_rim_resolve(info_ind);
6923 /* Transmit SI back to MS */
6924 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6925
6926 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6927 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6928 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6929 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6930 f_shutdown(__BFILE__, __LINE__);
6931 }
6932 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6933 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6934 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6935 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6936 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006937
6938 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006939}
6940
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006941/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6942testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6943 var PollFnCtx pollctx;
6944 var GprsMS ms;
6945 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Philipp Maier7d187ae2023-06-20 14:38:24 +02006946 var template (value) RlcmacUlCtrlMsg cell_chg_notif;
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006947 var RlcmacDlBlock dl_block;
6948 var uint32_t sched_fn, dl_fn;
6949 var CtrlMessage rx_ctrl;
6950 var GsmArfcn req_arfcn := 862;
6951 var uint6_t req_bsic := 43;
6952 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006953 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006954
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006955 if (use_old_ctrl_iface) {
6956 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6957 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6958 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006959
6960 /* Initialize NS/BSSGP side */
6961 f_init_bssgp();
6962 /* Initialize GPRS MS side */
6963 f_init_gprs_ms();
6964 ms := g_ms[0]; /* We only use first MS in this test */
6965
6966 /* Initialize the PCU interface abstraction */
6967 f_init_raw(testcasename(), info_ind);
6968
6969 /* Make sure we are not affected by full cache from previous tests */
6970 f_pcuvty_flush_neigh_caches();
6971
6972 /* Establish BSSGP connection to the PCU */
6973 f_bssgp_establish();
6974 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6975
6976 /* Send PACKET RESOURCE REQUEST */
6977 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6978 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6979 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6980
6981 /* Start NACC from MS side */
Philipp Maier7d187ae2023-06-20 14:38:24 +02006982 cell_chg_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6983 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 +01006984
6985 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006986 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 +01006987 /* RIM procedure: */
6988 as_outbound_nacc_rim_resolve(info_ind);
6989
6990 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6991 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6992 f_sleep(0.1);
6993 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6994 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6995
6996 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6997 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6998 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6999 * Data with unassigned DL TBF in line above): */
7000 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
7001 /* Continue receiving Pkt Cell Neighbor Data */
7002 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
7003
7004 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
7005 f_rx_rlcmac_dl_block(dl_block, sched_fn);
7006 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
7007 setverdict(fail, "Rx unexpected DL block: ", dl_block);
7008 f_shutdown(__BFILE__, __LINE__);
7009 }
7010 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
7011 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
7012 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
7013 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
7014 }
7015
7016 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
7017 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
7018 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
7019 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
7020 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02007021
7022 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007023}
7024
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007025
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007026function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
7027runs on RAW_PCU_Test_CT
7028{
7029 var template (value) RAN_Information_Request_RIM_Container req_cont;
7030 var template (value) PDU_BSSGP bssgp_rim_pdu;
7031 var template PDU_BSSGP bssgp_rim_pdu_expect;
7032 var template RAN_Information_RIM_Container rim_cont_expect;
7033 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007034
7035 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007036 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 +01007037 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007038 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 +01007039 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02007040 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);
7041 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007042 f_sleep(1.0);
7043
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007044 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007045
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007046 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
7047 ts_RIM_Sequence_Number(1),
7048 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7049 ts_RIM_Protocol_Version_Number(1),
7050 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
7051 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007052 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
7053 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007054
7055 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
7056 tr_RIM_Sequence_Number(1),
7057 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7058 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01007059 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 +01007060 omit);
7061
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007062 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
7063 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007064 rim_cont_expect);
7065 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007066 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007067 T.start;
7068 alt {
7069 [] RIM.receive(bssgp_rim_pdu_expect) { }
7070 [] RIM.receive {
7071 setverdict(fail, "Unexpected BSSGP RIM PDU received");
7072 }
7073 [] T.timeout {
7074 setverdict(fail, "No BSSGP RIM PDU received");
7075 mtc.stop;
7076 }
7077 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007078}
7079/* Send a RIM RAN info request to the PCU and verify the response, we expect
7080 * getting the system information back which we have transfered to the PCU via
7081 * PCUIF on startup. */
7082testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
7083 /* Initialize NS/BSSGP side */
7084 f_init_bssgp();
7085
7086 /* Initialize the PCU interface abstraction */
7087 f_init_raw(testcasename());
7088
7089 /* Establish BSSGP connection to the PCU */
7090 f_bssgp_establish();
7091
7092 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
7093 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
7094
7095 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7096 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
7097
7098 f_shutdown(__BFILE__, __LINE__, final := true);
7099}
7100
7101/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
7102 * Routing information, to verify PCU handles that kind of address just fine
7103 */
7104testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
7105 /* Initialize NS/BSSGP side */
7106 f_init_bssgp();
7107
7108 /* Initialize the PCU interface abstraction */
7109 f_init_raw(testcasename());
7110
7111 /* Establish BSSGP connection to the PCU */
7112 f_bssgp_establish();
7113
7114 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
7115 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
7116
7117 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
7118 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007119
7120 f_shutdown(__BFILE__, __LINE__, final := true);
7121}
7122
7123/* Same as above, but in this case we simulate the rare case in which the PCU
7124 * has no system information available. We expect getting a response back but
7125 * with no system information inside. */
7126testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01007127 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007128 var PCUIF_Message pcu_msg;
7129 timer T := 2.0;
7130
7131 /* Initialize NS/BSSGP side */
7132 f_init_bssgp();
7133
7134 /* Initialize the PCU interface abstraction */
7135 f_init_raw(testcasename(), info_ind);
7136
7137 /* Establish BSSGP connection to the PCU */
7138 f_bssgp_establish();
7139
7140 /* Clear sysinfo from the PCU */
7141 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);
7142 BTS.send(si1_data_ind);
7143 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);
7144 BTS.send(si3_data_ind);
7145 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);
7146 BTS.send(si16_data_ind);
7147 f_sleep(1.0);
7148
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01007149 var RIM_Routing_Address dst_addr;
7150 var RIM_Routing_Address src_addr;
7151 var template (value) RAN_Information_Request_RIM_Container req_cont;
7152 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007153 var template PDU_BSSGP bssgp_rim_pdu_expect;
7154 var template RAN_Information_RIM_Container rim_cont_expect;
7155
7156 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 +01007157 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
7158 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007159
7160 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
7161 ts_RIM_Sequence_Number(1),
7162 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7163 ts_RIM_Protocol_Version_Number(1),
7164 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
7165 omit);
7166 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
7167 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7168 req_cont);
7169
7170
7171 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
7172 tr_RIM_Sequence_Number(1),
7173 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
7174 tr_RIM_Protocol_Version_Number(1),
7175 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
7176 omit);
7177
7178 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
7179 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
7180 rim_cont_expect);
7181 RIM.send(bssgp_rim_pdu);
7182 T.start;
7183 alt {
7184 [] RIM.receive(bssgp_rim_pdu_expect) { }
7185 [] RIM.receive {
7186 setverdict(fail, "Unexpected BSSGP RIM PDU received");
7187 }
7188 [] T.timeout {
7189 setverdict(fail, "No BSSGP RIM PDU received");
7190 mtc.stop;
7191 }
7192 }
7193
7194 f_shutdown(__BFILE__, __LINE__, final := true);
7195}
7196
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007197/* 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 +02007198testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
7199 var PCUIF_info_ind info_ind;
7200 var template (value) TsTrxBtsNum nr;
7201 var RlcmacDlBlock dl_block;
7202 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007203 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007204 timer T;
7205
7206 /* Initialize NS/BSSGP side */
7207 f_init_bssgp();
7208
7209 info_ind := valueof(ts_PCUIF_INFO_default);
7210 /* The 2 first TRX are enabled. */
7211 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
7212 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7213 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
7214
7215 /* Initialize the PCU interface abstraction */
7216 f_init_raw(testcasename(), info_ind);
7217
7218 /* Establish BSSGP connection to the PCU */
7219 f_bssgp_establish();
7220
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007221 for (ts := 0; ts < 2; ts := ts + 1) {
7222 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007223
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02007224 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
7225 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
7226 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
7227 T.start(0.5);
7228 alt {
7229 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
7230 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
7231 omit)) -> value data_msg {
7232 setverdict(pass);
7233 T.stop;
7234 }
7235 [] as_rx_fail_dummy(nr);
7236 [] BTS.receive {
7237 setverdict(fail, "Unexpected block from BTS");
7238 f_shutdown(__BFILE__, __LINE__);
7239 }
7240 [] T.timeout {
7241 setverdict(fail, "Expected IDLE block from BTS");
7242 f_shutdown(__BFILE__, __LINE__);
7243 }
7244 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007245 }
7246
7247 f_shutdown(__BFILE__, __LINE__, final := true);
7248}
7249
Oliver Smith3d174882021-09-03 11:38:51 +02007250/* Test stats for available and occupied PDCHs */
7251testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
7252 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
7253 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
7254
7255 /* Initialize NS/BSSGP side */
7256 f_init_bssgp();
7257
Oliver Smithedcded22021-09-14 09:26:55 +02007258 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
7259 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
7260 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
7261 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
7262 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
7263 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02007264
Oliver Smith72d0c692021-09-08 10:03:52 +02007265 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02007266 f_init_gprs_ms(4);
7267
7268 /* Initialize the PCU interface abstraction */
7269 f_init_raw(testcasename(), info_ind);
7270
7271 /* Reset stats */
7272 f_statsd_reset();
7273
7274 /* Establish BSSGP */
7275 f_bssgp_establish();
7276
7277 /* 8 PDCHs available, 0 occupied */
7278 var StatsDExpects expect := {
7279 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007280 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
7281 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7282 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02007283 };
7284 f_statsd_expect(expect);
7285
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007286 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02007287 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007288 f_ms_establish_ul_tbf(g_ms[0]);
7289 f_ms_establish_ul_tbf(g_ms[1]);
7290 f_ms_establish_ul_tbf(g_ms[2]);
7291 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 +02007292
7293 /* 4 PDCHs occupied */
7294 expect := {
7295 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02007296 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
7297 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
7298 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02007299 };
7300 f_statsd_expect(expect);
7301
7302 f_shutdown(__BFILE__, __LINE__, final := true);
7303}
7304
Oliver Smithf04762d2021-09-14 17:20:38 +02007305/* Test stats for available and occupied PDCHs, for MS which is not known by
7306 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
7307 * data arrives from SGSN) */
7308function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
7309 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
7310 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
7311
7312 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
7313 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
7314 gprsmultislotclass := '00001'B,
7315 gprsextendeddynalloccap := '0'B
7316 };
7317 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
7318 egprsmultislotclass := '00001'B,
7319 egprsextendeddynalloccap := '0'B
7320 };
7321 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
7322 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
7323 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
7324 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
7325
7326 /* Initialize NS/BSSGP side */
7327 f_init_bssgp();
7328
7329 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
7330 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
7331 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
7332 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
7333 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
7334 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
7335
7336 /* Allocate 1 GprsMS instance */
7337 f_init_gprs_ms(1);
7338
7339 /* Initialize the PCU interface abstraction */
7340 f_init_raw(testcasename(), info_ind);
7341
7342 /* Reset stats */
7343 f_statsd_reset();
7344
7345 /* Establish BSSGP */
7346 f_bssgp_establish();
7347
7348 /* 8 PDCHs available, 0 occupied */
7349 var StatsDExpects expect := {
7350 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7351 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
7352 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7353 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
7354 };
7355 f_statsd_expect(expect);
7356
7357 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
7358 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
7359
7360 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
7361 var octetstring data := f_rnd_octstring(1400);
7362 if (egprs) {
Philipp Maier1ec31b32023-09-22 12:59:10 +02007363 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 +02007364 } else {
Philipp Maier1ec31b32023-09-22 12:59:10 +02007365 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 +02007366 }
Philipp Maier8e1a5ee2023-07-18 15:47:16 +02007367 f_ms_exp_dl_tbf_ass_ccch(ms);
Oliver Smithf04762d2021-09-14 17:20:38 +02007368
7369 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
7370 f_sleep(X2002);
7371
7372 /* 1 PDCH occupied */
7373 if (egprs) {
7374 expect := {
7375 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7376 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
7377 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
7378 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
7379 };
7380 } else {
7381 expect := {
7382 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7383 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
7384 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
7385 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
7386 };
7387 }
7388 f_statsd_expect(expect);
7389
7390 /* Clean up */
7391 f_shutdown(__BFILE__, __LINE__, final := true);
7392}
7393testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
7394 f_tc_stat_pdch_avail_occ_ms_not_known(false);
7395}
7396testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
7397 f_tc_stat_pdch_avail_occ_ms_not_known(true);
7398}
7399
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007400/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
7401testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
7402 var PCUIF_info_ind info_ind;
7403 var template IARRestOctets rest;
7404 var BIT11 ra11;
7405
7406 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007407
7408 /* Only the first TRX is enabled. */
7409 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
7410 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7411
7412 /* Initialize the PCU interface abstraction */
7413 f_init_raw(testcasename(), info_ind);
7414 f_statsd_reset();
7415
7416 var EGPRSPktChRequest req := {
7417 one_phase := {
7418 tag := '0'B,
7419 multislot_class := '10101'B,
7420 priority := '01'B,
7421 random_bits := '101'B
7422 }
7423 };
7424
7425 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
7426 for (var integer i := 0; i < 7; i := i + 1) {
7427 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
7428 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
7429 }
7430
7431 ra11 := enc_EGPRSPktChRequest2bits(req);
7432 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
7433
7434 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01007435 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007436
7437 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
7438 f_sleep(2.0);
7439 var StatsDExpects expect := {
7440 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
7441 };
7442 f_statsd_expect(expect);
7443
7444 f_shutdown(__BFILE__, __LINE__, final := true);
7445}
7446
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007447control {
7448 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01007449 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007450 execute( TC_ta_ptcch_idle() );
7451 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02007452 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007453 execute( TC_ta_idle_dl_tbf_ass() );
7454 execute( TC_ta_ptcch_ul_multi_tbf() );
7455 execute( TC_cs_lqual_ul_tbf() );
7456 execute( TC_cs_initial_ul() );
7457 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01007458 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01007459 execute( TC_cs_max_dl() );
7460 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01007461 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01007462 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01007463 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01007464 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02007465 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01007466 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02007467 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01007468 execute( TC_x2031_t3191() );
7469 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007470 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01007471 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01007472 execute( TC_t3172_wait_ind_size0() );
7473 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02007474 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02007475 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02007476 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007477 execute( TC_mo_ping_pong() );
7478 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02007479 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007480 execute( TC_mt_ping_pong() );
7481 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007482 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007483 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07007484 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007485 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01007486 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02007487 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrole8e3b962023-07-24 16:43:26 +02007488 execute( TC_ul_tbf_bsn_wraparound_gprs());
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007489 execute( TC_paging_cs_from_bts() );
7490 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
7491 execute( TC_paging_cs_from_sgsn_sign() );
7492 execute( TC_paging_cs_from_sgsn_ptp() );
7493 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
7494 execute( TC_paging_ps_from_sgsn_sign() );
7495 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01007496 execute( TC_paging_pch_timeout() );
7497
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07007498 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
7499 execute( TC_paging_cs_multi_ms_imsi() );
7500 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02007501 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
7502 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01007503 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
7504 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007505
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007506 execute( TC_ul_tbf_finished_pkt_dl_ass_pch() );
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02007507 execute( TC_ul_tbf_1phase_while_dl_ass_pch() );
7508 execute( TC_ul_tbf_2phase_while_dl_ass_pch() );
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007509
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007510 /* EGPRS specific test cases */
7511 execute( TC_egprs_pkt_chan_req_signalling() );
7512 execute( TC_egprs_pkt_chan_req_one_phase() );
7513 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07007514 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07007515 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07007516 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02007517
7518 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07007519
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007520 /* Immediate Assignment on AGCH/PCH */
7521 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
7522 execute( TC_pcuif_fh_imm_ass_ul() );
7523 execute( TC_pcuif_fh_imm_ass_dl() );
7524 /* Packet Uplink/Downlink Assignment on PACCH */
7525 execute( TC_pcuif_fh_pkt_ass_ul() );
7526 execute( TC_pcuif_fh_pkt_ass_dl() );
7527 execute( TC_multitrx_multims_alloc() );
7528 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
Pau Espin Pedrol85ad3d02023-07-28 15:00:19 +02007529 execute( TC_dl_multislot_tbf_ms_class_unknown() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007530 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
7531 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02007532 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02007533 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01007534 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
7535 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007536
Pau Espin Pedrole1303052020-11-16 11:13:51 +01007537 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07007538
7539 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01007540 execute( TC_nacc_outbound_success() );
Philipp Maiere640d8f2023-06-30 14:43:01 +02007541 execute( TC_nacc_outbound_success_utran() );
7542 execute( TC_nacc_outbound_success_eutran() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01007543 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01007544 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01007545 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01007546 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01007547 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01007548 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
7549 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01007550 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
7551 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
7552 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01007553 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
7554 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01007555 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
7556 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
7557 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007558 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02007559 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
7560 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
7561 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
7562 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007563
7564 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007565 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007566 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007567
7568 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02007569
7570 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02007571 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
7572 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007573 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007574}
7575
Harald Weltea419df22019-03-21 17:23:04 +01007576}