blob: f859b9b725c85fc1ae7cb4122628d533bfa8f6cd [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 Pedroldee55702021-04-23 21:08:22 +0200329 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 +0700330 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
331 }
332 }
333}
334
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100335private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
336 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
337runs on RAW_PCU_Test_CT return PollFnCtx {
338 var PollFnCtx pollctx;
339
340 /* Single block (two phase) packet access */
341 var uint16_t ra := bit2int(chan_req_sb);
342 if (g_force_two_phase_access) {
343 /* If 2phase access is enforced by the network, then let's
344 * request a One phase packet access, we'll receive a single block
345 * anyway
346 */
347 ra := bit2int(chan_req_def);
348 }
349
350 /* Establish an Uplink TBF */
351 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
352 f_ms_establish_ul_tbf(ms);
353
354 /* Make sure we've got an Uplink TBF assignment */
355 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
356 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
357 f_shutdown(__BFILE__, __LINE__);
358 }
359
360 /* Send PACKET RESOURCE REQUEST
361 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
362 */
363 if (istemplatekind(pkt_res_req, "omit")) {
364 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
365 }
366
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200367 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 +0100368 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100369 * overwrite the TS allocation on MS with info from new UL TBF:
370 */
371 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
372 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
373 return pollctx;
374}
375
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200376testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200377 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100378 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200379 timer T;
380
381 /* Initialize NS/BSSGP side */
382 f_init_bssgp();
383
384 /* Initialize the PCU interface abstraction */
385 f_init_raw(testcasename());
386
387 /* Establish BSSGP connection to the PCU */
388 f_bssgp_establish();
389
390 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
391
392 T.start(2.0);
393 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100394 [] 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 +0200395 setverdict(pass);
396 }
397 [] T.timeout {
398 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
399 }
400 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700401
402 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200403}
404
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100405/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
406testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
407 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200408 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100409 var RlcmacDlBlock dl_block;
410 var octetstring data := f_rnd_octstring(10);
411 var uint32_t sched_fn;
412 var uint32_t dl_fn;
413 var GprsMS ms;
414 timer T;
415
416 /* Initialize NS/BSSGP side */
417 f_init_bssgp();
418 /* Initialize GPRS MS side */
419 f_init_gprs_ms();
420 ms := g_ms[0]; /* We only use first MS in this test */
421
422 /* Initialize the PCU interface abstraction */
423 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
424
425 /* Establish BSSGP connection to the PCU */
426 f_bssgp_establish();
427 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
428
429 /* Establish an Uplink TBF */
430 f_ms_establish_ul_tbf(ms);
431
432 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200433 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200434 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 +0100435 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
436 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
437 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
438
439 /* UL block should be received in SGSN */
440 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
441
442 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
443 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
444 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
445
446 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
447 f_sleep(X2002);
448 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
449
450 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
451 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
452
453 T.start(2.0);
454 alt {
455 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
456 setverdict(pass);
457 }
458 [] T.timeout {
459 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
460 f_shutdown(__BFILE__, __LINE__);
461 }
462 }
463
464 /* Make sure we don't receive data for that TBF since it was released
465 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200466 f_pcuif_rx_data_req_pdtch(data_msg);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100467 if (data_msg.dl_block == omit) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200468 /* IDLE block, expected on new PCU versions */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200469 } else {
470 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100471 f_shutdown(__BFILE__, __LINE__);
472 }
473
474 /* New data arrives, PCU should page the MS since no TBF active exists: */
475 /* Send some more data, it will never reach the MS */
476 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
477 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
478
479 f_shutdown(__BFILE__, __LINE__, final := true);
480}
481
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200482/* Test of correct Timing Advance at the time of TBF establishment
483 * (derived from timing offset of the Access Burst). */
484testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200485 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200486
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200487 /* Initialize GPRS MS side */
488 f_init_gprs_ms();
489 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200490 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100491 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200492
493 /* We cannot send too many TBF requests in a short time because
494 * at some point the PCU will fail to allocate a new TBF. */
495 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
496 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200497 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700498 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200499
500 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200501 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700502 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200503 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700504 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700505 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200506 }
507 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700508
509 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200510}
511
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200512/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
513 * sent in response to the first Uplink block after resource allocation. */
514testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
515 var GprsMS ms := valueof(t_GprsMS_def);
516 var PacketUlAckNack ul_ack_nack;
517 var PacketTimingAdvance pkt_ta;
518 var RlcmacDlBlock dl_block;
519 var uint32_t sched_fn;
520
521 /* Initialize NS/BSSGP side */
522 f_init_bssgp();
523
524 /* Initialize the PCU interface abstraction */
525 f_init_raw(testcasename());
526
527 /* Establish BSSGP connection to the PCU */
528 f_bssgp_establish();
529 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
530
531 /* Establish an Uplink TBF */
532 f_ms_establish_ul_tbf(ms);
533
534 /* In a busy network, there can be a significant delay between resource
535 * allocation (Packet Uplink Assignment above) and the actual time when
536 * the MS is allowed to transmit the first Uplink data block. */
537
538 /* Simulate a delay > 0 */
539 ms.ta := 2;
540
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200541 /* We're in One-Phase Access contention resolution, include TLLI */
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200542 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
543 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
544
545 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
546 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
547 pkt_ta := ul_ack_nack.gprs.pkt_ta;
548 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
549 pkt_ta := ul_ack_nack.egprs.pkt_ta;
550 } else {
551 setverdict(fail, "PacketTimingAdvance IE is not present");
552 f_shutdown(__BFILE__, __LINE__);
553 }
554
555 if (not ispresent(pkt_ta.val)) {
556 setverdict(fail, "Timing Advance value is not present");
557 f_shutdown(__BFILE__, __LINE__);
558 } else if (pkt_ta.val != ms.ta) {
559 setverdict(fail, "Timing Advance mismatch: expected ",
560 ms.ta, ", but received ", pkt_ta.val);
561 f_shutdown(__BFILE__, __LINE__);
562 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +0200563
564 f_shutdown(__BFILE__, __LINE__, final := true);
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200565}
566
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200567/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
568 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
569 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
570 * no active TBF exists at the moment of establishment (idle mode). */
571testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100572 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200573
574 /* Initialize NS/BSSGP side */
575 f_init_bssgp();
576
577 /* Initialize the PCU interface abstraction */
578 f_init_raw(testcasename());
579
580 /* Establish BSSGP connection to the PCU */
581 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100582 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200583
584 /* SGSN sends some DL data, PCU will initiate Packet Downlink
585 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100586 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
587 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200588
589 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
590 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
591 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100592 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700593 setverdict(fail, "Timing Advance value doesn't match");
594 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700595
596 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200597}
598
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200599/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200600 * while neither Uplink nor Downlink TBF is established. */
601testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100602 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200603 timer T;
604
605 /* Initialize the PCU interface abstraction */
606 f_init_raw(testcasename());
607
608 /* Sent an RTS.req for PTCCH/D */
609 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
610 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
611 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100612
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200613 T.start(5.0);
614 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200615 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
616 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
617 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200618 }
619 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100620 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
621 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200622 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200623 [] BTS.receive(PCUIF_Message:?) { repeat; }
624 [] T.timeout {
625 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700626 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200627 }
628 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100629 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700630
631 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200632}
633
634/* Test of correct Timing Advance during an active Uplink TBF.
635 *
636 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
637 * are not continuous and there can be long time gaps between them. This happens
638 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
639 * significantly change between such rare Uplink transmissions, so GPRS introduces
640 * additional mechanisms to control Timing Advance, and thus reduce interference
641 * between neighboring TDMA time-slots.
642 *
643 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
644 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
645 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
646 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
647 * among with the initial Timing Advance value. And here PTCCH comes to play.
648 *
649 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
650 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
651 * continuously. To ensure continuous measurements of the signal propagation
652 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
653 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
654 *
655 * The purpose of this test case is to verify the assignment of Timing Advance
656 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
657 * first establishes several Uplink TBFs, but does not transmit any Uplink
658 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
659 * indications to the PCU, checking the correctness of two received PTCCH/D
660 * messages (period of PTCCH/D is two multi-frames).
661 */
662
663/* List of ToA values for Access Bursts to be sent on PTCCH/U,
664 * each ToA (Timing of Arrival) value is in units of 1/4 of
665 * a symbol (i.e. 1 symbol is 4 QTA units). */
666type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
667const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
668 0, 0, 0, 0,
669 0, 0, 0, 0,
670 0, 0, 0, 0,
671 0, 0, 0, 0
672};
673
674private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
675 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
676runs on RAW_PCU_Test_CT {
677 var RAW_PCU_Event event;
678 var integer ss;
679
680 /* Send Access Bursts on PTCCH/U for every TA Index */
681 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
682 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700683 if (ss < 0) { /* Shall not happen */
684 f_shutdown(__BFILE__, __LINE__);
685 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200686
687 log("Sending an Access Burst on PTCCH/U",
688 ", sub-slot=", ss, " (TAI)",
689 ", fn=", event.data.tdma_fn,
690 ", ToA=", toa_map[ss], " (QTA)");
691 /* TODO: do we care about RA and burst format? */
692 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
693 ra := oct2int('3A'O),
694 is_11bit := 0,
695 burst_type := BURST_TYPE_0,
696 fn := event.data.tdma_fn,
697 arfcn := 871,
698 qta := toa_map[ss],
699 sapi := PCU_IF_SAPI_PTCCH));
700 repeat;
701 }
702}
703
704private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
705 template PTCCHDownlinkMsg t_ta_msg)
706runs on RAW_PCU_Test_CT {
707 var PTCCHDownlinkMsg ta_msg;
708 var PCUIF_Message pcu_msg;
709 timer T;
710
711 /* First, send an RTS.req for the upcoming PTCCH/D block */
712 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
713 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
714 arfcn := 871, block_nr := 0));
715 T.start(2.0);
716 alt {
717 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
718 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
719 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
720 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
721 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
722 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
723 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
724 log("Rx PTCCH/D message: ", ta_msg);
725
726 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700727 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200728 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
729 }
730 }
731 [] BTS.receive { repeat; }
732 [] T.timeout {
733 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200734 }
735 }
736}
737
738testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
739 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200740 var GprsMS ms;
741
742 /* Initialize GPRS MS side */
743 f_init_gprs_ms();
744 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200745
746 /* Initialize the PCU interface abstraction */
747 f_init_raw(testcasename());
748
749 /* Enable forwarding of PTCCH/U TDMA events to us */
750 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
751
752 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
753 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200754 /* Establish an Uplink TBF */
755 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200756
757 /* We expect incremental TFI/USF assignment (dynamic allocation) */
758 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200759 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200760 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700761 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200762 }
763
764 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200765 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200766 setverdict(fail, "Failed to match Timing Advance Index for #", i);
767 /* Keep going, the current OsmoPCU does not assign TA Index */
768 }
769 }
770
771 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
772 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
773 for (var integer i := 0; i < 7; i := i + 1) {
774 /* ToA in units of 1/4 of a symbol */
775 toa_map[i] := (i + 1) * 7 * 4;
776 }
777
778 /* Now we have all 7 TBFs established in one-phase access mode,
779 * however we will not be sending any data on them. Instead, we
780 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
781 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
782 *
783 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
784 * time-slots, so at the moment of scheduling a PTCCH/D block
785 * the PCU has odd number of PTCCH/U Access Bursts received. */
786 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
787 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
788 /* Other values are not known (yet) */
789 tai3_ta := ?));
790 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
791 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
792 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
793 /* Other values are out of our interest */
794 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700795
796 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200797}
798
799/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
800 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
801 *
802 * NOTE: the ranges are intentionally overlapping because OsmoPCU
803 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
804private template integer CS1_lqual_dB_range := (-infinity .. 6);
805private template integer CS2_lqual_dB_range := (5 .. 8);
806private template integer CS3_lqual_dB_range := (7 .. 13);
807private template integer CS4_lqual_dB_range := (12 .. infinity);
808
809testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200810 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200811 var GprsMS ms;
812 var uint32_t unused_fn, sched_fn;
813 var uint4_t cv;
814
815 /* Initialize GPRS MS side */
816 f_init_gprs_ms();
817 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200818
819 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100820 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200821
822 f_pcuvty_set_allowed_cs_mcs();
823 f_pcuvty_set_link_quality_ranges();
824
825 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200826 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200827
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200828
829 /* The actual / old link quality values. We need to keep track of the old
830 * (basically previous) link quality value, because OsmoPCU actually
831 * changes the coding scheme if not only the actual, but also the old
832 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200833 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200834 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200835
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200836 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200837 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200838 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
839 /* 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 +0200840 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 +0200841 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
842 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
843 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200844
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
846 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200847 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200848 lqual_old := ms.lqual_cb;
849 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200850
851 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200852 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
853 if (i > g_bs_cv_max) {
854 cv := 15;
855 } else {
856 cv := i;
857 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200858
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200859 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
860
861 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
862 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700863 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200864 continue;
865 }
866 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
867 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
868 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
869 f_shutdown(__BFILE__, __LINE__);
870 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200871
872 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
873 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
874
875 /* Match the received Channel Coding Command. Since we are increasing
876 * the link quality value on each iteration and not decreasing, there
877 * is no need to check the both old and current link quality values. */
878 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200879 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200880 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
881 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
882 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
883 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
884 }
885
886 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
887 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200888 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200889 }
890 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700891
892 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200893}
894
895/* Test the max UL CS set by VTY works fine */
896testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200897 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200898 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200899 var uint32_t unused_fn, sched_fn;
900 var GprsMS ms;
901
902 /* Initialize GPRS MS side */
903 f_init_gprs_ms();
904 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200905
906 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100907 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200908
909 /* Set initial UL CS to 3 */
910 g_cs_initial_ul := 3;
911 f_pcuvty_set_allowed_cs_mcs();
912 f_pcuvty_set_link_quality_ranges();
913
914 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200915 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200916
917 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200918 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200919
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200920 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200921 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200922 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
923 /* 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 +0200924 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 +0200925 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
926 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
927 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200928
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200929 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
930 while (true) {
931 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
932 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700933 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200934 continue;
935 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200936
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200937 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
938 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
939 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
940 f_shutdown(__BFILE__, __LINE__);
941 break;
942 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200943
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200944 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200945 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200946 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200947 if (last_ch_coding != CH_CODING_CS3) {
948 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200949 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200950 }
951
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200952 /* Remaining UL blocks are used to make sure regardless of initial
953 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200954 /* 0 dB, make sure we downgrade CS */
955 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200956 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200957 f_ms_tx_ul_data_block_multi(ms, 5);
958 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
959 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
960 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200961
962 if (last_ch_coding != CH_CODING_CS1) {
963 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200964 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200965 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700966
967 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200968}
969
970/* Test the max UL CS set by VTY works fine */
971testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200972 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200973 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200974 var uint32_t unused_fn, sched_fn;
975 var GprsMS ms;
976
977 /* Initialize GPRS MS side */
978 f_init_gprs_ms();
979 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200980
981 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100982 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200983
984 /* Set maximum allowed UL CS to 3 */
985 g_cs_max_ul := 3;
986 f_pcuvty_set_allowed_cs_mcs();
987 f_pcuvty_set_link_quality_ranges();
988
989 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200990 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200991
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200992 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200993 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200994 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
995 /* 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 +0200996 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 +0200997 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
998 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
999 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001000
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001001 ms.lqual_cb := 40*10; /* 40 dB */
1002 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001003
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001004 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1005 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001006
1007 if (last_ch_coding != CH_CODING_CS3) {
1008 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001009 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001010 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001011
1012 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001013}
1014
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001015/* Test the initial DL CS set by VTY works fine */
1016testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1017 var octetstring data := f_rnd_octstring(10);
1018 var CodingScheme exp_dl_cs_mcs;
1019 var RlcmacDlBlock dl_block;
1020 var uint32_t poll_fn;
1021 var GprsMS ms;
1022
1023 /* Initialize NS/BSSGP side */
1024 f_init_bssgp();
1025 /* Initialize GPRS MS side */
1026 f_init_gprs_ms();
1027 ms := g_ms[0]; /* We only use first MS in this test */
1028
1029 /* Initialize the PCU interface abstraction */
1030 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1031
1032 /* Set initial allowed DL CS to 3 */
1033 g_cs_initial_dl := 3;
1034 exp_dl_cs_mcs := CS_3;
1035 /* Set maximum allowed UL CS to 4 */
1036 g_cs_max_dl := 4;
1037 f_pcuvty_set_allowed_cs_mcs();
1038 f_pcuvty_set_link_quality_ranges();
1039
1040 /* Establish BSSGP connection to the PCU */
1041 f_bssgp_establish();
1042 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1043
1044 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1045 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1046 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1047
1048 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1049 f_sleep(X2002);
1050 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1051
1052 /* ACK the DL block */
1053 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1054 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1055 f_dl_block_ack_fn(dl_block, poll_fn));
1056
1057 f_shutdown(__BFILE__, __LINE__, final := true);
1058}
1059
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001060/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001061function 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 +01001062 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001063 var RlcmacDlBlock prev_dl_block, dl_block;
1064 var uint32_t ack_fn;
1065 var uint32_t fn;
1066 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001067 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001068 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001069 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1070 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001071 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001072
1073 if (using_egprs) {
1074 exp_tmp_csmcs := mcs_egprs_any;
1075 bsn_mod := 2048;
1076 } else {
1077 exp_tmp_csmcs := cs_gprs_any;
1078 bsn_mod := 128;
1079 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001080
1081 /* Establish BSSGP connection to the PCU */
1082 f_bssgp_establish();
1083
1084 ms := g_ms[0]; /* We only use first MS in this test */
1085 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1086
1087 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001088 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001089 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1090
1091 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1092 f_sleep(X2002);
1093
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001094 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
1095 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
1096
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001097 for (var integer i := 0; i < 800; i := i + 1) {
1098 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001099
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001100 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001101 /* No more data to receive, done */
1102 break;
1103 }
1104
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001105 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001106
1107 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001108 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001109
1110 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001111 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001112 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001113 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 +01001114 if (tx_data_remain != 0) {
1115 /* Submit more data from time to time to keep the TBF ongoing */
1116 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1117 tx_data_remain := tx_data_remain - 1;
1118 }
1119 }
1120 prev_dl_block := dl_block;
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001121 f_rx_rlcmac_dl_block(dl_block, fn);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001122 }
1123
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001124 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1125 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001126
1127
1128 f_shutdown(__BFILE__, __LINE__, final := true);
1129}
1130
1131/* Verify DL CS above "cs max" set by VTY is never used */
1132testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1133 /* Initialize NS/BSSGP side */
1134 f_init_bssgp();
1135 /* Initialize GPRS MS side */
1136 f_init_gprs_ms();
1137
1138 /* Initialize the PCU interface abstraction */
1139 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1140
1141 /* Set maximum allowed DL CS to 3 */
1142 g_cs_initial_dl := 1;
1143 g_cs_max_dl := 3;
1144 f_pcuvty_set_allowed_cs_mcs();
1145 f_pcuvty_set_link_quality_ranges();
1146
1147 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001148
1149 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001150}
1151
1152/* Check DL CS4 is used in good link conditions if allowed by config */
1153testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1154 /* Initialize NS/BSSGP side */
1155 f_init_bssgp();
1156 /* Initialize GPRS MS side */
1157 f_init_gprs_ms();
1158
1159 /* Initialize the PCU interface abstraction */
1160 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1161
1162 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1163 g_cs_initial_dl := 1;
1164 g_cs_max_dl := 4;
1165 f_pcuvty_set_allowed_cs_mcs();
1166 f_pcuvty_set_link_quality_ranges();
1167
1168 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02001169
1170 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001171}
1172
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001173/* Test the initial UL MCS set by VTY works fine */
1174testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1175 var RlcmacDlBlock dl_block;
1176 var PollFnCtx pollctx;
1177 var EgprsChCodingCommand last_ch_coding;
1178 var uint32_t unused_fn, sched_fn;
1179 var GprsMS ms;
1180 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001181
1182 /* Initialize GPRS MS side */
1183 f_init_gprs_ms();
1184 ms := g_ms[0]; /* We only use first MS in this test */
1185
1186 /* Initialize the PCU interface abstraction */
1187 f_init_raw(testcasename());
1188
1189 /* Set initial UL MCS to 3 */
1190 g_mcs_initial_ul := 3;
1191 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1192 f_pcuvty_set_allowed_cs_mcs();
1193 f_pcuvty_set_link_quality_ranges();
1194
1195 /* Take lqual (dB->cB) so that we stay in that MCS */
1196 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1197
1198 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001199 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 +01001200
1201 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1202 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1203 f_shutdown(__BFILE__, __LINE__);
1204 }
1205
1206 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1207 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1208
1209 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1210 while (true) {
1211 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1212 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001213 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001214 continue;
1215 }
1216
1217 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1218 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1219 f_shutdown(__BFILE__, __LINE__);
1220 break;
1221 }
1222
1223 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1224 break;
1225 }
1226 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1227 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1228 f_shutdown(__BFILE__, __LINE__);
1229 }
1230
1231 /* Remaining UL blocks are used to make sure regardless of initial
1232 * lqual, we can go lower at any time
1233 * 0 dB, make sure we downgrade MCS */
1234 ms.lqual_cb := 0;
1235 /* 5 UL blocks, check we are in same initial MCS: */
1236 f_ms_tx_ul_data_block_multi(ms, 5);
1237 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1238 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1239 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1240
1241 if (last_ch_coding != CH_CODING_MCS1) {
1242 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1243 f_shutdown(__BFILE__, __LINE__);
1244 }
1245
1246 f_shutdown(__BFILE__, __LINE__, final := true);
1247}
1248
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001249/* Test the maximum UL MCS set by VTY works fine */
1250testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1251 var RlcmacDlBlock dl_block;
1252 var EgprsChCodingCommand last_ch_coding;
1253 var PollFnCtx pollctx;
1254 var uint32_t unused_fn, sched_fn;
1255 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001256
1257 /* Initialize GPRS MS side */
1258 f_init_gprs_ms();
1259 ms := g_ms[0]; /* We only use first MS in this test */
1260
1261 /* Initialize the PCU interface abstraction */
1262 f_init_raw(testcasename());
1263
1264 /* Set maximum allowed UL MCS to 5 */
1265 g_mcs_max_ul := 5;
1266 f_pcuvty_set_allowed_cs_mcs();
1267 f_pcuvty_set_link_quality_ranges();
1268
1269 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001270 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 +01001271 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1272 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1273
1274 ms.lqual_cb := 40*10; /* 40 dB */
1275 f_ms_tx_ul_data_block_multi(ms, 16);
1276
1277 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1278 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1279
1280 if (last_ch_coding != CH_CODING_MCS5) {
1281 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1282 f_shutdown(__BFILE__, __LINE__);
1283 }
1284
1285 f_shutdown(__BFILE__, __LINE__, final := true);
1286}
1287
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001288/* Test the initial DL CS set by VTY works fine */
1289testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1290 var octetstring data := f_rnd_octstring(10);
1291 var CodingScheme exp_dl_cs_mcs;
1292 var RlcmacDlBlock dl_block;
1293 var uint32_t poll_fn;
1294 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001295
1296 /* Initialize NS/BSSGP side */
1297 f_init_bssgp();
1298 /* Initialize GPRS MS side */
1299 f_init_gprs_ms();
1300 ms := g_ms[0]; /* We only use first MS in this test */
1301
1302 /* Initialize the PCU interface abstraction */
1303 f_init_raw(testcasename());
1304
1305 /* Set initial allowed DL MCS to 3 */
1306 g_mcs_initial_dl := 3;
1307 exp_dl_cs_mcs := MCS_3;
1308 /* Set maximum allowed DL MCS to 4 */
1309 g_mcs_max_dl := 4;
1310 f_pcuvty_set_allowed_cs_mcs();
1311 f_pcuvty_set_link_quality_ranges();
1312
1313 /* Establish BSSGP connection to the PCU */
1314 f_bssgp_establish();
1315 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1316
1317 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001318 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001319 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1320
1321 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1322 f_sleep(X2002);
1323 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1324
1325 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001326 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1327 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 +01001328 f_dl_block_ack_fn(dl_block, poll_fn));
1329
1330 f_shutdown(__BFILE__, __LINE__, final := true);
1331}
1332
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001333/* Verify DL MCS above "mcs max" set by VTY is never used */
1334testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1335 /* Initialize NS/BSSGP side */
1336 f_init_bssgp();
1337 /* Initialize GPRS MS side */
1338 f_init_gprs_ms();
1339
1340 /* Initialize the PCU interface abstraction */
1341 f_init_raw(testcasename());
1342
1343 /* Set maximum allowed DL CS to 3 */
1344 g_mcs_initial_dl := 1;
1345 g_mcs_max_dl := 3;
1346 f_pcuvty_set_allowed_cs_mcs();
1347 f_pcuvty_set_link_quality_ranges();
1348
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001349 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 +02001350
1351 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001352}
1353
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001354/* Verify PCU drops TBF after some time of inactivity. */
1355testcase TC_t3141() runs on RAW_PCU_Test_CT {
1356 var PCUIF_info_ind info_ind;
1357 var template (value) TsTrxBtsNum nr;
1358 var BTS_PDTCH_Block data_msg;
1359 var GprsMS ms;
1360 var uint3_t rx_usf;
1361 timer T_3141 := 1.0;
1362 var boolean ul_tbf_usf_req := false;
1363
1364 /* Initialize NS/BSSGP side */
1365 f_init_bssgp();
1366 /* Initialize GPRS MS side */
1367 f_init_gprs_ms();
1368 ms := g_ms[0]; /* We only use first MS in this test */
1369
1370 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1371 /* Only use 1 PDCH to simplify test: */
1372 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1373 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1374 /* Initialize the PCU interface abstraction */
1375 f_init_raw(testcasename(), info_ind);
1376
1377 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1378
1379 /* Establish BSSGP connection to the PCU */
1380 f_bssgp_establish();
1381 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1382
1383 /* Establish a one-phase access Uplink TBF */
1384 f_ms_establish_ul_tbf(ms);
1385
1386 T_3141.start;
1387
1388 /* Now we wait for PCU to transmit our USF */
1389 nr := ts_TsTrxBtsNum;
1390 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1391 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1392 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1393 block_nr := nr.blk_nr));
1394
1395 alt {
1396 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1397 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1398 ?)) -> value data_msg {
1399 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1400 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1401 f_shutdown(__BFILE__, __LINE__);
1402 }
1403
1404 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1405 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1406 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1407 ul_tbf_usf_req := true;
1408 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))
1409 } else if (rx_usf == USF_UNUSED) {
1410 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1411 if (ul_tbf_usf_req) {
1412 /* TBF was dropped by T3141, success */
1413 setverdict(pass);
1414 break;
1415 } else {
1416 log("PCU never requested USF, unexpected");
1417 f_shutdown(__BFILE__, __LINE__);
1418 }
1419 } /* else: Keep waiting for TBF to be active by network */
1420 } else {
1421 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1422 f_shutdown(__BFILE__, __LINE__);
1423 }
1424
1425 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1426 if (match(data_msg.dl_block,
1427 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1428 tr_UlAckNackGprs(tlli := ?,
1429 acknack_desc := ?,
1430 rel99 := *))))
1431 {
1432 log("Received UL ACK/NACK with TLLI set");
1433 f_shutdown(__BFILE__, __LINE__);
1434 }
1435
1436 nr := ts_TsTrxBtsNum;
1437 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1438 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1439 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1440 block_nr := nr.blk_nr));
1441 repeat;
1442 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001443 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1444 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1445 omit)) {
1446 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1447 our last RTS.req because there's no longer any MS listening on
1448 the TS. */
1449 setverdict(pass);
1450 break;
1451 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001452 [] T_3141.timeout {
1453 log("T_3141 expired but TBF is still active, unexpected");
1454 f_shutdown(__BFILE__, __LINE__);
1455 }
1456 [] BTS.receive {
1457 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1458 * because we never sent the TLLI to the PCU */
1459 setverdict(fail, "Unexpected BTS message");
1460 f_shutdown(__BFILE__, __LINE__);
1461 }
1462 }
1463
1464 f_shutdown(__BFILE__, __LINE__, final := true);
1465}
1466
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001467/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1468 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1469 * T3169. See OS#5033 */
1470testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1471 var PCUIF_info_ind info_ind;
1472 var template (value) TsTrxBtsNum nr;
1473 var BTS_PDTCH_Block data_msg;
1474 var GprsMS ms;
1475 var uint3_t rx_usf;
1476 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1477 var integer n3101 := 0;
1478 timer T_3169 := 1.0;
1479
1480 /* Initialize NS/BSSGP side */
1481 f_init_bssgp();
1482 /* Initialize GPRS MS side */
1483 f_init_gprs_ms();
1484 ms := g_ms[0]; /* We only use first MS in this test */
1485
1486 /* Initialize the PCU interface abstraction */
1487 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1488 info_ind.n3101 := N3101_MAX;
1489 info_ind.t3169 := 1;
1490 f_init_raw(testcasename(), info_ind);
1491
1492 /* Establish BSSGP connection to the PCU */
1493 f_bssgp_establish();
1494 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1495
1496 /* Establish UL TBF */
1497 f_ms_establish_ul_tbf(ms);
1498
1499 /* Now we wait for PCU to transmit our USF */
1500 nr := ts_TsTrxBtsNum;
1501 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1502 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1503 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1504 block_nr := nr.blk_nr));
1505
1506 alt {
1507 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1508 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1509 ?)) -> value data_msg {
1510 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1511 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1512 f_shutdown(__BFILE__, __LINE__);
1513 }
1514
1515 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1516 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1517 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1518 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001519 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1520 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001521 f_shutdown(__BFILE__, __LINE__);
1522 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001523 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001524 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1525 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1526 if (not T_3169.running) {
1527 log("T3169 started");
1528 T_3169.start;
1529 }
1530 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1531 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1532 f_shutdown(__BFILE__, __LINE__);
1533 } else {
1534 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1535 }
1536 nr := ts_TsTrxBtsNum;
1537 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1538 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1539 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1540 block_nr := nr.blk_nr));
1541 repeat;
1542 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001543 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1544 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001545 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001546 [] T_3169.timeout {
1547 log("T_3169 expired");
1548 /* Done in alt */
1549 }
1550 [] BTS.receive {
1551 setverdict(fail, "Unexpected BTS message");
1552 f_shutdown(__BFILE__, __LINE__);
1553 }
1554 }
1555
1556 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1557 /* USFs as per previous TBF since they were freed at expiration time: */
1558 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1559 var uint5_t old_tfi := ms.ul_tbf.tfi;
1560 f_ms_establish_ul_tbf(ms);
1561 if (old_tfi != ms.ul_tbf.tfi) {
1562 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1563 f_shutdown(__BFILE__, __LINE__);
1564 }
1565 for (var integer i := 0; i < 8; i := i +1) {
1566 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1567 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1568 f_shutdown(__BFILE__, __LINE__);
1569 }
1570 }
1571
1572 f_shutdown(__BFILE__, __LINE__, final := true);
1573}
1574
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001575
1576/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1577 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1578 the final UL ACK sent at us. */
1579testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1580 var PCUIF_info_ind info_ind;
1581 var BTS_PDTCH_Block data_msg;
1582 var RlcmacDlBlock dl_block;
1583 var uint32_t sched_fn;
1584 var template (value) TsTrxBtsNum nr;
1585 var template RlcmacDlBlock exp_ul_ack;
1586 var template UlAckNackGprs exp_ul_ack_sub;
1587 var GprsMS ms;
1588 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1589 var integer N3103 := 0;
1590 timer T_3169 := 1.0;
1591
1592 /* Initialize GPRS MS side */
1593 f_init_gprs_ms();
1594 ms := g_ms[0]; /* We only use first MS in this test */
1595
1596 /* Initialize the PCU interface abstraction */
1597 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1598 info_ind.n3103 := N3103_MAX;
1599 info_ind.t3169 := 1;
1600 f_init_raw(testcasename(), info_ind);
1601
1602 /* Establish an Uplink TBF */
1603 f_ms_establish_ul_tbf(ms);
1604
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001605 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001606 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1607 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1608
1609 nr := ts_TsTrxBtsNum;
1610 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1611 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1612 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1613 block_nr := nr.blk_nr));
1614 alt {
1615 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1616 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1617 exp_ul_ack)) -> value data_msg {
1618 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1619 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1620 f_shutdown(__BFILE__, __LINE__);
1621 }
1622
1623 nr := ts_TsTrxBtsNum;
1624 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1625 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1626 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1627 block_nr := nr.blk_nr));
1628 N3103 := N3103 + 1;
1629 if (N3103 == N3103_MAX) {
1630 /* At this point in time (N3103_MAX reached), PCU is
1631 * moving the TBF to RELEASE state so no data/ctrl for
1632 * it is tx'ed, hence the dummy blocks: */
1633 T_3169.start;
1634 }
1635 repeat;
1636 }
1637 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1638 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1639 exp_ul_ack)) -> value data_msg {
1640 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1641 f_shutdown(__BFILE__, __LINE__);
1642 }
1643 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001644 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001645 [T_3169.running] T_3169.timeout {
1646 log("T_3169 timeout");
1647 /* Done in alt, wait for pending RTS initiated previously in
1648 * above case before continuing (expect /* Dummy block): */
1649 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1650 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001651 tr_RLCMAC_DL_DUMMY_CTRL));
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001652 }
1653 [] BTS.receive {
1654 setverdict(fail, "Unexpected BTS message");
1655 f_shutdown(__BFILE__, __LINE__);
1656 }
1657 }
1658
1659 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1660 * USFs as per previous TBF since they were freed at expiration time: */
1661 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1662 var uint5_t old_tfi := ms.ul_tbf.tfi;
1663 f_ms_establish_ul_tbf(ms);
1664 if (old_tfi != ms.ul_tbf.tfi) {
1665 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1666 f_shutdown(__BFILE__, __LINE__);
1667 }
1668 for (var integer i := 0; i < 8; i := i +1) {
1669 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1670 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1671 f_shutdown(__BFILE__, __LINE__);
1672 }
1673 }
1674
1675 f_shutdown(__BFILE__, __LINE__, final := true);
1676}
1677
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001678/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1679 * point the TBF is no longer available. In order to get to start of T3191, we
1680 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1681 * until TBF release procedure starts after draining DL queue. */
1682testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1683 var PCUIF_info_ind info_ind;
1684 var RlcmacDlBlock dl_block;
1685 var octetstring data1 := f_rnd_octstring(200);
1686 var octetstring data2 := f_rnd_octstring(10);
1687 var uint32_t dl_fn;
1688 var template (value) TsTrxBtsNum nr;
1689 var BTS_PDTCH_Block data_msg;
1690 var GprsMS ms;
1691
1692 /* Initialize NS/BSSGP side */
1693 f_init_bssgp();
1694 /* Initialize GPRS MS side */
1695 f_init_gprs_ms();
1696 ms := g_ms[0]; /* We only use first MS in this test */
1697
1698 /* Initialize the PCU interface abstraction */
1699 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1700 /* Set timer to 1 sec (default 5) to speedup test: */
1701 info_ind.t3191 := 1;
1702 f_init_raw(testcasename(), info_ind);
1703
1704 /* Establish BSSGP connection to the PCU */
1705 f_bssgp_establish();
1706 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1707
1708 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1709 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1710 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1711
1712 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1713 f_sleep(X2002);
1714
1715 while (true) {
1716 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1717
1718 /* Keep Ack/Nack description updated (except for last BSN) */
1719 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1720
1721 if (f_dl_block_rrbp_valid(dl_block)) {
1722 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1723 f_dl_block_ack_fn(dl_block, dl_fn));
1724 break;
1725 }
1726 }
1727
1728 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1729 nr := ts_TsTrxBtsNum;
1730 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1731 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1732 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1733 block_nr := nr.blk_nr));
1734 alt {
1735 [] as_ms_rx_ignore_dummy(ms, nr);
1736 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1737 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1738 ?)) -> value data_msg {
1739 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1740 log("Received FINAL_ACK");
1741 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1742 break;
1743 }
1744 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1745 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1746 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1747 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1748 }
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 repeat;
1755 }
1756 [] BTS.receive {
1757 setverdict(fail, "Unexpected BTS message");
1758 f_shutdown(__BFILE__, __LINE__);
1759 }
1760 }
1761
1762 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1763 to time out. We simply sleep instead of requesting blocks because
1764 otherwise retransmissions would keep restarting the timer. */
1765 f_sleep(int2float(info_ind.t3191));
1766
1767 /* The TBF should be freed now, so new data should trigger an Assignment: */
1768 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1769 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1770
1771 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1772 f_sleep(X2002);
1773 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1774 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1775 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1776 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1777 f_dl_block_ack_fn(dl_block, dl_fn));
1778
1779 f_shutdown(__BFILE__, __LINE__, final := true);
1780}
1781
1782/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1783testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1784 var PCUIF_info_ind info_ind;
1785 var RlcmacDlBlock dl_block;
1786 var octetstring data1 := f_rnd_octstring(1400);
1787 var octetstring data2 := f_rnd_octstring(10);
1788 var uint32_t dl_fn;
1789 var GprsMS ms;
1790
1791 /* Initialize NS/BSSGP side */
1792 f_init_bssgp();
1793 /* Initialize GPRS MS side */
1794 f_init_gprs_ms();
1795 ms := g_ms[0]; /* We only use first MS in this test */
1796
1797 /* Initialize the PCU interface abstraction */
1798 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1799 /* Set timer to 1 sec (default 5) to speedup test: */
1800 info_ind.t3191 := 1;
1801 f_init_raw(testcasename(), info_ind);
1802
1803 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1804
1805 /* Establish BSSGP connection to the PCU */
1806 f_bssgp_establish();
1807 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1808
1809 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1810 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1811 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1812
1813 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1814 f_sleep(X2002);
1815
1816 /* Send enough DL data to at least be able to DL ACK once (excl the
1817 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1818 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1819 while (true) {
1820 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1821
1822 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1823 log("Received FINAL_ACK");
1824 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1825 break;
1826 }
1827
1828 /* Keep Ack/Nack description updated (except for last BSN) */
1829 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1830
1831 if (f_dl_block_rrbp_valid(dl_block)) {
1832 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1833 f_dl_block_ack_fn(dl_block, dl_fn));
1834 }
1835 }
1836
1837 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1838 to time out. We simply sleep instead of requesting blocks because
1839 otherwise retransmissions would keep restarting the timer. */
1840 f_sleep(int2float(info_ind.t3191));
1841
1842 /* The TBF should be freed now, so new data should trigger an Assignment: */
1843 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1844 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1845
1846 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1847 f_sleep(X2002);
1848 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1849 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1850 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1851 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1852 f_dl_block_ack_fn(dl_block, dl_fn));
1853
1854 f_shutdown(__BFILE__, __LINE__, final := true);
1855}
1856
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001857/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1858 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1859 * T3193) after DL TBF release */
1860testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001861 var RlcmacDlBlock dl_block;
1862 var octetstring data := f_rnd_octstring(10);
1863 var boolean ok;
1864 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001865 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001866 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001867 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1868
1869 /* Initialize NS/BSSGP side */
1870 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001871 /* Initialize GPRS MS side */
1872 f_init_gprs_ms();
1873 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001874
1875 /* Initialize the PCU interface abstraction */
1876 f_init_raw(testcasename());
1877
1878 /* Establish BSSGP connection to the PCU */
1879 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001880 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001881
1882 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001883 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1884 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001885
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001886 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1887 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001888 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001889
1890 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001891 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1892 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1893 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001894
1895 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001896 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001897 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001898 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001899 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001900
1901 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001902
1903 /* 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 +07001904 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001905 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1906 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1907 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001908
1909 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001910}
1911
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001912/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1913 freed and no longer available. Trigger it by sending DL blocks and never DL
1914 ACKing the data (which are requested through RRBP) */
1915testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1916 var PCUIF_info_ind info_ind;
1917 var RlcmacDlBlock dl_block;
1918 var octetstring data1 := f_rnd_octstring(1000);
1919 var octetstring data2 := f_rnd_octstring(10);
1920 var uint32_t dl_fn;
1921 var template (value) TsTrxBtsNum nr;
1922 var BTS_PDTCH_Block data_msg;
1923 var GprsMS ms;
1924 const integer N3105_MAX := 2;
1925 var integer N3105 := 0;
1926 timer T_3195 := 1.0;
1927 var integer num_poll_recv := 0;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001928 var template RlcmacDlBlock dl_block_exp;
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001929
1930 /* Initialize NS/BSSGP side */
1931 f_init_bssgp();
1932 /* Initialize GPRS MS side */
1933 f_init_gprs_ms();
1934 ms := g_ms[0]; /* We only use first MS in this test */
1935
1936 /* Initialize the PCU interface abstraction */
1937 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1938 /* Speedup test: */
1939 info_ind.n3105 := N3105_MAX;
1940 info_ind.t3195 := 1;
1941 f_init_raw(testcasename(), info_ind);
1942
1943 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1944 * MS and retransmitted after the TBF is released and later on created
1945 * (because the MS is reused) */
1946 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1947
1948 /* Establish BSSGP connection to the PCU */
1949 f_bssgp_establish();
1950 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1951
1952 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1953 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1954 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1955
1956 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1957 f_sleep(X2002);
1958
1959 /* Now we go on receiving DL data and not answering RRBP: */
1960 nr := ts_TsTrxBtsNum;
1961 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1962 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1963 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1964 block_nr := nr.blk_nr));
1965 alt {
1966 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1967 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1968 tr_RLCMAC_DATA)) -> value data_msg {
1969 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1970 if (num_poll_recv == 0) {
1971 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1972 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1973 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1974 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1975 } else {
1976 log("Ignoring RRBP ", num_poll_recv);
1977 N3105 := N3105 + 1;
1978 }
1979 num_poll_recv := num_poll_recv + 1;
1980 }
1981
1982 nr := ts_TsTrxBtsNum;
1983 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1984 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1985 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1986 block_nr := nr.blk_nr));
1987 repeat;
1988 }
1989 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001990 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001991 */
1992 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1993 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001994 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001995 if (not T_3195.running) {
1996 T_3195.start;
1997 /* We even send some new data, nothing should be sent to MS */
1998 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1999 }
2000 nr := ts_TsTrxBtsNum;
2001 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2002 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2003 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2004 block_nr := nr.blk_nr));
2005 repeat;
2006 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01002007 /* We may already receive idle blocks before our own TTCN3 timer
2008 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002009 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002010 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002011 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002012 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002013 * above case before continuing (expect empty block): */
2014 dl_block_exp := omit;
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002015 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2016 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002017 dl_block_exp));
2018 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002019 [] BTS.receive {
2020 setverdict(fail, "Unexpected BTS message");
2021 f_shutdown(__BFILE__, __LINE__);
2022 }
2023 }
2024
2025 /* after T_3195 timeout, TBF is released */
2026 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
2027 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2028
2029 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2030 f_sleep(X2002);
2031 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2032
2033 /* ACK the DL block */
2034 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2035 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2036 f_dl_block_ack_fn(dl_block, dl_fn));
2037
2038 f_shutdown(__BFILE__, __LINE__, final := true);
2039}
2040
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002041/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2042function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2043 var PCUIF_info_ind info_ind;
2044 var template IARRestOctets rest;
2045 var BIT11 ra11;
2046 var GprsMS ms;
2047 var octetstring data := f_rnd_octstring(10);
2048 var RlcmacDlBlock dl_block;
2049 var template RlcmacDlBlock rej_tmpl;
2050 var uint32_t dl_fn;
2051 var uint32_t sched_fn;
2052 var uint8_t wait_ind_val;
2053
2054 /* Initialize NS/BSSGP side */
2055 f_init_bssgp();
2056 /* Initialize GPRS MS side */
2057 f_init_gprs_ms();
2058 ms := g_ms[0]; /* We only use first MS in this test */
2059
2060 info_ind := valueof(ts_PCUIF_INFO_default);
2061
2062 /* Only the first TRX is enabled. */
2063 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2064 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2065
2066 /* Initialize the PCU interface abstraction */
2067 f_init_raw(testcasename(), info_ind);
2068
2069 f_pcuvty_set_timer(3172, t3172_ms);
2070
2071 /* Establish BSSGP connection to the PCU */
2072 f_bssgp_establish();
2073 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2074
2075 var EGPRSPktChRequest req := {
2076 one_phase := {
2077 tag := '0'B,
2078 multislot_class := '10101'B,
2079 priority := '01'B,
2080 random_bits := '101'B
2081 }
2082 };
2083
2084 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2085 for (var integer i := 0; i < 7; i := i + 1) {
2086 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2087 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2088 }
2089
2090 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2091 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2092 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2093
2094 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2095 f_sleep(X2002);
2096 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2097
2098 /* ACK the DL block */
2099 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2100 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2101 f_dl_block_ack_fn(dl_block, dl_fn));
2102
2103 /* Since all USF are taken, we should receive a Reject: */
2104
2105 if (wait_ind_size == '0'B) {
2106 wait_ind_val := t3172_ms / 1000;
2107 } else {
2108 wait_ind_val := t3172_ms / 20;
2109 }
2110 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2111 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2112 wait_ind_val,
2113 wait_ind_size)));
2114 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2115 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2116 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2117 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2118 block_nr := nr.blk_nr));
2119 alt {
2120 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2121 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2122 rej_tmpl));
2123 [] BTS.receive {
2124 setverdict(fail, "Unexpected BTS message");
2125 f_shutdown(__BFILE__, __LINE__);
2126 }
2127 }
2128 f_shutdown(__BFILE__, __LINE__, final := true);
2129}
2130testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2131 /* size=0 means value is provided in seconds. Due to value being 8
2132 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2133 * = 5100. Hence, values above it should use size=0 to be able to
2134 * provide values in range. Let's use 6 seconds, 6000ms
2135 */
2136 f_TC_t3172(6000, '0'B);
2137}
2138testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2139 f_TC_t3172(3000, '1'B);
2140}
2141
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002142/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2143testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002144 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002145 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002146 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002147 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002148
2149 /* Initialize NS/BSSGP side */
2150 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002151 /* Initialize GPRS MS side */
2152 f_init_gprs_ms();
2153 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002154
2155 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002156 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002157
2158 /* Establish BSSGP connection to the PCU */
2159 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002160 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002161
2162 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002163 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002164
2165 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002166 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002167 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002168 /* 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 +02002169 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 +02002170 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2171 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002172 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002173
2174 /* Send enough blocks to test whole procedure: Until Nth block
2175 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2176 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002177 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002178 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2179 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002180 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002181
2182 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002183 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 +07002184
2185 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002186}
2187
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002188/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2189testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2190 var RlcmacDlBlock dl_block;
2191 var uint32_t dl_fn, sched_fn;
2192 var octetstring payload;
2193 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002194 var template (value) LlcBlockHdr blk_hdr;
2195 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002196 var integer blk_len;
2197 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002198 var GprsMS ms;
2199
2200 /* Initialize NS/BSSGP side */
2201 f_init_bssgp();
2202 /* Initialize GPRS MS side */
2203 f_init_gprs_ms();
2204 ms := g_ms[0]; /* We only use first MS in this test */
2205
2206 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002207 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002208
2209 /* Establish BSSGP connection to the PCU */
2210 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002211 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002212
2213 /* Establish an Uplink TBF */
2214 f_ms_establish_ul_tbf(ms);
2215
2216 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002217 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002218 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002219 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2220 more := false, e := true);
2221 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002222 /* 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 +01002223 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2224 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002225 cv := 15,
2226 bsn := ms.ul_tbf.bsn,
2227 blocks := blocks,
2228 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002229 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002230 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002231
2232 /* ACK and check it was received fine */
2233 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2234 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2235 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2236 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002237 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 +02002238
2239 /* Test sending LLC PDUS of incrementing size */
2240 var integer max_size := 49;
2241 for (var integer i := 1; i <= max_size; i := i + 1) {
2242 var integer cv;
2243 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2244 log("Sending DATA.ind with LLC payload size ", i);
2245 if (i < max_size - g_bs_cv_max) {
2246 cv := 15;
2247 } else {
2248 cv := max_size - i;
2249 }
2250
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002251 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2252 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002253 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002254 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2255 more := false, e := true);
2256 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002257 /* 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 +01002258 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2259 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002260 cv := cv,
2261 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002262 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002263 f_ultbf_inc_bsn(ms.ul_tbf);
2264 f_ms_tx_ul_block(ms, ul_data);
2265
2266 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002267 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 +02002268
2269 /* we will receive UL ACK/NACK from time to time, handle it. */
2270 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002271 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002272 continue;
2273 }
2274 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2275 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2276 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2277 f_shutdown(__BFILE__, __LINE__);
2278 }
2279
2280 log("Rx Packet Uplink ACK / NACK");
2281 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2282 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2283 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2284 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002285
2286 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002287}
2288
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002289function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2290 var octetstring payload;
2291 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002292 var template (value) LlcBlockHdr blk_hdr;
2293 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002294 var integer block_len, max_valid_data_len;
2295 timer T;
2296
2297 block_len := f_rlcmac_cs_mcs2block_len(cs);
2298 /* We need to send with TLLI since we are in One-Phase Access Contenion
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002299 * resolution), so that's -4 bytes of data, -3 for headers, -1 for LI
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002300 * indicator, -1 for spare bits octet at the end */
2301 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2302 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 +07002303 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2304 more := false, e := true);
2305 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002306 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2307 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002308 cv := cv,
2309 bsn := ms.ul_tbf.bsn,
2310 blocks := blocks,
2311 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002312 f_ultbf_inc_bsn(ms.ul_tbf);
2313 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2314
2315 T.start(0.5);
2316 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002317 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002318 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2319 f_shutdown(__BFILE__, __LINE__);
2320 }
2321 [] T.timeout {
2322 setverdict(pass);
2323 }
2324 }
2325}
2326/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2327 blocks intentionally contain last byte of data placed in last byte of RLC
2328 containing padding/spare bits, which is incorrect. Spare bits exist and are
2329 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2330 discounting padding in octet" */
2331testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2332 var GprsMS ms;
2333 var integer block_len, max_valid_data_len;
2334
2335 /* Initialize NS/BSSGP side */
2336 f_init_bssgp();
2337 /* Initialize GPRS MS side */
2338 f_init_gprs_ms();
2339 ms := g_ms[0]; /* We only use first MS in this test */
2340
2341 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002342 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002343
2344 /* Establish BSSGP connection to the PCU */
2345 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002346 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002347
2348 /* Establish an Uplink TBF */
2349 f_ms_establish_ul_tbf(ms);
2350
2351 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2352 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2353 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2354
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002355 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002356}
2357
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002358/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2359 * answered, so TBFs for uplink and later for downlink are created.
2360 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002361private 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 +02002362 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002363 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002364 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002365 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002366 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002367
2368 /* Initialize NS/BSSGP side */
2369 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002370 /* Initialize GPRS MS side */
2371 f_init_gprs_ms();
2372 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002373
2374 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002375 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002376
2377 /* Establish BSSGP connection to the PCU */
2378 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002379 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002380
2381 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002382 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002383
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002384 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002385 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002386 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 +02002387 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2388 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002389 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002390
2391 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002392 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002393
2394 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002395 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2396 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002397
2398 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2399 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002400 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002401
2402 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002403 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2404 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2405 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002406
2407 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002408}
2409
2410/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2411 * answered, so TBFs for uplink and later for downlink are created.
2412 */
2413testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002414 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002415 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002416}
2417
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002418/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2419 * answered, so TBFs for uplink and later for downlink are created.
2420 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002421private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2422 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002423 template (present) CodingScheme exp_ul_cs_mcs := ?,
2424 template (present) CodingScheme exp_dl_cs_mcs := ?)
2425runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002426 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002427 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002428 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002429 var uint32_t sched_fn;
2430 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002431 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002432 var GprsMS ms;
2433
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002434 /* Initialize NS/BSSGP side */
2435 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002436 /* Initialize GPRS MS side */
2437 f_init_gprs_ms();
2438 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002439
2440 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002441 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002442
2443 /* Establish BSSGP connection to the PCU */
2444 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002445 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002446
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002447 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2448 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 +02002449
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002450 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2451 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 +02002452 f_shutdown(__BFILE__, __LINE__);
2453 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002454
2455 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2456 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002457 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002458
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002459 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002460 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 +02002461
2462 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002463 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002464
2465 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002466 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002467 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2468 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002469 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002470 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002471 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002472
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002473 /* PCU acks the UL data after having received CV=0) */
2474 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2475
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002476 /* 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 +02002477 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 +02002478
2479 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002480 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2481 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 +02002482 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002483
2484 f_shutdown(__BFILE__, __LINE__, final := true);
2485}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002486
2487testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002488 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2489 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002490
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002491 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 +01002492
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002493 var StatsDExpects expect := {
2494 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2495 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2496 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2497 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2498 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2499 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2500 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2501 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2502 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2503 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2504 };
2505 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002506
2507 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002508}
2509
2510testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002511 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2512 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002513
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002514 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 +01002515
2516 var StatsDExpects expect := {
2517 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2518 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2519 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2520 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2521 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2522 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2523 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2524 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2525 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2526 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2527 };
2528 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002529
2530 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002531}
2532
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002533testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2534 /* Configure PCU to force two phase access */
2535 g_force_two_phase_access := true;
2536
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002537 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002538 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002539
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002540 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01002541
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002542 var StatsDExpects expect := {
2543 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2544 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2545 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2546 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2547 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2548 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2549 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2550 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2551 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2552 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2553 };
2554 f_statsd_expect(expect);
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02002555
2556 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002557}
2558
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002559/* Test scenario where SGSN wants to send some data against MS and it is
2560 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2561 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002562private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2563 template (present) CodingScheme exp_cs_mcs := ?)
2564runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002565 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002566 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002567 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002568 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002569 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002570
2571 /* Initialize NS/BSSGP side */
2572 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002573 /* Initialize GPRS MS side */
2574 f_init_gprs_ms();
2575 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002576
2577 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002578 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002579
2580 /* Establish BSSGP connection to the PCU */
2581 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002582 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002583
2584 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002585 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2586 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002587
2588 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2589 f_sleep(X2002);
Pau Espin Pedrol3f2b5e42022-11-29 14:54:34 +01002590 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2591 dl_fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
2592
2593 f_rlcmac_dl_block_exp_data(dl_block, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002594
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002595 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002596 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2597 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 +02002598 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002599
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002600 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002601 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002602
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002603 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002604 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002605 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002606 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2607 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002608 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002609
2610 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002611 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002612
2613 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002614}
2615
2616testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002617 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002618 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2619}
2620
2621/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2622/* information about the MS */
2623testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002624 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002625 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002626}
2627
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002628/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2629 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2630 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2631 * be transferred).
2632 */
2633testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002634 var RlcmacDlBlock dl_block;
2635 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002636 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002637 var octetstring total_payload;
2638 var octetstring payload;
2639 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002640 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002641 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002642 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002643
2644 /* Initialize NS/BSSGP side */
2645 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002646 /* Initialize GPRS MS side */
2647 f_init_gprs_ms();
2648 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002649
2650 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002651 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002652
2653 /* Establish BSSGP connection to the PCU */
2654 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002655 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002656
2657 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002658 f_ms_establish_ul_tbf(ms);
2659 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002660
2661 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002662 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002663 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 +02002664 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 +02002665
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002666 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2667 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002668 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002669 total_payload := payload;
2670
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002671 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2672
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002673 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002674 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002675 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002676 total_payload := total_payload & payload;
2677
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002678 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002679 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002680 total_payload := total_payload & payload;
2681
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002682 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002683 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 +02002684 total_payload := total_payload & lost_payload;
2685
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002686 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002687 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002688 total_payload := total_payload & payload;
2689
2690 /* 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 +02002691 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002692
2693 /* On CV=0, we'll receive a UL ACK asking about missing block */
2694 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2695 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002696 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2697 tfi := tfi,
2698 cv := 15,
2699 bsn := 3,
2700 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002701 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002702
2703 /* Now final ack is recieved */
2704 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2705 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002706 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002707
2708 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002709 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 +07002710
2711 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002712}
2713
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002714/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2715 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2716 * timeout occurs (specified by sent RRBP on DL block). */
2717testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002718 var RlcmacDlBlock dl_block;
2719 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002720 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002721 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002722
2723 /* Initialize NS/BSSGP side */
2724 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002725 /* Initialize GPRS MS side */
2726 f_init_gprs_ms();
2727 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002728
2729 /* Initialize the PCU interface abstraction */
2730 f_init_raw(testcasename());
2731
2732 /* Establish BSSGP connection to the PCU */
2733 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002734 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002735
2736 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002737 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2738 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002739
2740 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2741 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002742 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002743
2744 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2745 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2746 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002747 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002748
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002749 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2750 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002751 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002752
2753 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002754 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2755 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2756 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002757
2758 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002759}
2760
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002761/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2762testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2763 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2764 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002765 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002766 var RlcmacDlBlock dl_block;
2767 var uint32_t ack_fn;
2768 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002769 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002770 timer T := 5.0;
2771
2772 /* Initialize NS/BSSGP side */
2773 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002774 /* Initialize GPRS MS side */
2775 f_init_gprs_ms();
2776 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002777
2778 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002779 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002780
Daniel Willmann535aea62020-09-21 13:27:08 +02002781 f_statsd_reset();
2782
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002783 /* 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);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002786
2787 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002788 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2789 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002790
2791 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2792 f_sleep(X2002);
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002793 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2794 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002795
2796 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002797 f_rlcmac_dl_block_exp_data(dl_block, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002798 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002799
2800 /* TDMA frame number on which we are supposed to send the ACK */
2801 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2802
2803 /* SGSN sends more blocks during the indicated RRBP */
2804 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2805 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002806 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002807
2808 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2809
2810 /* Make sure this block has the same TFI as was assigned
2811 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002812 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002813 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2814 dl_block.data.mac_hdr.hdr_ext.tfi);
2815 f_shutdown(__BFILE__, __LINE__);
2816 }
2817
2818 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002819 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002820
2821 /* Break if this is the end of RRBP */
2822 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002823 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002824 break;
2825 }
2826 }
2827
2828 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002829 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 +07002830
2831 /* Make sure that the next block (after the Ack) is dummy */
2832 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2833
Daniel Willmann535aea62020-09-21 13:27:08 +02002834 var StatsDExpects expect := {
2835 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2836 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2837 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2838 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2839 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002840 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002841 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2842 };
2843 f_statsd_expect(expect);
2844
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002845 f_shutdown(__BFILE__, __LINE__, final := true);
2846}
2847
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002848/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2849 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2850 * Check "3GPP TS 44.060" Annex B. */
2851testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2852 var RlcmacDlBlock dl_block;
2853 var octetstring dataA := f_rnd_octstring(20);
2854 var octetstring dataB := f_rnd_octstring(13);
2855 var octetstring dataC := f_rnd_octstring(3);
2856 var octetstring dataD := f_rnd_octstring(12);
2857 var uint32_t sched_fn;
2858 var GprsMS ms;
2859 var template (value) RlcmacUlBlock ul_data;
2860
2861 /* Initialize NS/BSSGP side */
2862 f_init_bssgp();
2863 /* Initialize GPRS MS side */
2864 f_init_gprs_ms();
2865 ms := g_ms[0]; /* We only use first MS in this test */
2866
2867 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002868 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002869
2870 /* Establish BSSGP connection to the PCU */
2871 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002872 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002873
2874 /* Establish an Uplink TBF */
2875 f_ms_establish_ul_tbf(ms);
2876
2877 /* Summary of what's transmitted:
2878 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2879 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2880 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2881 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2882 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2883 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2884 */
2885
2886 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002887 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2888 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002889 cv := 3,
2890 bsn := ms.ul_tbf.bsn,
2891 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2892 tlli := ms.tlli);
2893 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2894 * RLCMAC block being sent. */
2895 ul_data.data.mac_hdr.e := true;
2896 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002897 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002898
2899 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002900 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2901 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002902 cv := 2,
2903 bsn := ms.ul_tbf.bsn,
2904 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2905 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2906 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2907 },
2908 tlli := ms.tlli);
2909 f_ultbf_inc_bsn(ms.ul_tbf);
2910 f_ms_tx_ul_block(ms, ul_data);
2911
2912 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002913 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 +02002914
2915 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002916 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2917 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002918 cv := 1,
2919 bsn := ms.ul_tbf.bsn,
2920 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2921 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2922 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2923 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2924 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2925 },
2926 tlli := ms.tlli);
2927 f_ultbf_inc_bsn(ms.ul_tbf);
2928 f_ms_tx_ul_block(ms, ul_data);
2929
2930 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002931 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2932 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 +02002933
2934 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002935 ul_data := t_RLCMAC_UL_DATA_TLLI(
2936 cs := CS_1,
2937 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002938 cv := 0,
2939 bsn := ms.ul_tbf.bsn,
2940 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2941 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2942 },
2943 tlli := ms.tlli);
2944 f_ultbf_inc_bsn(ms.ul_tbf);
2945 f_ms_tx_ul_block(ms, ul_data);
2946
2947 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002948 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 +02002949
2950 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2951 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2952 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2953
2954 f_shutdown(__BFILE__, __LINE__, final := true);
2955}
2956
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002957/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2958 * ACK/NACK is not answered */
2959testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2960 var RlcmacDlBlock dl_block;
2961 var octetstring data1 := f_rnd_octstring(200);
2962 var octetstring data2 := f_rnd_octstring(10);
2963 var uint32_t dl_fn;
2964 var GprsMS ms;
2965 var template (value) TsTrxBtsNum nr;
2966 var BTS_PDTCH_Block data_msg;
2967
2968 /* Initialize NS/BSSGP side */
2969 f_init_bssgp();
2970 /* Initialize GPRS MS side */
2971 f_init_gprs_ms();
2972 ms := g_ms[0]; /* We only use first MS in this test */
2973
2974 /* Initialize the PCU interface abstraction */
2975 f_init_raw(testcasename())
2976
2977 /* Establish BSSGP connection to the PCU */
2978 f_bssgp_establish();
2979 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2980
2981 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2982 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2983 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2984
2985 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2986 f_sleep(X2002);
2987
2988 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2989 while (true) {
2990 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2991
2992 /* Keep Ack/Nack description updated (except for last BSN) */
2993 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2994
2995 if (f_dl_block_rrbp_valid(dl_block)) {
2996 /* Don't transmit DL ACK here on purpose ignore it */
2997 break;
2998 }
2999 }
3000
3001 /* PCU starts whole process again */
3002 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3003
3004 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3005 f_sleep(X2002);
3006
3007 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
3008 /* DL data), after that we receive only DUMMY blocks so we are done */
3009 var boolean data_received := false;
3010 nr := ts_TsTrxBtsNum;
3011 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3012 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3013 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3014 block_nr := nr.blk_nr));
3015 alt {
3016 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3017 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003018 tr_RLCMAC_DL_DUMMY_CTRL)) { /* done */ }
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003019 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3020 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3021 tr_RLCMAC_DATA)) -> value data_msg {
3022 data_received := true;
3023 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3024 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3025 log("Received FINAL_ACK");
3026 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3027 }
3028 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3029 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3030 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3031 }
3032 nr := ts_TsTrxBtsNum;
3033 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3034 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3035 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3036 block_nr := nr.blk_nr));
3037 repeat;
3038 }
3039 [] BTS.receive {
3040 setverdict(fail, "Unexpected BTS message");
3041 f_shutdown(__BFILE__, __LINE__);
3042 }
3043 }
3044
3045 f_shutdown(__BFILE__, __LINE__, final := true);
3046}
3047
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003048/* OS#5508: Verify scheduling of LLC frames with SAPI=1 (GMM) takes precedence
3049 * over SAPI2/7/8 which in turn take prececende over others */
3050testcase TC_dl_llc_sapi_priority() runs on RAW_PCU_Test_CT {
3051 var octetstring data_sapi1 := f_pad_oct('01'O, 19, 'ff'O);
3052 var octetstring data_sapi2 := f_pad_oct('02'O, 19, 'ff'O);
3053 var octetstring data_sapi7 := f_pad_oct('07'O, 19, 'ff'O);
3054 var octetstring data_sapi8 := f_pad_oct('08'O, 19, 'ff'O);
3055 var octetstring data_sapi_other := f_pad_oct('03'O, 19, 'ff'O);
3056 var RlcmacDlBlock dl_block;
3057 var uint32_t dl_fn;
3058 var GprsMS ms;
3059 var integer state := 1;
3060
3061 /* Initialize NS/BSSGP side */
3062 f_init_bssgp();
3063 /* Initialize GPRS MS side */
3064 f_init_gprs_ms();
3065 ms := g_ms[0]; /* We only use first MS in this test */
3066
3067 /* Initialize the PCU interface abstraction */
3068 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3069
3070 /* Lock to CS1 to keep same DL RLCMAC data block size: */
3071 g_cs_initial_dl := 1;
3072 g_mcs_max_dl := 1;
3073 f_pcuvty_set_allowed_cs_mcs();
3074
3075 /* Establish BSSGP connection to the PCU */
3076 f_bssgp_establish();
3077 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3078
3079 /* SGSN sends some low prio DL data, PCU will page on CCCH (PCH) */
3080 for (var integer i := 0; i < 10; i := i + 1) {
3081 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi_other));
3082 }
3083 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi2));
3084 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi7));
3085 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi8));
3086 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi1));
3087 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3088
3089 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3090 f_sleep(X2002);
3091
3092 while (state != 0) {
3093 var OCT1 rx_sapi;
3094 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3095 rx_sapi := dl_block.data.blocks[0].payload[0];
3096
3097 select (state) {
3098 case(1) { /* We expect the first GMM LLC frame here (SAPI=1, highest prio) */
3099 if (rx_sapi != '01'O) {
3100 setverdict(fail, "Wrong prio: Expected LLC SAPI 1 (GMM) but got ", rx_sapi);
3101 f_shutdown(__BFILE__, __LINE__);
3102 }
3103 state := 2;
3104 }
3105 case(2) { /* We expect the second LLC frame here (SAPI=2, middle prio) */
3106 if (rx_sapi != '02'O) {
3107 setverdict(fail, "Wrong prio: Expected LLC SAPI 2 but got ", rx_sapi);
3108 f_shutdown(__BFILE__, __LINE__);
3109 }
3110 state := 7;
3111 }
3112 case(7) { /* We expect the third LLC frame here (SAPI=7, middle prio) */
3113 if (rx_sapi != '07'O) {
3114 setverdict(fail, "Wrong prio: Expected LLC SAPI 7 but got ", rx_sapi);
3115 f_shutdown(__BFILE__, __LINE__);
3116 }
3117 state := 8;
3118 }
3119 case(8) { /* We expect the fourth LLC frame here (SAPI=8, middle prio) */
3120 if (rx_sapi != '08'O) {
3121 setverdict(fail, "Wrong prio: Expected LLC SAPI 8 but got ", rx_sapi);
3122 f_shutdown(__BFILE__, __LINE__);
3123 }
3124 state := 3;
3125 }
3126 case(3) { /* We expect the other LLC frame here (SAPI=3, lower prio) */
3127 if (rx_sapi != '03'O) {
3128 setverdict(fail, "Wrong prio: Expected LLC SAPI 3 but got ", rx_sapi);
3129 f_shutdown(__BFILE__, __LINE__);
3130 }
3131 state := 0; /* Done, break */
3132 }
3133 }
3134 /* Keep Ack/Nack description updated (except for last BSN) */
3135 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3136
3137 if (f_dl_block_rrbp_valid(dl_block)) {
3138 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3139 f_dl_block_ack_fn(dl_block, dl_fn));
3140 }
3141 }
3142
3143 f_shutdown(__BFILE__, __LINE__, final := true);
3144}
3145
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003146/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3147testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003148 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003149 var octetstring data := f_rnd_octstring(10);
3150 var PacketDlAssign dl_tbf_ass;
3151 var RlcmacDlBlock dl_block;
3152 var uint32_t poll_fn;
3153 var uint32_t sched_fn;
3154 var GprsMS ms;
3155 timer T := 5.0;
3156
3157 /* Initialize NS/BSSGP side */
3158 f_init_bssgp();
3159 /* Initialize GPRS MS side */
3160 f_init_gprs_ms();
3161 ms := g_ms[0]; /* We only use first MS in this test */
3162
3163 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003164 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3165 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003166
3167 /* Initialize the PCU interface abstraction */
3168 f_init_raw(testcasename(), info_ind);
3169
3170 /* Establish BSSGP connection to the PCU */
3171 f_bssgp_establish();
3172 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3173
3174 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3175 through PDCH (no multiblock assignment possible through PCH) */
3176 f_ms_establish_ul_tbf(ms);
3177
3178 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003179 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003180 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
3181 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003182 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3183 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3184
3185 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3186 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3187 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3188 gprsextendeddynalloccap := '0'B
3189 };
3190 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3191 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3192 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3193 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3194 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3195 f_shutdown(__BFILE__, __LINE__);
3196 }
3197 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3198
3199 f_shutdown(__BFILE__, __LINE__, final := true);
3200}
3201
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003202testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003203 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003204 var RlcmacDlBlock dl_block;
3205 var octetstring data := f_rnd_octstring(10);
3206 var PollFnCtx pollctx;
3207 var uint32_t sched_fn;
3208 var GprsMS ms;
3209
3210 var MultislotCap_GPRS mscap_gprs := {
3211 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3212 gprsextendeddynalloccap := '0'B
3213 };
3214 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3215
3216
3217 /* Initialize NS/BSSGP side */
3218 f_init_bssgp();
3219 /* Initialize GPRS MS side */
3220 f_init_gprs_ms();
3221 ms := g_ms[0]; /* We only use first MS in this test */
3222
3223 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003224 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3225 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003226
3227 /* Initialize the PCU interface abstraction */
3228 f_init_raw(testcasename(), info_ind);
3229
3230 /* Establish BSSGP connection to the PCU */
3231 f_bssgp_establish();
3232 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3233
3234 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3235 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3236
3237 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3238 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3239
3240 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3241 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3242 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3243 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3244 f_shutdown(__BFILE__, __LINE__);
3245 }
3246 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3247
3248 f_shutdown(__BFILE__, __LINE__, final := true);
3249}
3250
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003251testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3252 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3253 var RlcmacDlBlock dl_block;
3254 var octetstring data := f_rnd_octstring(10);
3255 var PollFnCtx pollctx;
3256 var uint32_t sched_fn;
3257 var GprsMS ms;
3258
3259 var MultislotCap_GPRS mscap_gprs := {
3260 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3261 gprsextendeddynalloccap := '0'B
3262 };
3263 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3264
3265
3266 /* Initialize NS/BSSGP side */
3267 f_init_bssgp();
3268 /* Initialize GPRS MS side */
3269 f_init_gprs_ms();
3270 ms := g_ms[0]; /* We only use first MS in this test */
3271
3272 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003273 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3274 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003275
3276 /* Initialize the PCU interface abstraction */
3277 f_init_raw(testcasename(), info_ind);
3278
3279 /* Establish BSSGP connection to the PCU */
3280 f_bssgp_establish();
3281 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3282
3283 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3284 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3285
3286 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3287 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3288 f_shutdown(__BFILE__, __LINE__);
3289 }
3290
3291 f_shutdown(__BFILE__, __LINE__, final := true);
3292}
3293
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003294/* Test scenario where MS wants to request a new TBF once the current one is
3295 * ending, by means of sending a Packet Resource Request on ul slot provided by
3296 * last Pkt Ul ACK's RRBP.
3297 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3298testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003299 var RlcmacDlBlock dl_block;
3300 var octetstring data := f_rnd_octstring(10);
3301 var uint32_t sched_fn;
3302 var uint32_t dl_fn;
3303 var template RlcmacDlBlock acknack_tmpl;
3304 var GprsMS ms;
3305
3306 /* Initialize NS/BSSGP side */
3307 f_init_bssgp();
3308 /* Initialize GPRS MS side */
3309 f_init_gprs_ms();
3310 ms := g_ms[0]; /* We only use first MS in this test */
3311
3312 /* Initialize the PCU interface abstraction */
3313 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003314 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003315
3316 /* Establish BSSGP connection to the PCU */
3317 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003318 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003319
3320 /* Establish an Uplink TBF */
3321 f_ms_establish_ul_tbf(ms);
3322
3323 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003324 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003325 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 +02003326
3327 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003328 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003329
3330 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3331 tr_UlAckNackGprs(ms.tlli,
3332 tr_AckNackDescription(final_ack := '1'B),
3333 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3334 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3335
3336 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3337
3338 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003339 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 +07003340 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003341 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3342 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3343
3344 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3345 and make sure it is ACKED fine */
3346 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3347
3348 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003349 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003350
3351 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3352 /* ACK the ACK */
3353 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3354
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003355 var StatsDExpects expect := {
3356 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3357 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3358 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3359 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3360 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3361 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3362 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3363 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3364 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3365 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3366 };
3367 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003368
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003369 f_shutdown(__BFILE__, __LINE__, final := true);
3370}
3371
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003372/* Test scenario where MS wants to request a new TBF once the current one is
3373 * ending, by means of sending a Packet Resource Request on ul slot provided by
3374 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3375 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3376testcase TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() runs on RAW_PCU_Test_CT {
3377 var PCUIF_info_ind info_ind;
3378 var RlcmacDlBlock dl_block;
3379 var octetstring data := f_rnd_octstring(10);
3380 var uint32_t sched_fn;
3381 var uint32_t dl_fn;
3382 var template (value) TsTrxBtsNum nr;
3383 var BTS_PDTCH_Block data_msg;
3384 var template RlcmacDlBlock acknack_tmpl;
3385 var GprsMS ms;
3386 const integer N3105_MAX := 2;
3387 var integer N3105 := 0;
3388 timer T_3195 := 1.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
3389
3390 /* Initialize NS/BSSGP side */
3391 f_init_bssgp();
3392 /* Initialize GPRS MS side */
3393 f_init_gprs_ms();
3394 ms := g_ms[0]; /* We only use first MS in this test */
3395
3396 /* Initialize the PCU interface abstraction */
3397 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3398 /* Speedup test: */
3399 info_ind.n3105 := N3105_MAX;
3400 info_ind.t3195 := 1;
3401 f_init_raw(testcasename(), info_ind);
3402
3403 /* Establish BSSGP connection to the PCU */
3404 f_bssgp_establish();
3405 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3406
3407 /* Establish an Uplink TBF */
3408 f_ms_establish_ul_tbf(ms);
3409
3410 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003411 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003412 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3413
3414 /* UL block should be received in SGSN */
3415 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3416
3417 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3418 tr_UlAckNackGprs(ms.tlli,
3419 tr_AckNackDescription(final_ack := '1'B),
3420 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3421 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3422
3423 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3424
3425 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
3426 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3427
3428 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3429 /* Now we go on receiving DL data and not answering RRBP: */
3430 nr := ts_TsTrxBtsNum;
3431 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3432 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3433 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3434 block_nr := nr.blk_nr));
3435 alt {
3436 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3437 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3438 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
3439 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3440 log("Ignoring RRBP N3105 ", N3105);
3441 N3105 := N3105 + 1;
3442 }
3443 nr := ts_TsTrxBtsNum;
3444 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3445 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3446 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3447 block_nr := nr.blk_nr));
3448 repeat;
3449 }
3450 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
3451 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
3452 */
3453 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3454 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003455 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003456 if (not T_3195.running) {
3457 T_3195.start;
3458 }
3459 nr := ts_TsTrxBtsNum;
3460 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3461 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3462 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3463 block_nr := nr.blk_nr));
3464 repeat;
3465 }
3466 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3467 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3468 omit)) -> value data_msg {
3469 /* We may already receive idle blocks before our own TTCN3 timer
3470 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
3471 nr := ts_TsTrxBtsNum;
3472 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3473 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3474 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3475 block_nr := nr.blk_nr));
3476 repeat;
3477 }
3478 /* We receive Dummy blocks in between Pkt Ul Ass while PCU waits for us to ack it */
3479 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3480 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003481 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003482 log("Ignoring Dummy block FN ", data_msg.raw.fn);
3483 nr := ts_TsTrxBtsNum;
3484 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3485 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3486 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3487 block_nr := nr.blk_nr));
3488 repeat;
3489 }
3490 [T_3195.running] T_3195.timeout {
3491 log("T_3195 timeout");
3492 /* Done in alt, wait for pending RTS initiated previously in
3493 * above case before continuing (expect nothing to be sent since there's no active TBF): */
3494 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3495 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3496 omit));
3497 }
3498 [] BTS.receive {
3499 setverdict(fail, "Unexpected BTS message");
3500 f_shutdown(__BFILE__, __LINE__);
3501 }
3502 }
3503
3504 f_shutdown(__BFILE__, __LINE__, final := true);
3505}
3506
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003507/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3508 * transmitted on ul slot provided by its DL TBF.
3509 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3510function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3511 var GprsMS ms;
3512 var octetstring data := f_rnd_octstring(10);
3513 var RlcmacDlBlock dl_block;
3514 var template RlcmacDlBlock rej_tmpl;
3515 var uint32_t dl_fn;
3516 var uint32_t sched_fn;
3517 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3518
3519 if (use_egprs == true) {
3520 racap_tmpl := bssgp_ms_racap_egprs_def;
3521 } else {
3522 racap_tmpl := bssgp_ms_racap_gprs_def;
3523 }
3524
3525 /* Initialize NS/BSSGP side */
3526 f_init_bssgp();
3527 /* Initialize GPRS MS side */
3528 f_init_gprs_ms();
3529 ms := g_ms[0]; /* We only use first MS in this test */
3530 /* Initialize the PCU interface abstraction */
3531 f_init_raw(testcasename());
3532
3533 /* Establish BSSGP connection to the PCU */
3534 f_bssgp_establish();
3535 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3536
3537 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3538 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3539 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3540
3541 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3542 f_sleep(X2002);
3543 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3544
3545 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3546 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3547 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3548 f_dl_block_ack_fn(dl_block, dl_fn));
3549
3550 /* We should receive a Pkt Ul ASS */
3551 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3552 f_shutdown(__BFILE__, __LINE__, final := true);
3553}
3554testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3555 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3556}
3557testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3558 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3559}
3560
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003561/* Test CS paging over the BTS<->PCU socket.
3562 * 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.
3563 * Paging should be send on the PACCH.
3564 *
3565 * 1. Send a Paging Request over PCU socket.
3566 * 2. Send a Ready-To-Send message over PCU socket
3567 * 3. Expect a Paging Frame
3568 */
3569testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003570 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003571 var MobileIdentityLV mi;
3572 var octetstring mi_enc_lv;
3573 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003574 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003575
3576 /* Initialize NS/BSSGP side */
3577 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003578 /* Initialize GPRS MS side */
3579 f_init_gprs_ms();
3580 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003581
3582 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003583 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003584
3585 /* Establish BSSGP connection to the PCU */
3586 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003587 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003588
3589 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003590 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003591
3592 /* build mobile Identity */
3593 mi := valueof(ts_MI_IMSI_LV(imsi));
3594 mi_enc_lv := enc_MobileIdentityLV(mi);
3595 /* Send paging request */
3596 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3597 sapi :=PCU_IF_SAPI_PDTCH));
3598
3599 /* Receive it on BTS side towards MS */
3600 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3601
3602 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003603 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3604 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3605 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3606 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003607
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003608 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003609}
3610
3611/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3612 */
3613private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3614runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003615 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003616 var hexstring imsi := f_gen_imsi(42);
3617 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003618 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003619
3620 /* Initialize NS/BSSGP side */
3621 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003622 /* Initialize GPRS MS side */
3623 f_init_gprs_ms();
3624 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003625
3626 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003627 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003628
3629 /* Establish BSSGP connection to the PCU */
3630 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003631 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003632
3633 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003634 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003635
3636 /* Send paging request with or without TMSI */
3637 if (use_ptmsi) {
3638 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3639 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3640 } else {
3641 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3642 }
3643
Pau Espin Pedrol00fec582022-11-29 16:03:13 +01003644 /* Now receive it on BTS side towards MS.
3645 * Skip any dummy blocks in case the PCUIF req arrives before the BSSP CS_PAGING:
3646 */
3647 f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
3648
3649 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
3650 setverdict(fail, "Failed to match Packet Paging Request: ",
3651 dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
3652 f_shutdown(__BFILE__, __LINE__);
3653 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003654
3655 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003656 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003657 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003658 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3659 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3660 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003661 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003662 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3663 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3664 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003665 }
3666
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003667 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003668}
3669
3670testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3671 f_tc_paging_cs_from_sgsn(0, true);
3672}
3673
3674testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3675 f_tc_paging_cs_from_sgsn(0);
3676}
3677
3678testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003679 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003680}
3681
3682/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3683 */
3684private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3685runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003686 var integer imsi_suff_tx := 423;
3687 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003688 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003689
3690 /* Initialize NS/BSSGP side */
3691 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003692 /* Initialize GPRS MS side */
3693 f_init_gprs_ms();
3694 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003695
Oliver Smith61b4e732021-07-22 08:14:29 +02003696 f_statsd_reset();
3697
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003698 /* Establish BSSGP connection to the PCU */
3699 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003700 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003701
3702 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3703 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3704 if (use_ptmsi) {
3705 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3706 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3707 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3708 } else {
3709 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3710 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3711 }
3712
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003713 var StatsDExpects expect := {
3714 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3715 /* After the PCU receives the paging request from SGSN,
3716 * and it doesn't have any errors, PCU sends it to the
3717 * BTS to do paging over PCH. */
3718 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3719 };
3720 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003721}
3722
3723testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3724 /* Initialize the PCU interface abstraction */
3725 f_init_raw(testcasename());
3726
3727 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003728
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003729 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003730}
3731
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003732testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003733 /* Initialize the PCU interface abstraction */
3734 f_init_raw(testcasename());
3735
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003736 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003737
3738 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003739}
3740
3741testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003742 /* Initialize the PCU interface abstraction */
3743 f_init_raw(testcasename());
3744
Harald Welte5339b2e2020-10-04 22:52:56 +02003745 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003746
3747 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003748}
3749
Oliver Smithe1a77c42021-07-28 13:36:09 +02003750testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3751 /* Initialize the PCU interface abstraction */
3752 f_init_raw(testcasename());
3753
3754 /* Set T3113 to 1s to shorten the test duration */
3755 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3756
3757 /* Reset stats and send paging PS request */
3758 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3759
3760 /* Verify that counter increases when T3113 times out (MS did not start
3761 * TBF to respond to paging). */
3762 f_sleep(1.2);
3763 var StatsDExpects expect := {
3764 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3765 };
3766 f_statsd_expect(expect);
3767
3768 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3769 f_shutdown(__BFILE__, __LINE__, final := true);
3770}
3771
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003772/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3773testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3774 var RlcmacDlBlock dl_block;
3775 var octetstring data := f_rnd_octstring(10);
3776 var uint32_t sched_fn;
3777 var uint32_t dl_fn;
3778 var GprsMS ms;
3779
3780 /* Initialize NS/BSSGP side */
3781 f_init_bssgp();
3782 /* Initialize GPRS MS side */
3783 f_init_gprs_ms();
3784 ms := g_ms[0]; /* We only use first MS in this test */
3785
3786 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003787 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003788
Daniel Willmann535aea62020-09-21 13:27:08 +02003789 f_statsd_reset();
3790
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003791 /* Establish BSSGP connection to the PCU */
3792 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003793 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003794
3795 /* Establish an Uplink TBF */
3796 f_ms_establish_ul_tbf(ms);
3797
3798 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003799 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 +02003800 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3801 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3802 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3803
3804 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003805 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003806
3807 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3808 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3809 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3810
3811 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3812 f_sleep(X2002);
3813 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3814
3815 /* ACK the DL block */
3816 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3817 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3818 f_dl_block_ack_fn(dl_block, dl_fn));
3819
Daniel Willmann535aea62020-09-21 13:27:08 +02003820 var StatsDExpects expect := {
3821 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3822 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3823 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3824 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003825 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003826 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003827 };
3828 f_statsd_expect(expect);
3829
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003830 f_shutdown(__BFILE__, __LINE__, final := true);
3831}
3832
3833/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3834testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3835 var RlcmacDlBlock dl_block;
3836 var octetstring data := f_rnd_octstring(10);
3837 var uint32_t sched_fn;
3838 var uint32_t dl_fn;
3839 var GprsMS ms;
3840
3841 /* Initialize NS/BSSGP side */
3842 f_init_bssgp();
3843 /* Initialize GPRS MS side */
3844 f_init_gprs_ms();
3845 ms := g_ms[0]; /* We only use first MS in this test */
3846
3847 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003848 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003849
3850 /* Establish BSSGP connection to the PCU */
3851 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003852 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003853
3854 /* Establish an Uplink TBF */
3855 f_ms_establish_ul_tbf(ms);
3856
3857 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003858 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 +02003859 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3860 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3861 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3862
3863 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003864 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003865
3866 /* Now SGSN sends some DL data with an invalid IMSI */
3867 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3868
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003869 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003870
3871 /* TODO: make sure no data is sent over PCU -> MS */
3872
3873 f_shutdown(__BFILE__, __LINE__, final := true);
3874}
3875
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003876private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3877 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3878 var octetstring data := f_rnd_octstring(6);
3879 var RlcmacDlBlock dl_block;
3880 var GprsMS ms;
3881 var uint32_t fn;
3882
3883 /* Initialize NS/BSSGP side */
3884 f_init_bssgp();
3885 /* Initialize GPRS MS side */
3886 f_init_gprs_ms();
3887 ms := g_ms[0]; /* We only use first MS in this test */
3888
3889 /* Initialize the PCU interface abstraction */
3890 f_init_raw(testcasename());
3891
3892 /* Establish BSSGP connection to the PCU */
3893 f_bssgp_establish();
3894 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3895
3896 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3897 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3898 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3899
3900 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3901 f_sleep(X2002);
3902
3903 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3904 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3905
3906 if (ischosen(dl_block.data_egprs)) {
3907 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3908 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3909 f_shutdown(__BFILE__, __LINE__);
3910 }
3911 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3912 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3913 f_shutdown(__BFILE__, __LINE__);
3914 }
3915 if (not match(dl_block.data_egprs.blocks[1].payload,
3916 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3917 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3918 f_shutdown(__BFILE__, __LINE__);
3919 }
3920 } else if (lengthof(dl_block.data.blocks) > 1) {
3921 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3922 f_shutdown(__BFILE__, __LINE__);
3923 }
3924
3925 f_shutdown(__BFILE__, __LINE__, final := true);
3926}
3927
3928/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3929 * containing llc data. See OS#4849 */
3930testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3931 f_tc_dl_data_no_llc_ui_dummy(omit);
3932}
3933
3934/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3935 * containing llc data. See OS#4849 */
3936testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003937 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003938}
3939
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02003940/* Scenario: MS creates one phase access, does contention resolution CV>0 and
3941 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
3942 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
3943 * has to assign a DL TBF (through PCH because of FINISHED state, TS 44.060 9.3.3.3.2).
3944 * Make sure the assignment is not done until we receive the PKT CTRL ACK from the MS
3945 * (at that time we know the MS is listening on PCH again). OS#5700.
3946 */
3947testcase TC_ul_tbf_finished_pkt_dl_ass_pch() runs on RAW_PCU_Test_CT {
3948 var RlcmacDlBlock dl_block;
3949 var octetstring data := f_rnd_octstring(10);
3950 var uint32_t sched_fn;
3951 var uint32_t dl_fn;
3952 var GprsMS ms;
3953 timer T;
3954 var octetstring payload;
3955
3956 /* Initialize NS/BSSGP side */
3957 f_init_bssgp();
3958 /* Initialize GPRS MS side */
3959 f_init_gprs_ms();
3960 ms := g_ms[0]; /* We only use first MS in this test */
3961
3962 /* Initialize the PCU interface abstraction */
3963 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3964
3965 /* Establish BSSGP connection to the PCU */
3966 f_bssgp_establish();
3967 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3968
3969 /* Establish an Uplink TBF */
3970 f_ms_establish_ul_tbf(ms);
3971
3972 /* Send one UL block (with TLLI since we are in One-Phase Access
3973 contention resolution) and make sure it is ACKED fine. */
3974 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
3975 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
3976 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
3977
3978 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3979 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
3980 f_ms_tx_ul_data_block(ms, payload, cv := 0);
3981 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3982
3983 /* 1 UL block should be received in SGSN */
3984 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3985 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3986 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3987
3988 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3989 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3990 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3991 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3992 f_sleep(X2002);
3993 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3994
3995 f_shutdown(__BFILE__, __LINE__, final := true);
3996}
3997
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02003998/* Scenario: MS creates a UL TBF and
3999 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
4000 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
4001 * has to assign a DL TBF on PCH. While the network is waiting for the MS to
4002 * move to PDCH before transmitting DL data (timer X2002), the MS finds out it
4003 * needs to send new UL data and hence sends a RACH request to create a new UL
4004 * TBF.
4005 * Make sure the the MS is assigned a DL TBF through PACCH in that case even if
4006 * no new DL data is received from the SGSN. OS#5700.
4007 * This test validates the specific case where the 2nd UL TBF is done through
4008 * 1phase-access.
4009 */
4010testcase TC_ul_tbf_1phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4011 var RlcmacDlBlock dl_block;
4012 var octetstring data := f_rnd_octstring(10);
4013 var uint32_t sched_fn;
4014 var uint32_t poll_fn;
4015 var uint32_t dl_fn;
4016 var GprsMS ms;
4017 timer T;
4018 var octetstring payload;
4019
4020 /* Initialize NS/BSSGP side */
4021 f_init_bssgp();
4022 /* Initialize GPRS MS side */
4023 f_init_gprs_ms();
4024 ms := g_ms[0]; /* We only use first MS in this test */
4025
4026 /* Initialize the PCU interface abstraction */
4027 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4028
4029 /* Establish BSSGP connection to the PCU */
4030 f_bssgp_establish();
4031 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4032
4033 /* Establish an Uplink TBF */
4034 f_ms_establish_ul_tbf(ms);
4035
4036 /* Send one UL block (with TLLI since we are in One-Phase Access
4037 contention resolution) and make sure it is ACKED fine. */
4038 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4039 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4040 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4041
4042 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4043 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4044 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4045 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4046
4047 /* 1 UL block should be received in SGSN */
4048 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4049 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4050 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4051
4052 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4053 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4054 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4055
4056 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4057 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4058 f_ms_establish_ul_tbf(ms);
4059
4060 /* Send one UL block (with TLLI since we are in One-Phase Access
4061 * contention resolution) and make sure it is ACKED fine. */
4062 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4063 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4064 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4065
4066 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4067 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4068
4069 /* The PCU considers the MS to have gone over Contention Resolution
4070 * after having sent the first UL ACK/NACK to it, hence next it will try to
4071 * assign the DL-TBF to send the data it received from the SGSN previously: */
4072 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4073 /* the MS ACKs the PKT_DL_ASS: */
4074 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4075
4076 /* We should finally receive the DL-data that was received previously from the SGSN: */
4077 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4078
4079 f_shutdown(__BFILE__, __LINE__, final := true);
4080}
4081
4082/* Same as TC_ul_tbf_2phase_while_dl_ass_pch, but this test validates the
4083 * specific case where the 2nd UL TBF is done through 2phase-access. */
4084testcase TC_ul_tbf_2phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4085 var RlcmacDlBlock dl_block;
4086 var octetstring data := f_rnd_octstring(10);
4087 var uint32_t sched_fn;
4088 var uint32_t poll_fn;
4089 var uint32_t dl_fn;
4090 var GprsMS ms;
4091 timer T;
4092 var octetstring payload;
4093 var PollFnCtx pollctx;
4094
4095 /* Initialize NS/BSSGP side */
4096 f_init_bssgp();
4097 /* Initialize GPRS MS side */
4098 f_init_gprs_ms();
4099 ms := g_ms[0]; /* We only use first MS in this test */
4100
4101 /* Initialize the PCU interface abstraction */
4102 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4103
4104 /* Establish BSSGP connection to the PCU */
4105 f_bssgp_establish();
4106 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4107
4108 /* Establish an Uplink TBF */
4109 f_ms_establish_ul_tbf(ms);
4110
4111 /* Send one UL block (with TLLI since we are in One-Phase Access
4112 contention resolution) and make sure it is ACKED fine. */
4113 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4114 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4115 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4116
4117 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4118 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4119 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4120 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4121
4122 /* 1 UL block should be received in SGSN */
4123 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4124 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4125 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4126
4127 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4128 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4129 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4130
4131 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4132 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4133 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4134
4135 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4136 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4137
4138 /* Now that MS seized the UL-TBF, PCU sends DL-TBF Assignment on PACCH */
4139 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4140 /* the MS ACKs the PKT_DL_ASS: */
4141 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4142
4143 /* We should finally receive the DL-data that was received previously from the SGSN: */
4144 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4145
4146 f_shutdown(__BFILE__, __LINE__, final := true);
4147}
4148
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004149private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004150 template GsmRrMessage t_imm_ass := ?,
4151 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004152runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004153 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004154 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004155
4156 ra11 := enc_EGPRSPktChRequest2uint(req);
4157 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
4158
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07004159 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004160 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004161 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004162 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004163 }
4164
4165 setverdict(pass);
4166}
4167
4168testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
4169 var template GsmRrMessage imm_ass;
4170 var template IaRestOctets rest;
4171 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004172 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004173
4174 /* Initialize the PCU interface abstraction */
4175 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004176 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004177
4178 var EGPRSPktChRequest req := {
4179 /* NOTE: other fields are set in the loop */
4180 signalling := { tag := '110011'B }
4181 };
4182
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004183 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004184 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4185 req.signalling.random_bits := ext_ra;
4186
4187 /* For signalling, do we expect Multiblock UL TBF Assignment? */
4188 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4189 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4190 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4191
4192 f_TC_egprs_pkt_chan_req(req, imm_ass);
4193 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004194
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004195 var StatsDExpects expect := {
4196 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4197 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4198 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4199 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4200 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4201 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4202 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4203 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4204 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4205 };
4206 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004207
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004208 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004209}
4210
4211testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
4212 var template GsmRrMessage imm_ass;
4213 var template IaRestOctets rest;
4214 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004215 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004216
4217 /* Initialize the PCU interface abstraction */
4218 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004219 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004220
4221 var EGPRSPktChRequest req := {
4222 /* NOTE: other fields are set in the loop */
4223 one_phase := { tag := '0'B }
4224 };
4225
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004226 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004227 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4228 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
4229 var BIT2 priority := substr(ext_ra, 0, 2);
4230 var BIT3 rand := substr(ext_ra, 2, 3);
4231
4232 req.one_phase.multislot_class := mslot_class;
4233 req.one_phase.priority := priority;
4234 req.one_phase.random_bits := rand;
4235
4236 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
4237 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
4238 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4239 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4240
4241 f_TC_egprs_pkt_chan_req(req, imm_ass);
4242 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004243
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004244 var StatsDExpects expect := {
4245 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4246 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4247 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4248 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4249 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4250 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4251 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4252 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4253 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4254 };
4255 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004256
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004257 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004258}
4259
4260testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4261 var template GsmRrMessage imm_ass;
4262 var template IaRestOctets rest;
4263 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004264 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004265
4266 /* Initialize the PCU interface abstraction */
4267 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004268 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004269
4270 var EGPRSPktChRequest req := {
4271 /* NOTE: other fields are set in the loop */
4272 two_phase := { tag := '110000'B }
4273 };
4274
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004275 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004276 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4277 var BIT2 priority := substr(ext_ra, 0, 2);
4278 var BIT3 rand := substr(ext_ra, 2, 3);
4279
4280 req.two_phase.priority := priority;
4281 req.two_phase.random_bits := rand;
4282
4283 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4284 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4285 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4286 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4287
4288 f_TC_egprs_pkt_chan_req(req, imm_ass);
4289 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004290
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004291 var StatsDExpects expect := {
4292 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4293 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4294 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4295 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4296 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4297 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4298 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4299 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4300 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4301 };
4302 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004303
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004304 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004305}
4306
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004307private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4308 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004309 PCUIF_BurstType bt := BURST_TYPE_1,
4310 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004311runs on RAW_PCU_Test_CT {
4312 var template ReqRefWaitInd tr_ref;
4313 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004314
4315 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4316 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4317 ra := bit2int(ra11), is_11bit := 1,
4318 burst_type := bt, fn := fn,
4319 arfcn := 871));
4320
4321 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004322 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004323
4324 /* Just to have a short-name reference to the actual message */
4325 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4326
4327 /* Make sure that Request Reference list contains at least one entry
4328 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004329 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004330 if (not match(iar.payload, { *, tr_ref, * })) {
4331 setverdict(fail, "Request Reference list does not match");
4332 f_shutdown(__BFILE__, __LINE__);
4333 }
4334
4335 /* Match Feature Indicator (must indicate PS domain) */
4336 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4337 setverdict(fail, "Feature Indicator does not match");
4338 f_shutdown(__BFILE__, __LINE__);
4339 }
4340
4341 /* Match IAR Rest Octets */
4342 if (not match(iar.rest_octets, rest)) {
4343 setverdict(fail, "IAR Rest Octets does not match: ",
4344 iar.rest_octets, " vs expected ", rest);
4345 f_shutdown(__BFILE__, __LINE__);
4346 }
4347
4348 setverdict(pass);
4349}
4350
4351/* Verify the contents of RR Immediate Assignment Reject message and its
4352 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4353testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4354 var template IARRestOctets rest;
4355 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004356 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004357
4358 /* Initialize the PCU interface abstraction */
4359 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004360 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004361
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004362 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004363 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4364 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4365
4366 /* Intentionally incorrect message (see table 11.2.5a.2) */
4367 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4368 }
4369
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004370 var StatsDExpects expect := {
4371 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4372 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4373 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4374 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4375 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4376 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4377 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4378 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4379 };
4380 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004381
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004382 f_shutdown(__BFILE__, __LINE__, final := true);
4383}
4384
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004385/* At the moment, the IUT does not support any emergency services. Make sure
4386 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4387testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4388 var template IARRestOctets rest;
4389 var BIT5 ext_ra;
4390 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004391 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004392
4393 /* Initialize the PCU interface abstraction */
4394 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004395 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004396
4397 var EGPRSPktChRequest req := {
4398 /* NOTE: other fields are set in the loop */
4399 emergency := { tag := '110111'B }
4400 };
4401
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004402 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004403 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4404 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4405
4406 req.emergency.random_bits := ext_ra;
4407 ra11 := enc_EGPRSPktChRequest2bits(req);
4408
4409 /* Intentionally incorrect message (see table 11.2.5a.2) */
4410 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4411 }
4412
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004413 var StatsDExpects expect := {
4414 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4415 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4416 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4417 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4418 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4419 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4420 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4421 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4422 };
4423 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004424
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004425 f_shutdown(__BFILE__, __LINE__, final := true);
4426}
4427
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004428/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4429testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004430 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004431 var template IARRestOctets rest;
4432 var BIT11 ra11;
4433
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004434 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004435 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004436
4437 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004438 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4439 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004440
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004441 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004442 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004443 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004444
4445 var EGPRSPktChRequest req := {
4446 one_phase := {
4447 tag := '0'B,
4448 multislot_class := '10101'B,
4449 priority := '01'B,
4450 random_bits := '101'B
4451 }
4452 };
4453
4454 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4455 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4456 for (var integer i := 0; i < 7; i := i + 1) {
4457 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4458 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4459 }
4460
4461 ra11 := enc_EGPRSPktChRequest2bits(req);
4462 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4463
4464 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004465 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004466
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004467 var StatsDExpects expect := {
4468 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4469 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4470 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4471 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4472 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4473 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4474 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4475 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4476 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4477 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4478 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4479 };
4480 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004481
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004482 f_shutdown(__BFILE__, __LINE__, final := true);
4483}
4484
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004485/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004486private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004487return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004488 /* Pick a random MA length in range 2 .. max_ma_len */
4489 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4490
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004491 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4492 hsn := f_rnd_int(63),
4493 maio := f_rnd_int(63),
4494 ma := f_rnd_bitstring(ma_len));
4495}
4496
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004497private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4498 in GsmRrMessage rr_msg)
4499{
4500 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004501 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004502
4503 var template PacketChannelDescription tr_pkt_chan_desc := {
4504 channel_Type_spare := ?,
4505 tn := ?,
4506 tsc := ts.tsc,
4507 presence := '1'B,
4508 zero := omit,
4509 one := {
4510 maio := ts.maio,
4511 hsn := ts.hsn
4512 }
4513 };
4514
4515 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4516 setverdict(fail, "Packet Channel Description does not match: ",
4517 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4518 }
4519
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004520 /* Mobile Allocation is expected to be octet-aligned */
4521 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4522 var template MobileAllocationLV tr_ma := {
4523 len := ma_oct_len, /* in bytes */
4524 ma := substr(ts.ma, 0, ma_oct_len * 8)
4525 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004526
4527 if (not match(ia.mobile_allocation, tr_ma)) {
4528 setverdict(fail, "Mobile Allocation does not match: ",
4529 ia.mobile_allocation, " vs ", tr_ma);
4530 }
4531
4532 setverdict(pass);
4533}
4534
4535/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4536testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004537 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004538 var GprsMS ms := valueof(t_GprsMS_def);
4539
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004540 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004541 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004542
4543 /* Initialize the PCU interface abstraction */
4544 f_init_raw(testcasename(), info_ind);
4545
4546 /* EGPRS Packet Channel Request (cause=Signalling) */
4547 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4548
4549 /* Establish an Uplink EGPRS TBF */
4550 f_ms_establish_ul_tbf(ms);
4551
4552 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4553 f_shutdown(__BFILE__, __LINE__, final := true);
4554}
4555
4556/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4557testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004558 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004559 var GprsMS ms := valueof(t_GprsMS_def);
4560
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004561 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004562 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004563
4564 /* Initialize the PCU interface abstraction */
4565 f_init_raw(testcasename(), info_ind);
4566
4567 /* Establish an Uplink TBF */
4568 f_ms_establish_ul_tbf(ms);
4569
4570 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4571 f_shutdown(__BFILE__, __LINE__, final := true);
4572}
4573
4574/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4575testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004576 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004577 var GprsMS ms := valueof(t_GprsMS_def);
4578
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004579 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004580 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004581
4582 /* Initialize NS/BSSGP side */
4583 f_init_bssgp();
4584
4585 /* Initialize the PCU interface abstraction */
4586 f_init_raw(testcasename(), info_ind);
4587
4588 /* Establish BSSGP connection to the PCU */
4589 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004590 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004591
4592 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4593 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4594 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4595
4596 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4597 f_shutdown(__BFILE__, __LINE__, final := true);
4598}
4599
4600private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4601 in FrequencyParameters fp)
4602{
4603 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004604 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004605
4606 /* Table 12.8.1: Frequency Parameters information elements */
4607 var template FrequencyParameters tr_fp := {
4608 tsc := ts.tsc,
4609 presence := '10'B, /* Direct encoding 1 */
4610 arfcn := omit,
4611 indirect := omit,
4612 direct1 := {
4613 maio := ts.maio,
4614 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4615 mobile_allocation := {
4616 hsn := ts.hsn,
4617 rfl_number_list_present := '0'B,
4618 rfl_number_list := omit,
4619 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004620 ma_length := ts.ma_bit_len,
4621 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004622 }
4623 },
4624 direct2 := omit
4625 };
4626
4627 if (not match(fp, tr_fp)) {
4628 setverdict(fail, "Frequency Parameters IE does not match: ",
4629 fp, " vs ", tr_fp);
4630 }
4631
4632 setverdict(pass);
4633}
4634
4635/* Make sure that Packet Uplink Assignment contains hopping parameters */
4636testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004637 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004638 var GprsMS ms := valueof(t_GprsMS_def);
4639 var uint32_t poll_fn;
4640
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004641 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004642 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004643
4644 /* Initialize the PCU interface abstraction */
4645 f_init_raw(testcasename(), info_ind);
4646
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004647 /* Single block (two phase) packet access */
4648 var uint16_t ra := bit2int(chan_req_sb);
4649 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4650
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004651 /* Establish an Uplink TBF */
4652 f_ms_establish_ul_tbf(ms);
4653
4654 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004655 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4656 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004657
4658 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004659 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4660 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004661
4662 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4663 var template (omit) FrequencyParameters fp;
4664 if (ua.is_egprs == '1'B) {
4665 fp := ua.egprs.freq_par;
4666 } else {
4667 fp := ua.gprs.freq_par;
4668 }
4669
4670 /* This is an optional IE, so it's worth to check its presence */
4671 if (istemplatekind(fp, "omit")) {
4672 setverdict(fail, "Frequency Parameters IE is not present");
4673 f_shutdown(__BFILE__, __LINE__);
4674 }
4675
4676 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4677 f_shutdown(__BFILE__, __LINE__, final := true);
4678}
4679
4680/* Make sure that Packet Downlink Assignment contains hopping parameters */
4681testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004682 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004683 var octetstring data := f_rnd_octstring(10);
4684 var GprsMS ms := valueof(t_GprsMS_def);
4685 var RlcmacDlBlock dl_block;
4686 var uint32_t poll_fn;
4687
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004688 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004689 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004690
4691 /* Initialize NS/BSSGP side */
4692 f_init_bssgp();
4693
4694 /* Initialize the PCU interface abstraction */
4695 f_init_raw(testcasename(), info_ind);
4696
4697 /* Establish BSSGP connection to the PCU */
4698 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004699 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004700
4701 /* Establish an Uplink TBF */
4702 f_ms_establish_ul_tbf(ms);
4703
4704 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004705 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 +07004706
4707 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4708 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4709 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4710
4711 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4712 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4713
4714 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004715 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4716 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004717
4718 /* This is an optional IE, so it's worth to check its presence */
4719 if (not ispresent(da.freq_par)) {
4720 setverdict(fail, "Frequency Parameters IE is not present");
4721 f_shutdown(__BFILE__, __LINE__);
4722 }
4723
4724 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4725 f_shutdown(__BFILE__, __LINE__, final := true);
4726}
4727
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004728/* Check if the IUT handles subsequent INFO.ind messages */
4729testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004730 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004731 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004732
4733 /* Initialize the PCU interface abstraction */
4734 f_init_raw(testcasename(), info_ind);
4735
4736 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4737 for (var integer i := 0; i < 16; i := i + 1) {
4738 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004739 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004740 }
4741
4742 f_shutdown(__BFILE__, __LINE__, final := true);
4743}
4744
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004745/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4746testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4747 var PCUIF_info_ind info_ind;
4748 var integer i;
4749 const integer num_ms := 8;
4750
4751 /* Initialize NS/BSSGP side */
4752 f_init_bssgp();
4753 /* Initialize GPRS MS side */
4754 f_init_gprs_ms(num_ms);
4755
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004756 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004757 /* Only the 3 first TRX are enabled. The enabled ones all have same
4758 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004759 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4760 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4761 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4762 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004763
4764 /* Initialize the PCU interface abstraction */
4765 f_init_raw(testcasename(), info_ind);
4766
4767 /* Establish BSSGP connection to the PCU */
4768 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004769 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004770
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004771 /* Establish an Uplink TBF for each GprsMS instance */
4772 f_multi_ms_establish_tbf(do_activate := false);
4773
4774 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004775 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004776 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004777 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004778 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004779 f_shutdown(__BFILE__, __LINE__);
4780 }
4781 }
4782
4783 f_shutdown(__BFILE__, __LINE__, final := true);
4784}
4785
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004786/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4787 * downgraded to CS1-4 so that GPRS can read the USF).
4788 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4789 */
4790testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4791 var PCUIF_info_ind info_ind;
4792 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4793 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004794 var uint32_t sched_fn, dl_fn, ack_fn;
4795 var octetstring data := f_rnd_octstring(10);
4796 var RlcmacDlBlock dl_block;
4797 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004798 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004799 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4800 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4801
4802 /* Initialize NS/BSSGP side */
4803 f_init_bssgp();
4804 /* Initialize GPRS MS side */
4805 f_init_gprs_ms(num_ms);
4806
4807 info_ind := valueof(ts_PCUIF_INFO_default);
4808 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004809 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4810 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004811
4812 /* Initialize the PCU interface abstraction */
4813 f_init_raw(testcasename(), info_ind);
4814
4815 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4816 g_mcs_initial_dl := 5;
4817 g_mcs_max_dl := 5;
4818 f_pcuvty_set_allowed_cs_mcs();
4819
4820 /* Establish BSSGP connection to the PCU */
4821 f_bssgp_establish();
4822 f_multi_ms_bssgp_register();
4823
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004824 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004825 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 +01004826 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4827 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4828 f_shutdown(__BFILE__, __LINE__);
4829 }
4830 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4831 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4832
4833 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004834 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 +01004835 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4836 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4837 f_shutdown(__BFILE__, __LINE__);
4838 }
4839 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4840 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4841
4842 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4843 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4844 f_sleep(0.1);
4845 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4846 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4847 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4848 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4849 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4850 /* ACK the DL block */
4851 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4852 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4853 f_dl_block_ack_fn(dl_block, dl_fn));
4854
4855 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4856 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4857 f_sleep(0.1);
4858 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4859 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4860 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4861 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4862 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4863 /* ACK the DL block */
4864 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4865 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4866 f_dl_block_ack_fn(dl_block, dl_fn));
4867
4868 data := f_rnd_octstring(1400);
4869 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4870 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4871
4872 for (var integer i := 0; i < 800; i := i + 1) {
4873 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4874
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07004875 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004876 /* No more data to receive, done */
4877 break;
4878 }
4879
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004880 usf_ms := -1;
4881
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004882 if (ischosen(dl_block.ctrl)) {
4883 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4884 f_shutdown(__BFILE__, __LINE__);
4885 } else if (ischosen(dl_block.data_egprs)) {
4886 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4887 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4888 f_shutdown(__BFILE__, __LINE__);
4889 }
4890 tgt_ms := 1;
4891 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4892 if (dl_block.data_egprs.mcs > MCS_4) {
4893 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4894 f_shutdown(__BFILE__, __LINE__);
4895 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004896 usf_ms := 0;
4897 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004898 } else {
4899 if (dl_block.data_egprs.mcs <= MCS_4) {
4900 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4901 f_shutdown(__BFILE__, __LINE__);
4902 }
4903 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004904 usf_ms := 1;
4905 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004906 }
4907 }
4908 } else {
4909 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4910 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4911 f_shutdown(__BFILE__, __LINE__);
4912 }
4913 tgt_ms := 0;
4914 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 +01004915 usf_ms := 0;
4916 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004917 } 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 +01004918 usf_ms := 1;
4919 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004920 }
4921 }
4922
4923 /* Keep Ack/Nack description updated */
4924 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4925
4926 /* TDMA frame number on which we are supposed to send the ACK */
4927 if (f_dl_block_rrbp_valid(dl_block)) {
4928 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4929 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);
4930 if (tx_data_remain != 0) {
4931 /* Submit more data from time to time to keep the TBF ongoing */
4932 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4933 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4934 tx_data_remain := tx_data_remain - 1;
4935 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004936 } else if (tx_data_remain != 0) {
4937 /* keep sending UL blocks when requested by USF to avoid
4938 * UL TBF timeout and hence stop receival of USFs */
4939 if (usf_ms != -1) {
4940 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4941 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004942 }
4943 }
4944
4945 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 +01004946 /* He we check that DL blocks scheduled at GPRS can still request UL
4947 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4948 * condition also ensures the downgrade to <=MCS4 condition is tested
4949 * above */
4950 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4951 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004952 f_shutdown(__BFILE__, __LINE__);
4953 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004954 /* Here check for some level of fairness between them (at least ~40%): */
4955 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4956 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4957 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4958 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4959 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4960 f_shutdown(__BFILE__, __LINE__);
4961 }
4962 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4963 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4964 f_shutdown(__BFILE__, __LINE__);
4965 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004966
4967 f_shutdown(__BFILE__, __LINE__, final := true);
4968}
4969
4970
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004971private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4972 boolean exp_imsi, boolean exp_tmsi)
4973runs on RAW_PCU_Test_CT {
4974 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4975 var integer pending := lengthof(g_ms);
4976 var RlcmacDlBlock dl_block;
4977 var boolean f1, f2;
4978
4979 while (pending > 0) {
4980 var uint32_t poll_fn;
4981
4982 /* Obtain a Downlink block and make sure it is a paging request */
4983 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4984 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4985 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4986 break;
4987 }
4988
4989 /* This should not happen in general, but who knows... */
4990 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4991 if (not ispresent(req.repeated_pageinfo)) {
4992 setverdict(fail, "Repeated Page Info IE is absent?!?");
4993 break;
4994 }
4995
4996 /* A single message may contain several MIs depending on their type */
4997 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4998 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4999 ps_domain := false);
5000 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
5001 ps_domain := false);
5002 if (not f1 and not f2)
5003 { continue; }
5004
5005 /* Detect duplicate MIs */
5006 if (mask[i] == '1'B) {
5007 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
5008 continue;
5009 }
5010
5011 mask[i] := '1'B;
5012 }
5013
5014 pending := pending - lengthof(req.repeated_pageinfo);
5015 }
5016
5017 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
5018 if (mask[i] != '1'B) {
5019 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
5020 log("===== mask := ", mask);
5021 }
5022 }
5023
5024 /* All messages must have been received by now, expect a dummy block */
5025 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
5026}
5027
5028private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
5029runs on RAW_PCU_Test_CT {
5030 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5031 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5032
5033 /* Initialize NS/BSSGP side */
5034 f_init_bssgp();
5035
5036 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005037 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005038
5039 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
5040 f_init_gprs_ms(7 * 8);
5041
5042 /* Initialize the PCU interface abstraction */
5043 f_init_raw(testcasename(), info_ind);
5044
5045 /* Establish BSSGP connection to the PCU */
5046 f_bssgp_establish();
5047 f_multi_ms_bssgp_register();
5048
5049 /* Establish an Uplink TBF for each GprsMS instance */
5050 f_multi_ms_establish_tbf(do_activate := true);
5051}
5052
5053testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
5054 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5055
5056 /* Common part: send INFO.ind, establish TBFs... */
5057 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5058
5059 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
5060 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5061 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5062 }
5063
5064 /* FIXME: work around a race condition between PCUIF and BSSGP */
5065 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5066
5067 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5068 * The IUT is expected to page on all PDCH slots of all transceivers. */
5069 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5070 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5071 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
5072 }
5073
5074 f_shutdown(__BFILE__, __LINE__, final := true);
5075}
5076
5077testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
5078 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5079
5080 /* Common part: send INFO.ind, establish TBFs... */
5081 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5082
5083 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
5084 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5085 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5086 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5087 }
5088
5089 /* FIXME: work around a race condition between PCUIF and BSSGP */
5090 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5091
5092 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5093 * The IUT is expected to page on all PDCH slots of all transceivers. */
5094 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5095 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5096 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
5097 }
5098
5099 f_shutdown(__BFILE__, __LINE__, final := true);
5100}
5101
5102testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
5103 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5104
5105 /* Common part: send INFO.ind, establish TBFs... */
5106 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5107
5108 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
5109 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5110 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5111 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
5112 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5113 } else {
5114 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5115 }
5116 }
5117
5118 /* FIXME: work around a race condition between PCUIF and BSSGP */
5119 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5120
5121 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5122 * The IUT is expected to page on all PDCH slots of all transceivers. */
5123 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5124 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5125 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
5126 }
5127
5128 f_shutdown(__BFILE__, __LINE__, final := true);
5129}
5130
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005131private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005132runs on RAW_PCU_Test_CT return RlcmacDlBlock {
5133 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005134 var integer i := 0;
5135 while (true) {
5136 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005137 if (not match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005138 break;
5139 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005140 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005141 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5142 f_shutdown(__BFILE__, __LINE__);
5143 }
5144 i := i + 1;
5145 }
5146 return dl_block;
5147}
5148
Vadim Yanitskiy03f74d42023-02-10 09:22:42 +07005149private const GsmMcc c_BssgpCellMcc := '623'H; /* MCC: Central African Republic */
5150private const GsmMnc c_BssgpCellMnc := '03'H; /* MNC: Celca (Socatel) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005151private template (value) BssgpCellId ts_BssgpCellIdDstAddr_default := {
5152 ra_id := {
5153 lai := {
5154 mcc_mnc := f_build_BcdMccMnc(c_BssgpCellMcc, c_BssgpCellMnc),
5155 lac := 423
5156 },
5157 rac := 2
5158 },
5159 cell_id := 5
5160}
5161
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005162private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
5163runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005164 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5165 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5166 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 +01005167 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005168 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005169 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005170 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5171 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5172 var template (value) RAN_Information_RIM_Container res_cont :=
5173 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5174 ts_RIM_Sequence_Number(2),
5175 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5176 ts_RIM_Protocol_Version_Number(1),
5177 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
5178 omit);
5179 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5180 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5181 res_cont));
5182}
5183
5184altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
5185runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005186 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5187 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5188 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 +01005189 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005190 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005191 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005192 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5193 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5194 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5195 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5196 tr_RAN_Information_Request_RIM_Container)) {
5197 if (do_answer) {
5198 f_outbound_nacc_rim_tx_resp(info_ind);
5199 }
5200 if (do_repeat) {
5201 repeat;
5202 }
5203 }
5204}
5205
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005206private function f_ctrl_rx_nacc_rac_ci_req(out CtrlMessage ctrl_req,
5207 PCUIF_info_ind info_ind,
5208 GsmArfcn req_arfcn,
5209 uint6_t req_bsic)
5210runs on RAW_PCU_Test_CT {
5211 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5212 int2str(info_ind.lac) & "." &
5213 int2str(info_ind.cell_id) & "." &
5214 int2str(req_arfcn) & "." &
5215 int2str(req_bsic);
5216 f_ipa_ctrl_wait_link_up();
5217 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value ctrl_req;
5218}
5219
5220private function f_ctrl_tx_nacc_rac_ci_rsp(in CtrlMessage ctrl_req)
5221runs on RAW_PCU_Test_CT {
5222 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5223 IPA_CTRL.send(ts_CtrlMsgGetRepl(ctrl_req.cmd.id,
5224 ctrl_req.cmd.variable,
5225 hex2str(c_BssgpCellMcc) & "-" &
5226 hex2str(c_BssgpCellMnc) & "-" &
5227 int2str(addr.ra_id.lai.lac) & "-" &
5228 int2str(addr.ra_id.rac) & "-" &
5229 int2str(addr.cell_id)));
5230}
5231
5232private function f_pcuif_rx_nacc_rac_ci_req(out PCUIF_Message addr_req,
5233 PCUIF_info_ind info_ind,
5234 GsmArfcn req_arfcn,
5235 uint6_t req_bsic)
5236runs on RAW_PCU_Test_CT {
5237 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id,
5238 req_arfcn, req_bsic)) -> value addr_req;
5239}
5240
5241private function f_pcuif_tx_nacc_rac_ci_rsp(in PCUIF_Message addr_req)
5242runs on RAW_PCU_Test_CT {
5243 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5244 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, addr_req.u.container.u.neigh_addr_req, 0,
5245 str2int(hex2str(c_BssgpCellMcc)),
5246 str2int(hex2str(c_BssgpCellMnc)),
5247 lengthof(c_BssgpCellMnc) - 2,
5248 addr.ra_id.lai.lac,
5249 addr.ra_id.rac,
5250 addr.cell_id));
5251}
5252
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005253private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
5254 boolean answer := true, boolean use_old_ctrl_iface := false)
5255runs on RAW_PCU_Test_CT {
5256 if (use_old_ctrl_iface == true) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005257 var CtrlMessage ctrl_req;
5258 f_ctrl_rx_nacc_rac_ci_req(ctrl_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005259 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005260 f_ctrl_tx_nacc_rac_ci_rsp(ctrl_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005261 }
5262 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005263 var PCUIF_Message pcuif_req;
5264 f_pcuif_rx_nacc_rac_ci_req(pcuif_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005265 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005266 f_pcuif_tx_nacc_rac_ci_rsp(pcuif_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005267 }
5268 }
5269}
5270
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005271/* Start NACC from MS side */
5272private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005273 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005274 boolean skip_final_ctrl_ack := false,
5275 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005276runs on RAW_PCU_Test_CT {
5277 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5278 var RlcmacDlBlock dl_block;
5279 var uint32_t sched_fn;
5280 var GsmArfcn req_arfcn := 862;
5281 var uint6_t req_bsic := 43;
5282
5283 /* Start NACC from MS side */
5284 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5285 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5286
5287 if (exp_rac_ci_query == true) {
5288 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005289 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 +01005290 }
5291
5292 if (exp_si_query == true) {
5293 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005294 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005295 }
5296
5297 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005298 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005299
5300 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5301 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5302 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5303 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5304 f_shutdown(__BFILE__, __LINE__);
5305 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005306 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005307 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005308 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5309 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5310 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005311}
5312
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005313/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
5314testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005315 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005316 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005317 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005318 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005319
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005320 if (use_old_ctrl_iface) {
5321 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5322 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5323 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005324
5325 /* Initialize NS/BSSGP side */
5326 f_init_bssgp();
5327 /* Initialize GPRS MS side */
5328 f_init_gprs_ms();
5329 ms := g_ms[0]; /* We only use first MS in this test */
5330
5331 /* Initialize the PCU interface abstraction */
5332 f_init_raw(testcasename(), info_ind);
5333
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005334 /* Make sure we are not affected by full cache from previous tests */
5335 f_pcuvty_flush_neigh_caches();
5336
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005337 /* Establish BSSGP connection to the PCU */
5338 f_bssgp_establish();
5339 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5340
5341 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005342 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 +01005343 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5344 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5345
5346 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005347 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005348
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005349 f_shutdown(__BFILE__, __LINE__, final := true);
5350}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005351
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005352/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5353testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5354 var PollFnCtx pollctx;
5355 var GprsMS ms;
5356 var RlcmacDlBlock dl_block;
5357 var uint32_t sched_fn;
5358 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005359 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005360
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005361 if (use_old_ctrl_iface) {
5362 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5363 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5364 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005365
5366 /* Initialize NS/BSSGP side */
5367 f_init_bssgp();
5368 /* Initialize GPRS MS side */
5369 f_init_gprs_ms();
5370 ms := g_ms[0]; /* We only use first MS in this test */
5371
5372 /* Initialize the PCU interface abstraction */
5373 f_init_raw(testcasename(), info_ind);
5374
5375 /* Make sure we are not affected by full cache from previous tests */
5376 f_pcuvty_flush_neigh_caches();
5377
5378 /* Establish BSSGP connection to the PCU */
5379 f_bssgp_establish();
5380 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5381
5382 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005383 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 +01005384 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5385 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5386
5387 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005388 f_outbound_nacc_success(ms, info_ind, skip_final_ctrl_ack := true, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005389
5390 /* Wait until we receive something non-dummy */
5391 dl_block := f_skip_dummy(0, sched_fn);
5392 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5393 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5394 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5395 }
5396 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5397 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5398 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5399 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5400 }
5401
5402 f_shutdown(__BFILE__, __LINE__, final := true);
5403}
5404
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005405/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5406testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5407 var PollFnCtx pollctx;
5408 var GprsMS ms;
5409 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005410 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005411 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005412
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005413 if (use_old_ctrl_iface) {
5414 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5415 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5416 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005417
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005418 /* Initialize NS/BSSGP side */
5419 f_init_bssgp();
5420 /* Initialize GPRS MS side */
5421 f_init_gprs_ms();
5422 ms := g_ms[0]; /* We only use first MS in this test */
5423
5424 /* Initialize the PCU interface abstraction */
5425 f_init_raw(testcasename(), info_ind);
5426
5427 /* Make sure we are not affected by full cache from previous tests */
5428 f_pcuvty_flush_neigh_caches();
5429 /* Set timeout values for caches so that entries will be in cache during second try */
5430 f_pcuvty_set_neigh_caches(10, 10);
5431
5432 /* Establish BSSGP connection to the PCU */
5433 f_bssgp_establish();
5434 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5435
5436 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005437 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 +01005438 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5439 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5440
5441 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005442 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005443
5444 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005445 f_outbound_nacc_success(ms, info_ind, false, false, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005446
5447 f_shutdown(__BFILE__, __LINE__, final := true);
5448}
5449
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005450/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5451 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5452 */
5453testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5454 var PollFnCtx pollctx;
5455 var GprsMS ms;
5456 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005457 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005458 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005459
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005460 if (use_old_ctrl_iface) {
5461 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5462 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5463 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005464
5465 /* Initialize NS/BSSGP side */
5466 f_init_bssgp();
5467 /* Initialize GPRS MS side */
5468 f_init_gprs_ms();
5469 ms := g_ms[0]; /* We only use first MS in this test */
5470
5471 /* Initialize the PCU interface abstraction */
5472 f_init_raw(testcasename(), info_ind);
5473
5474 /* Make sure we are not affected by full cache from previous tests */
5475 f_pcuvty_flush_neigh_caches();
5476 /* Set timeout values for caches so that entries will be erased before the second try */
5477 f_pcuvty_set_neigh_caches(1, 1);
5478
5479 /* Establish BSSGP connection to the PCU */
5480 f_bssgp_establish();
5481 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5482
5483 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005484 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 +01005485 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5486 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5487
5488 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005489 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005490
5491 /* CTRL client should have disconnected from us */
5492 f_ipa_ctrl_wait_link_down();
5493 /* wait for cache entries to time out */
5494 f_sleep(2.0);
5495 /* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005496 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005497
5498 f_shutdown(__BFILE__, __LINE__, final := true);
5499}
5500
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005501/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005502testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5503 var RlcmacDlBlock dl_block;
5504 var PollFnCtx pollctx;
5505 var uint32_t sched_fn;
5506 var GprsMS ms;
5507 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5508 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005509 var GsmArfcn req_arfcn := 862;
5510 var uint6_t req_bsic := 43;
5511
5512 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5513 * resolution CTRL port, to trigger Conn Refused by socket:
5514 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5515 */
5516
5517 /* Initialize NS/BSSGP side */
5518 f_init_bssgp();
5519 /* Initialize GPRS MS side */
5520 f_init_gprs_ms();
5521 ms := g_ms[0]; /* We only use first MS in this test */
5522
5523 /* Initialize the PCU interface abstraction */
5524 f_init_raw(testcasename(), info_ind);
5525
5526 /* Make sure we are not affected by full cache from previous tests */
5527 f_pcuvty_flush_neigh_caches();
5528
5529 /* Establish BSSGP connection to the PCU */
5530 f_bssgp_establish();
5531 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5532
5533 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005534 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 +01005535 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5536 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5537
5538 /* Start NACC from MS side */
5539 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5540 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5541
5542 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005543 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005544 /* Make sure it is a Pkt Cell Chg Continue */
5545 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5546 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5547 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005548 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5549 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5550 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5551 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5552 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005553
5554 f_shutdown(__BFILE__, __LINE__, final := true);
5555}
5556
5557/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005558testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5559 var RlcmacDlBlock dl_block;
5560 var PollFnCtx pollctx;
5561 var uint32_t sched_fn;
5562 var GprsMS ms;
5563 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5564 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005565 var GsmArfcn req_arfcn := 862;
5566 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005567 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005568
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005569 if (use_old_ctrl_iface) {
5570 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5571 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5572 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005573
5574 /* Initialize NS/BSSGP side */
5575 f_init_bssgp();
5576 /* Initialize GPRS MS side */
5577 f_init_gprs_ms();
5578 ms := g_ms[0]; /* We only use first MS in this test */
5579
5580 /* Initialize the PCU interface abstraction */
5581 f_init_raw(testcasename(), info_ind);
5582
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005583 /* Make sure we are not affected by full cache from previous tests */
5584 f_pcuvty_flush_neigh_caches();
5585
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005586 /* Establish BSSGP connection to the PCU */
5587 f_bssgp_establish();
5588 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5589
5590 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005591 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 +01005592 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5593 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5594
5595 /* Start NACC from MS side */
5596 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5597 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5598
5599 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005600 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005601 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 +01005602
5603 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005604 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005605 /* Make sure it is a Pkt Cell Chg Continue */
5606 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5607 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5608 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005609 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5610 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5611 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5612 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5613 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005614
5615 f_shutdown(__BFILE__, __LINE__, final := true);
5616}
5617
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005618/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5619testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5620 var RlcmacDlBlock dl_block;
5621 var PollFnCtx pollctx;
5622 var uint32_t sched_fn;
5623 var GprsMS ms;
5624 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5625 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005626 var GsmArfcn req_arfcn := 862;
5627 var uint6_t req_bsic := 43;
5628
5629 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5630 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5631
5632 /* Initialize NS/BSSGP side */
5633 f_init_bssgp();
5634 /* Initialize GPRS MS side */
5635 f_init_gprs_ms();
5636 ms := g_ms[0]; /* We only use first MS in this test */
5637
5638 /* Initialize the PCU interface abstraction */
5639 f_init_raw(testcasename(), info_ind);
5640
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005641 /* Make sure we are not affected by full cache from previous tests */
5642 f_pcuvty_flush_neigh_caches();
5643
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005644 /* Establish BSSGP connection to the PCU */
5645 f_bssgp_establish();
5646 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5647
5648 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005649 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 +01005650 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5651 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5652
5653 /* Start NACC from MS side */
5654 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5655 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5656
5657 /* osmo-pcu should now ask for resolution: */
5658 f_ipa_ctrl_wait_link_up();
5659 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5660 int2str(info_ind.lac) & "." &
5661 int2str(info_ind.cell_id) & "." &
5662 int2str(req_arfcn) & "." &
5663 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005664 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005665 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5666
5667 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005668 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005669 /* Make sure it is a Pkt Cell Chg Continue */
5670 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5671 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5672 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005673 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5674 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5675 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5676 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5677 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005678
5679 f_shutdown(__BFILE__, __LINE__, final := true);
5680}
5681
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005682/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5683testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5684 var RlcmacDlBlock dl_block;
5685 var PollFnCtx pollctx;
5686 var uint32_t sched_fn;
5687 var GprsMS ms;
5688 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5689 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005690 var GsmArfcn req_arfcn := 862;
5691 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005692 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005693
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005694 if (use_old_ctrl_iface) {
5695 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5696 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5697 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005698
5699 /* Initialize NS/BSSGP side */
5700 f_init_bssgp();
5701 /* Initialize GPRS MS side */
5702 f_init_gprs_ms();
5703 ms := g_ms[0]; /* We only use first MS in this test */
5704
5705 /* Initialize the PCU interface abstraction */
5706 f_init_raw(testcasename(), info_ind);
5707
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005708 /* Make sure we are not affected by full cache from previous tests */
5709 f_pcuvty_flush_neigh_caches();
5710
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005711 /* Establish BSSGP connection to the PCU */
5712 f_bssgp_establish();
5713 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5714
5715 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005716 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 +01005717 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5718 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5719
5720 /* Start NACC from MS side */
5721 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5722 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5723
5724 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005725 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 +01005726
5727 /* RIM procedure: */
Vadim Yanitskiyd8aa5e82023-02-12 17:11:42 +07005728 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005729 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5730
5731 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005732 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005733 /* Make sure it is a Pkt Cell Chg Continue */
5734 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5735 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5736 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005737 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5738 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5739 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5740 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5741 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005742
5743 f_shutdown(__BFILE__, __LINE__, final := true);
5744}
5745
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005746/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5747testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5748 var PollFnCtx pollctx;
5749 var GprsMS ms;
5750 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5751 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5752 var RlcmacDlBlock dl_block;
5753 var uint32_t sched_fn;
5754 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005755 var charstring ctrl_var;
5756 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005757 var GsmArfcn req_arfcn := 862;
5758 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005759 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005760
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005761 if (use_old_ctrl_iface) {
5762 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5763 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5764 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005765
5766 /* Initialize NS/BSSGP side */
5767 f_init_bssgp();
5768 /* Initialize GPRS MS side */
5769 f_init_gprs_ms();
5770 ms := g_ms[0]; /* We only use first MS in this test */
5771
5772 /* Initialize the PCU interface abstraction */
5773 f_init_raw(testcasename(), info_ind);
5774
5775 /* Make sure we are not affected by full cache from previous tests */
5776 f_pcuvty_flush_neigh_caches();
5777
5778 /* Establish BSSGP connection to the PCU */
5779 f_bssgp_establish();
5780 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5781
5782 /* Send PACKET RESOURCE REQUEST */
5783 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5784 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5785 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5786
5787 /* Start NACC from MS side */
5788 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5789 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5790
5791 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005792 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005793 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005794 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005795 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005796 }
5797
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005798 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5799 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5800 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005801
5802 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005803 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005804 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005805 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005806 }
5807
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005808 timer T := 2.0;
5809 T.start;
5810 alt {
5811 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005812 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005813 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5814 f_shutdown(__BFILE__, __LINE__);
5815 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005816 [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 {
5817 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5818 f_shutdown(__BFILE__, __LINE__);
5819 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005820 [] T.timeout {
5821 setverdict(pass);
5822 }
5823 }
5824
5825 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005826 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005827
5828 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5829 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5830 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5831 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5832 f_shutdown(__BFILE__, __LINE__);
5833 }
5834 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5835 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5836 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5837 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5838 }
5839
5840 f_shutdown(__BFILE__, __LINE__, final := true);
5841}
5842
5843/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5844testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5845 var PollFnCtx pollctx;
5846 var GprsMS ms;
5847 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5848 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5849 var RlcmacDlBlock dl_block;
5850 var uint32_t sched_fn;
5851 var CtrlMessage rx_ctrl;
5852 var GsmArfcn req_arfcn := 862;
5853 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005854 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005855
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005856 if (use_old_ctrl_iface) {
5857 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5858 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5859 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005860
5861 /* Initialize NS/BSSGP side */
5862 f_init_bssgp();
5863 /* Initialize GPRS MS side */
5864 f_init_gprs_ms();
5865 ms := g_ms[0]; /* We only use first MS in this test */
5866
5867 /* Initialize the PCU interface abstraction */
5868 f_init_raw(testcasename(), info_ind);
5869
5870 /* Make sure we are not affected by full cache from previous tests */
5871 f_pcuvty_flush_neigh_caches();
5872
5873 /* Establish BSSGP connection to the PCU */
5874 f_bssgp_establish();
5875 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5876
5877 /* Send PACKET RESOURCE REQUEST */
5878 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5879 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5880 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5881
5882 /* Start NACC from MS side */
5883 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5884 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5885
5886 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005887 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 +01005888 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5889 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5890 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5891 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5892 f_outbound_nacc_rim_tx_resp(info_ind);
5893 timer T := 1.0;
5894 T.start;
5895 alt {
5896 [] RIM.receive {
5897 setverdict(fail, "Received unexpected RIM message");
5898 f_shutdown(__BFILE__, __LINE__);
5899 }
5900 [] T.timeout {
5901 setverdict(pass);
5902 }
5903 }
5904
5905 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005906 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005907
5908 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5909 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5910 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5911 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5912 f_shutdown(__BFILE__, __LINE__);
5913 }
5914 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5915 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5916 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5917 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5918 }
5919
5920 f_shutdown(__BFILE__, __LINE__, final := true);
5921}
5922
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005923/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5924testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5925 var PollFnCtx pollctx;
5926 var GprsMS ms;
5927 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5928 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5929 var RlcmacDlBlock dl_block;
5930 var uint32_t sched_fn;
5931 var CtrlMessage rx_ctrl;
5932 var GsmArfcn req_arfcn := 862;
5933 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005934 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005935
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005936 if (use_old_ctrl_iface) {
5937 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5938 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5939 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005940
5941 /* Initialize NS/BSSGP side */
5942 f_init_bssgp();
5943 /* Initialize GPRS MS side */
5944 f_init_gprs_ms();
5945 ms := g_ms[0]; /* We only use first MS in this test */
5946
5947 /* Initialize the PCU interface abstraction */
5948 f_init_raw(testcasename(), info_ind);
5949
5950 /* Make sure we are not affected by full cache from previous tests */
5951 f_pcuvty_flush_neigh_caches();
5952
5953 /* Establish BSSGP connection to the PCU */
5954 f_bssgp_establish();
5955 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5956
5957 /* Send PACKET RESOURCE REQUEST */
5958 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5959 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5960 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5961
5962 /* Start NACC from MS side */
5963 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5964 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5965
5966 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005967 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 +01005968 /* RIM procedure: */
5969 as_outbound_nacc_rim_resolve(info_ind);
5970
5971 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5972 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5973 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5974
5975 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5976 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5977
5978 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5979 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5980 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5981 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5982 f_shutdown(__BFILE__, __LINE__);
5983 }
5984 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5985 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5986 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5987 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5988 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02005989
5990 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005991}
5992
5993/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5994testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5995 var PollFnCtx pollctx;
5996 var GprsMS ms;
5997 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5998 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5999 var RlcmacDlBlock dl_block;
6000 var uint32_t sched_fn;
6001 var CtrlMessage rx_ctrl;
6002 var GsmArfcn req_arfcn := 862;
6003 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006004 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006005
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006006 if (use_old_ctrl_iface) {
6007 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6008 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6009 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006010
6011 /* Initialize NS/BSSGP side */
6012 f_init_bssgp();
6013 /* Initialize GPRS MS side */
6014 f_init_gprs_ms();
6015 ms := g_ms[0]; /* We only use first MS in this test */
6016
6017 /* Initialize the PCU interface abstraction */
6018 f_init_raw(testcasename(), info_ind);
6019
6020 /* Make sure we are not affected by full cache from previous tests */
6021 f_pcuvty_flush_neigh_caches();
6022
6023 /* Establish BSSGP connection to the PCU */
6024 f_bssgp_establish();
6025 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6026
6027 /* Send PACKET RESOURCE REQUEST */
6028 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6029 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6030 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6031
6032 /* Start NACC from MS side */
6033 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6034 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6035
6036 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006037 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 +01006038 /* RIM procedure: */
6039 as_outbound_nacc_rim_resolve(info_ind);
6040
6041 /* Announce SI back to MS, continue NACC procedure */
6042 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6043
6044 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
6045 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6046
6047 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6048 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6049 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6050 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6051 f_shutdown(__BFILE__, __LINE__);
6052 }
6053 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6054 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6055 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6056 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6057 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006058
6059 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006060}
6061
6062/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
6063testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
6064 var PollFnCtx pollctx;
6065 var GprsMS ms;
6066 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6067 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6068 var RlcmacDlBlock dl_block;
6069 var uint32_t sched_fn;
6070 var CtrlMessage rx_ctrl;
6071 var GsmArfcn req_arfcn := 862;
6072 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006073 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006074
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006075 if (use_old_ctrl_iface) {
6076 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6077 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6078 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006079
6080 /* Initialize NS/BSSGP side */
6081 f_init_bssgp();
6082 /* Initialize GPRS MS side */
6083 f_init_gprs_ms();
6084 ms := g_ms[0]; /* We only use first MS in this test */
6085
6086 /* Initialize the PCU interface abstraction */
6087 f_init_raw(testcasename(), info_ind);
6088
6089 /* Make sure we are not affected by full cache from previous tests */
6090 f_pcuvty_flush_neigh_caches();
6091
6092 /* Establish BSSGP connection to the PCU */
6093 f_bssgp_establish();
6094 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6095
6096 /* Send PACKET RESOURCE REQUEST */
6097 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6098 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6099 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6100
6101 /* Start NACC from MS side */
6102 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6103 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6104
6105 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006106 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 +01006107 /* RIM procedure: */
6108 as_outbound_nacc_rim_resolve(info_ind);
6109
6110 /* Announce SI back to MS, continue NACC procedure */
6111 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6112
6113 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6114 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6115 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6116 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6117 f_shutdown(__BFILE__, __LINE__);
6118 }
6119 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
6120 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6121
6122 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6123 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6124 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6125 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6126 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006127
6128 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006129}
6130
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006131/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6132 * while waiting for CTRL resolution */
6133testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
6134 var PollFnCtx pollctx;
6135 var GprsMS ms;
6136 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6137 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6138 var RlcmacDlBlock dl_block;
6139 var uint32_t sched_fn;
6140 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006141 var charstring ctrl_var;
6142 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006143 var GsmArfcn req_arfcn := 862;
6144 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006145 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006146
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006147 if (use_old_ctrl_iface) {
6148 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6149 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6150 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006151
6152 /* Initialize NS/BSSGP side */
6153 f_init_bssgp();
6154 /* Initialize GPRS MS side */
6155 f_init_gprs_ms();
6156 ms := g_ms[0]; /* We only use first MS in this test */
6157
6158 /* Initialize the PCU interface abstraction */
6159 f_init_raw(testcasename(), info_ind);
6160
6161 /* Make sure we are not affected by full cache from previous tests */
6162 f_pcuvty_flush_neigh_caches();
6163
6164 /* Establish BSSGP connection to the PCU */
6165 f_bssgp_establish();
6166 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6167
6168 /* Send PACKET RESOURCE REQUEST */
6169 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6170 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6171 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6172
6173 /* Start NACC from MS side */
6174 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6175 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6176
6177 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006178 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006179 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006180 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006181 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006182 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006183 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
6184 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6185 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6186 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006187 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006188 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006189 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006190 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006191 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006192 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006193 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 +01006194
6195 /* And finally everything continues as usual with RIN procedure */
6196 as_outbound_nacc_rim_resolve(info_ind);
6197
6198 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006199 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006200
6201 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6202 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6203 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6204 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6205 f_shutdown(__BFILE__, __LINE__);
6206 }
6207 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6208 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6209 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6210 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6211 }
6212
6213 f_shutdown(__BFILE__, __LINE__, final := true);
6214}
6215
6216/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6217 * while waiting for SI resolution */
6218testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
6219 var PollFnCtx pollctx;
6220 var GprsMS ms;
6221 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6222 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6223 var RlcmacDlBlock dl_block;
6224 var uint32_t sched_fn;
6225 var CtrlMessage rx_ctrl;
6226 var GsmArfcn req_arfcn := 862;
6227 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006228 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006229
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006230 if (use_old_ctrl_iface) {
6231 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6232 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6233 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006234
6235 /* Initialize NS/BSSGP side */
6236 f_init_bssgp();
6237 /* Initialize GPRS MS side */
6238 f_init_gprs_ms();
6239 ms := g_ms[0]; /* We only use first MS in this test */
6240
6241 /* Initialize the PCU interface abstraction */
6242 f_init_raw(testcasename(), info_ind);
6243
6244 /* Make sure we are not affected by full cache from previous tests */
6245 f_pcuvty_flush_neigh_caches();
6246
6247 /* Establish BSSGP connection to the PCU */
6248 f_bssgp_establish();
6249 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6250
6251 /* Send PACKET RESOURCE REQUEST */
6252 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6253 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6254 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6255
6256 /* Start NACC from MS side */
6257 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6258 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6259
6260 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006261 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 +01006262 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6263 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
6264 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6265 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6266 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6267 f_outbound_nacc_rim_tx_resp(info_ind);
6268
6269 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006270 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 +01006271
6272 /* And finally everything continues as usual with RIN procedure */
6273 as_outbound_nacc_rim_resolve(info_ind);
6274
6275 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006276 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006277
6278 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6279 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6280 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6281 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6282 f_shutdown(__BFILE__, __LINE__);
6283 }
6284 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6285 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6286 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6287 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6288 }
6289
6290 f_shutdown(__BFILE__, __LINE__, final := true);
6291}
6292
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006293/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6294 * while sending Pkt Neigh Data Change */
6295testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6296 var PollFnCtx pollctx;
6297 var GprsMS ms;
6298 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6299 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6300 var RlcmacDlBlock dl_block;
6301 var uint32_t sched_fn;
6302 var CtrlMessage rx_ctrl;
6303 var GsmArfcn req_arfcn := 862;
6304 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006305 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006306
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006307 if (use_old_ctrl_iface) {
6308 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6309 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6310 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006311
6312 /* Initialize NS/BSSGP side */
6313 f_init_bssgp();
6314 /* Initialize GPRS MS side */
6315 f_init_gprs_ms();
6316 ms := g_ms[0]; /* We only use first MS in this test */
6317
6318 /* Initialize the PCU interface abstraction */
6319 f_init_raw(testcasename(), info_ind);
6320
6321 /* Make sure we are not affected by full cache from previous tests */
6322 f_pcuvty_flush_neigh_caches();
6323
6324 /* Establish BSSGP connection to the PCU */
6325 f_bssgp_establish();
6326 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6327
6328 /* Send PACKET RESOURCE REQUEST */
6329 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6330 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6331 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6332
6333 /* Start NACC from MS side */
6334 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6335 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6336
6337 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006338 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 +01006339 /* RIM procedure: */
6340 as_outbound_nacc_rim_resolve(info_ind);
6341
6342 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6343 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6344 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6345 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6346
6347 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006348 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 +01006349 /* RIM procedure: */
6350 as_outbound_nacc_rim_resolve(info_ind);
6351 /* Transmit SI back to MS */
6352 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6353
6354 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6355 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6356 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6357 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6358 f_shutdown(__BFILE__, __LINE__);
6359 }
6360 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6361 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6362 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6363 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6364 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006365
6366 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006367}
6368
6369/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6370testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6371 var PollFnCtx pollctx;
6372 var GprsMS ms;
6373 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6374 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6375 var RlcmacDlBlock dl_block;
6376 var uint32_t sched_fn;
6377 var CtrlMessage rx_ctrl;
6378 var GsmArfcn req_arfcn := 862;
6379 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006380 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006381
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006382 if (use_old_ctrl_iface) {
6383 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6384 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6385 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006386
6387 /* Initialize NS/BSSGP side */
6388 f_init_bssgp();
6389 /* Initialize GPRS MS side */
6390 f_init_gprs_ms();
6391 ms := g_ms[0]; /* We only use first MS in this test */
6392
6393 /* Initialize the PCU interface abstraction */
6394 f_init_raw(testcasename(), info_ind);
6395
6396 /* Make sure we are not affected by full cache from previous tests */
6397 f_pcuvty_flush_neigh_caches();
6398
6399 /* Establish BSSGP connection to the PCU */
6400 f_bssgp_establish();
6401 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6402
6403 /* Send PACKET RESOURCE REQUEST */
6404 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6405 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6406 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6407
6408 /* Start NACC from MS side */
6409 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6410 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6411
6412 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006413 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 +01006414 /* RIM procedure: */
6415 as_outbound_nacc_rim_resolve(info_ind);
6416
6417 /* Announce SI back to MS, continue NACC procedure */
6418 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6419
6420 /* trigger a Pkt Cell Change Notif with different tgt cell */
6421 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6422 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6423
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006424 /* It should trigger RAC_CI resolution to start again: */
6425 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6426
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006427 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6428 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6429
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006430 /* RIM procedure: */
6431 as_outbound_nacc_rim_resolve(info_ind);
6432 /* Transmit SI back to MS */
6433 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6434
6435 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6436 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6437 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6438 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6439 f_shutdown(__BFILE__, __LINE__);
6440 }
6441 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6442 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6443 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6444 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6445 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006446
6447 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006448}
6449
6450/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6451testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6452 var PollFnCtx pollctx;
6453 var GprsMS ms;
6454 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6455 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6456 var RlcmacDlBlock dl_block;
6457 var uint32_t sched_fn;
6458 var CtrlMessage rx_ctrl;
6459 var GsmArfcn req_arfcn := 862;
6460 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006461 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006462
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006463 if (use_old_ctrl_iface) {
6464 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6465 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6466 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006467
6468 /* Initialize NS/BSSGP side */
6469 f_init_bssgp();
6470 /* Initialize GPRS MS side */
6471 f_init_gprs_ms();
6472 ms := g_ms[0]; /* We only use first MS in this test */
6473
6474 /* Initialize the PCU interface abstraction */
6475 f_init_raw(testcasename(), info_ind);
6476
6477 /* Make sure we are not affected by full cache from previous tests */
6478 f_pcuvty_flush_neigh_caches();
6479
6480 /* Establish BSSGP connection to the PCU */
6481 f_bssgp_establish();
6482 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6483
6484 /* Send PACKET RESOURCE REQUEST */
6485 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6486 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6487 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6488
6489 /* Start NACC from MS side */
6490 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6491 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6492
6493 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006494 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 +01006495 /* RIM procedure: */
6496 as_outbound_nacc_rim_resolve(info_ind);
6497
6498 /* Announce SI back to MS, continue NACC procedure */
6499 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6500
6501 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6502 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6503 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6504 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6505 f_shutdown(__BFILE__, __LINE__);
6506 }
6507
6508 /* trigger a Pkt Cell Change Notif with different tgt cell */
6509 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6510 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6511
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006512 /* It should trigger RAC_CI resolution to start again: */
6513 /* When using new PCUIF interface for resolution, we must
6514 * PCUIF.receive() here since that's the first message in the PCUIF
6515 * queue that PCU will have sent. Calling other functions doing
6516 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6517 * due to unexpected message receive. */
6518 if (not use_old_ctrl_iface) {
6519 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6520 }
6521
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006522 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6523 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6524 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6525 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6526 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006527
6528 /* When using CTRL interface, we must schedule the ACK before (see
6529 * above) blocking here waiting for the resoltion, otherwise we'll be
6530 * too late scheduling by the time the resolution is done. */
6531 if (use_old_ctrl_iface) {
6532 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6533 }
6534
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006535 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6536 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6537
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006538 /* RIM procedure: */
6539 as_outbound_nacc_rim_resolve(info_ind);
6540 /* Transmit SI back to MS */
6541 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6542
6543 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6544 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6545 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6546 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6547 f_shutdown(__BFILE__, __LINE__);
6548 }
6549 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6550 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6551 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6552 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6553 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006554
6555 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006556}
6557
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006558/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6559testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6560 var PollFnCtx pollctx;
6561 var GprsMS ms;
6562 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6563 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6564 var RlcmacDlBlock dl_block;
6565 var uint32_t sched_fn, dl_fn;
6566 var CtrlMessage rx_ctrl;
6567 var GsmArfcn req_arfcn := 862;
6568 var uint6_t req_bsic := 43;
6569 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006570 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006571
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006572 if (use_old_ctrl_iface) {
6573 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6574 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6575 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006576
6577 /* Initialize NS/BSSGP side */
6578 f_init_bssgp();
6579 /* Initialize GPRS MS side */
6580 f_init_gprs_ms();
6581 ms := g_ms[0]; /* We only use first MS in this test */
6582
6583 /* Initialize the PCU interface abstraction */
6584 f_init_raw(testcasename(), info_ind);
6585
6586 /* Make sure we are not affected by full cache from previous tests */
6587 f_pcuvty_flush_neigh_caches();
6588
6589 /* Establish BSSGP connection to the PCU */
6590 f_bssgp_establish();
6591 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6592
6593 /* Send PACKET RESOURCE REQUEST */
6594 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6595 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6596 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6597
6598 /* Start NACC from MS side */
6599 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6600 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6601
6602 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006603 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 +01006604 /* RIM procedure: */
6605 as_outbound_nacc_rim_resolve(info_ind);
6606
6607 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6608 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6609 f_sleep(0.1);
6610 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6611 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6612
6613 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6614 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6615 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6616 * Data with unassigned DL TBF in line above): */
6617 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6618 /* Continue receiving Pkt Cell Neighbor Data */
6619 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6620
6621 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6622 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6623 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6624 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6625 f_shutdown(__BFILE__, __LINE__);
6626 }
6627 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6628 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6629 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6630 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6631 }
6632
6633 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6634 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6635 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6636 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6637 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006638
6639 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006640}
6641
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006642
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006643function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6644runs on RAW_PCU_Test_CT
6645{
6646 var template (value) RAN_Information_Request_RIM_Container req_cont;
6647 var template (value) PDU_BSSGP bssgp_rim_pdu;
6648 var template PDU_BSSGP bssgp_rim_pdu_expect;
6649 var template RAN_Information_RIM_Container rim_cont_expect;
6650 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006651
6652 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006653 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 +01006654 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006655 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 +01006656 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006657 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);
6658 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006659 f_sleep(1.0);
6660
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006661 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006662
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006663 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6664 ts_RIM_Sequence_Number(1),
6665 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6666 ts_RIM_Protocol_Version_Number(1),
6667 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6668 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006669 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6670 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006671
6672 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6673 tr_RIM_Sequence_Number(1),
6674 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6675 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006676 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 +01006677 omit);
6678
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006679 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6680 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006681 rim_cont_expect);
6682 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006683 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006684 T.start;
6685 alt {
6686 [] RIM.receive(bssgp_rim_pdu_expect) { }
6687 [] RIM.receive {
6688 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6689 }
6690 [] T.timeout {
6691 setverdict(fail, "No BSSGP RIM PDU received");
6692 mtc.stop;
6693 }
6694 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006695}
6696/* Send a RIM RAN info request to the PCU and verify the response, we expect
6697 * getting the system information back which we have transfered to the PCU via
6698 * PCUIF on startup. */
6699testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6700 /* Initialize NS/BSSGP side */
6701 f_init_bssgp();
6702
6703 /* Initialize the PCU interface abstraction */
6704 f_init_raw(testcasename());
6705
6706 /* Establish BSSGP connection to the PCU */
6707 f_bssgp_establish();
6708
6709 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6710 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6711
6712 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6713 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6714
6715 f_shutdown(__BFILE__, __LINE__, final := true);
6716}
6717
6718/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6719 * Routing information, to verify PCU handles that kind of address just fine
6720 */
6721testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6722 /* Initialize NS/BSSGP side */
6723 f_init_bssgp();
6724
6725 /* Initialize the PCU interface abstraction */
6726 f_init_raw(testcasename());
6727
6728 /* Establish BSSGP connection to the PCU */
6729 f_bssgp_establish();
6730
6731 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6732 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6733
6734 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6735 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006736
6737 f_shutdown(__BFILE__, __LINE__, final := true);
6738}
6739
6740/* Same as above, but in this case we simulate the rare case in which the PCU
6741 * has no system information available. We expect getting a response back but
6742 * with no system information inside. */
6743testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006744 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006745 var PCUIF_Message pcu_msg;
6746 timer T := 2.0;
6747
6748 /* Initialize NS/BSSGP side */
6749 f_init_bssgp();
6750
6751 /* Initialize the PCU interface abstraction */
6752 f_init_raw(testcasename(), info_ind);
6753
6754 /* Establish BSSGP connection to the PCU */
6755 f_bssgp_establish();
6756
6757 /* Clear sysinfo from the PCU */
6758 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);
6759 BTS.send(si1_data_ind);
6760 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);
6761 BTS.send(si3_data_ind);
6762 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);
6763 BTS.send(si16_data_ind);
6764 f_sleep(1.0);
6765
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006766 var RIM_Routing_Address dst_addr;
6767 var RIM_Routing_Address src_addr;
6768 var template (value) RAN_Information_Request_RIM_Container req_cont;
6769 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006770 var template PDU_BSSGP bssgp_rim_pdu_expect;
6771 var template RAN_Information_RIM_Container rim_cont_expect;
6772
6773 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 +01006774 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6775 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006776
6777 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6778 ts_RIM_Sequence_Number(1),
6779 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6780 ts_RIM_Protocol_Version_Number(1),
6781 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6782 omit);
6783 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6784 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6785 req_cont);
6786
6787
6788 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6789 tr_RIM_Sequence_Number(1),
6790 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6791 tr_RIM_Protocol_Version_Number(1),
6792 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6793 omit);
6794
6795 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6796 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6797 rim_cont_expect);
6798 RIM.send(bssgp_rim_pdu);
6799 T.start;
6800 alt {
6801 [] RIM.receive(bssgp_rim_pdu_expect) { }
6802 [] RIM.receive {
6803 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6804 }
6805 [] T.timeout {
6806 setverdict(fail, "No BSSGP RIM PDU received");
6807 mtc.stop;
6808 }
6809 }
6810
6811 f_shutdown(__BFILE__, __LINE__, final := true);
6812}
6813
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006814/* 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 +02006815testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6816 var PCUIF_info_ind info_ind;
6817 var template (value) TsTrxBtsNum nr;
6818 var RlcmacDlBlock dl_block;
6819 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006820 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006821 timer T;
6822
6823 /* Initialize NS/BSSGP side */
6824 f_init_bssgp();
6825
6826 info_ind := valueof(ts_PCUIF_INFO_default);
6827 /* The 2 first TRX are enabled. */
6828 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6829 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6830 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6831
6832 /* Initialize the PCU interface abstraction */
6833 f_init_raw(testcasename(), info_ind);
6834
6835 /* Establish BSSGP connection to the PCU */
6836 f_bssgp_establish();
6837
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006838 for (ts := 0; ts < 2; ts := ts + 1) {
6839 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006840
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006841 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6842 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6843 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6844 T.start(0.5);
6845 alt {
6846 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6847 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6848 omit)) -> value data_msg {
6849 setverdict(pass);
6850 T.stop;
6851 }
6852 [] as_rx_fail_dummy(nr);
6853 [] BTS.receive {
6854 setverdict(fail, "Unexpected block from BTS");
6855 f_shutdown(__BFILE__, __LINE__);
6856 }
6857 [] T.timeout {
6858 setverdict(fail, "Expected IDLE block from BTS");
6859 f_shutdown(__BFILE__, __LINE__);
6860 }
6861 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006862 }
6863
6864 f_shutdown(__BFILE__, __LINE__, final := true);
6865}
6866
Oliver Smith3d174882021-09-03 11:38:51 +02006867/* Test stats for available and occupied PDCHs */
6868testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6869 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6870 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6871
6872 /* Initialize NS/BSSGP side */
6873 f_init_bssgp();
6874
Oliver Smithedcded22021-09-14 09:26:55 +02006875 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6876 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6877 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6878 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6879 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6880 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006881
Oliver Smith72d0c692021-09-08 10:03:52 +02006882 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006883 f_init_gprs_ms(4);
6884
6885 /* Initialize the PCU interface abstraction */
6886 f_init_raw(testcasename(), info_ind);
6887
6888 /* Reset stats */
6889 f_statsd_reset();
6890
6891 /* Establish BSSGP */
6892 f_bssgp_establish();
6893
6894 /* 8 PDCHs available, 0 occupied */
6895 var StatsDExpects expect := {
6896 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006897 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6898 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6899 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006900 };
6901 f_statsd_expect(expect);
6902
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006903 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006904 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006905 f_ms_establish_ul_tbf(g_ms[0]);
6906 f_ms_establish_ul_tbf(g_ms[1]);
6907 f_ms_establish_ul_tbf(g_ms[2]);
6908 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 +02006909
6910 /* 4 PDCHs occupied */
6911 expect := {
6912 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006913 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6914 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6915 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006916 };
6917 f_statsd_expect(expect);
6918
6919 f_shutdown(__BFILE__, __LINE__, final := true);
6920}
6921
Oliver Smithf04762d2021-09-14 17:20:38 +02006922/* Test stats for available and occupied PDCHs, for MS which is not known by
6923 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6924 * data arrives from SGSN) */
6925function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6926 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6927 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6928
6929 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6930 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6931 gprsmultislotclass := '00001'B,
6932 gprsextendeddynalloccap := '0'B
6933 };
6934 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6935 egprsmultislotclass := '00001'B,
6936 egprsextendeddynalloccap := '0'B
6937 };
6938 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6939 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6940 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6941 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6942
6943 /* Initialize NS/BSSGP side */
6944 f_init_bssgp();
6945
6946 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6947 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6948 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6949 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6950 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6951 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6952
6953 /* Allocate 1 GprsMS instance */
6954 f_init_gprs_ms(1);
6955
6956 /* Initialize the PCU interface abstraction */
6957 f_init_raw(testcasename(), info_ind);
6958
6959 /* Reset stats */
6960 f_statsd_reset();
6961
6962 /* Establish BSSGP */
6963 f_bssgp_establish();
6964
6965 /* 8 PDCHs available, 0 occupied */
6966 var StatsDExpects expect := {
6967 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6968 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6969 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6970 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6971 };
6972 f_statsd_expect(expect);
6973
6974 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6975 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6976
6977 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6978 var octetstring data := f_rnd_octstring(1400);
6979 if (egprs) {
6980 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6981 } else {
6982 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6983 }
6984 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6985
6986 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6987 f_sleep(X2002);
6988
6989 /* 1 PDCH occupied */
6990 if (egprs) {
6991 expect := {
6992 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6993 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6994 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6995 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6996 };
6997 } else {
6998 expect := {
6999 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
7000 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
7001 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
7002 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
7003 };
7004 }
7005 f_statsd_expect(expect);
7006
7007 /* Clean up */
7008 f_shutdown(__BFILE__, __LINE__, final := true);
7009}
7010testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
7011 f_tc_stat_pdch_avail_occ_ms_not_known(false);
7012}
7013testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
7014 f_tc_stat_pdch_avail_occ_ms_not_known(true);
7015}
7016
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007017/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
7018testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
7019 var PCUIF_info_ind info_ind;
7020 var template IARRestOctets rest;
7021 var BIT11 ra11;
7022
7023 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007024
7025 /* Only the first TRX is enabled. */
7026 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
7027 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7028
7029 /* Initialize the PCU interface abstraction */
7030 f_init_raw(testcasename(), info_ind);
7031 f_statsd_reset();
7032
7033 var EGPRSPktChRequest req := {
7034 one_phase := {
7035 tag := '0'B,
7036 multislot_class := '10101'B,
7037 priority := '01'B,
7038 random_bits := '101'B
7039 }
7040 };
7041
7042 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
7043 for (var integer i := 0; i < 7; i := i + 1) {
7044 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
7045 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
7046 }
7047
7048 ra11 := enc_EGPRSPktChRequest2bits(req);
7049 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
7050
7051 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01007052 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007053
7054 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
7055 f_sleep(2.0);
7056 var StatsDExpects expect := {
7057 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
7058 };
7059 f_statsd_expect(expect);
7060
7061 f_shutdown(__BFILE__, __LINE__, final := true);
7062}
7063
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007064control {
7065 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01007066 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007067 execute( TC_ta_ptcch_idle() );
7068 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02007069 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007070 execute( TC_ta_idle_dl_tbf_ass() );
7071 execute( TC_ta_ptcch_ul_multi_tbf() );
7072 execute( TC_cs_lqual_ul_tbf() );
7073 execute( TC_cs_initial_ul() );
7074 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01007075 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01007076 execute( TC_cs_max_dl() );
7077 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01007078 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01007079 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01007080 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01007081 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02007082 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01007083 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02007084 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01007085 execute( TC_x2031_t3191() );
7086 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007087 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01007088 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01007089 execute( TC_t3172_wait_ind_size0() );
7090 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02007091 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02007092 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02007093 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007094 execute( TC_mo_ping_pong() );
7095 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02007096 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007097 execute( TC_mt_ping_pong() );
7098 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007099 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007100 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07007101 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007102 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01007103 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02007104 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007105 execute( TC_paging_cs_from_bts() );
7106 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
7107 execute( TC_paging_cs_from_sgsn_sign() );
7108 execute( TC_paging_cs_from_sgsn_ptp() );
7109 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
7110 execute( TC_paging_ps_from_sgsn_sign() );
7111 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01007112 execute( TC_paging_pch_timeout() );
7113
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07007114 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
7115 execute( TC_paging_cs_multi_ms_imsi() );
7116 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02007117 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
7118 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01007119 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
7120 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007121
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007122 execute( TC_ul_tbf_finished_pkt_dl_ass_pch() );
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02007123 execute( TC_ul_tbf_1phase_while_dl_ass_pch() );
7124 execute( TC_ul_tbf_2phase_while_dl_ass_pch() );
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007125
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007126 /* EGPRS specific test cases */
7127 execute( TC_egprs_pkt_chan_req_signalling() );
7128 execute( TC_egprs_pkt_chan_req_one_phase() );
7129 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07007130 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07007131 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07007132 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02007133
7134 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07007135
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007136 /* Immediate Assignment on AGCH/PCH */
7137 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
7138 execute( TC_pcuif_fh_imm_ass_ul() );
7139 execute( TC_pcuif_fh_imm_ass_dl() );
7140 /* Packet Uplink/Downlink Assignment on PACCH */
7141 execute( TC_pcuif_fh_pkt_ass_ul() );
7142 execute( TC_pcuif_fh_pkt_ass_dl() );
7143 execute( TC_multitrx_multims_alloc() );
7144 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
7145 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
7146 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02007147 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02007148 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01007149 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
7150 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007151
Pau Espin Pedrole1303052020-11-16 11:13:51 +01007152 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07007153
7154 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01007155 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01007156 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01007157 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01007158 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01007159 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01007160 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01007161 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
7162 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01007163 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
7164 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
7165 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01007166 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
7167 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01007168 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
7169 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
7170 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007171 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02007172 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
7173 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
7174 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
7175 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007176
7177 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007178 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007179 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007180
7181 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02007182
7183 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02007184 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
7185 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007186 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007187}
7188
Harald Weltea419df22019-03-21 17:23:04 +01007189}