blob: 9388f8f42ebfd97352a54c08d1e56da43c60a086 [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" */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003376testcase TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() runs on RAW_PCU_Test_CT {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003377 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;
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003386 var integer cnt_rrbp := 0;
3387 var integer cnt_dummy_after_timeout := 0;
3388 /* Maximum T3168 value = 8 * 500 ms = 4s => * 4 retrans = 16s */
3389 timer T_3168 := 16.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003390
3391 /* Initialize NS/BSSGP side */
3392 f_init_bssgp();
3393 /* Initialize GPRS MS side */
3394 f_init_gprs_ms();
3395 ms := g_ms[0]; /* We only use first MS in this test */
3396
3397 /* Initialize the PCU interface abstraction */
3398 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003399 /* TODO: Speedup test by sending a PCU_IF_SAPI_BCCH SI13 with T3168=0 (500ms) */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003400 f_init_raw(testcasename(), info_ind);
3401
3402 /* Establish BSSGP connection to the PCU */
3403 f_bssgp_establish();
3404 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3405
3406 /* Establish an Uplink TBF */
3407 f_ms_establish_ul_tbf(ms);
3408
3409 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003410 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003411 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3412
3413 /* UL block should be received in SGSN */
3414 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3415
3416 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3417 tr_UlAckNackGprs(ms.tlli,
3418 tr_AckNackDescription(final_ack := '1'B),
3419 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3420 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3421
3422 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3423
3424 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003425 T_3168.start;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003426 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 {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003436 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003437 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3438 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003439 /* We should not be receiving PKT UL ASS anymore after T3168 timeout */
3440 if (not T_3168.running) {
3441 setverdict(fail, log2str("Unexpected PKT UL ASS after T3168 timeout: ", data_msg));
3442 f_shutdown(__BFILE__, __LINE__);
3443 }
3444
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003445 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003446 log("Ignoring RRBP ", cnt_rrbp);
3447 cnt_rrbp := cnt_rrbp + 1;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003448 }
3449 nr := ts_TsTrxBtsNum;
3450 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3451 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3452 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3453 block_nr := nr.blk_nr));
3454 repeat;
3455 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003456 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003457 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003458 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003459 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 }
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003466 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003467 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3468 omit)) -> value data_msg {
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003469
3470 /* T3168 expired and we are not receiving blocks anymore, meaning PCU released the TBF. */
3471 break;
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003472 }
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003473 [] BTS.receive {
3474 setverdict(fail, "Unexpected BTS message");
3475 f_shutdown(__BFILE__, __LINE__);
3476 }
3477 }
3478
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02003479 /* Check that we received at least a few PKT UL ASS before T3168 expiration */
3480 if (cnt_rrbp <= 3) {
3481 setverdict(fail, log2str("Received only ", cnt_rrbp, " before T3168 timeout!"));
3482 f_shutdown(__BFILE__, __LINE__);
3483 }
3484
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003485 f_shutdown(__BFILE__, __LINE__, final := true);
3486}
3487
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003488/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3489 * transmitted on ul slot provided by its DL TBF.
3490 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3491function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3492 var GprsMS ms;
3493 var octetstring data := f_rnd_octstring(10);
3494 var RlcmacDlBlock dl_block;
3495 var template RlcmacDlBlock rej_tmpl;
3496 var uint32_t dl_fn;
3497 var uint32_t sched_fn;
3498 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3499
3500 if (use_egprs == true) {
3501 racap_tmpl := bssgp_ms_racap_egprs_def;
3502 } else {
3503 racap_tmpl := bssgp_ms_racap_gprs_def;
3504 }
3505
3506 /* Initialize NS/BSSGP side */
3507 f_init_bssgp();
3508 /* Initialize GPRS MS side */
3509 f_init_gprs_ms();
3510 ms := g_ms[0]; /* We only use first MS in this test */
3511 /* Initialize the PCU interface abstraction */
3512 f_init_raw(testcasename());
3513
3514 /* Establish BSSGP connection to the PCU */
3515 f_bssgp_establish();
3516 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3517
3518 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3519 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3520 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3521
3522 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3523 f_sleep(X2002);
3524 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3525
3526 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3527 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3528 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3529 f_dl_block_ack_fn(dl_block, dl_fn));
3530
3531 /* We should receive a Pkt Ul ASS */
3532 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3533 f_shutdown(__BFILE__, __LINE__, final := true);
3534}
3535testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3536 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3537}
3538testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3539 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3540}
3541
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003542/* Test CS paging over the BTS<->PCU socket.
3543 * 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.
3544 * Paging should be send on the PACCH.
3545 *
3546 * 1. Send a Paging Request over PCU socket.
3547 * 2. Send a Ready-To-Send message over PCU socket
3548 * 3. Expect a Paging Frame
3549 */
3550testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003551 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003552 var MobileIdentityLV mi;
3553 var octetstring mi_enc_lv;
3554 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003555 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003556
3557 /* Initialize NS/BSSGP side */
3558 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003559 /* Initialize GPRS MS side */
3560 f_init_gprs_ms();
3561 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003562
3563 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003564 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003565
3566 /* Establish BSSGP connection to the PCU */
3567 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003568 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003569
3570 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003571 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003572
3573 /* build mobile Identity */
3574 mi := valueof(ts_MI_IMSI_LV(imsi));
3575 mi_enc_lv := enc_MobileIdentityLV(mi);
3576 /* Send paging request */
3577 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3578 sapi :=PCU_IF_SAPI_PDTCH));
3579
3580 /* Receive it on BTS side towards MS */
3581 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3582
3583 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003584 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3585 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3586 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3587 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003588
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003589 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003590}
3591
3592/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3593 */
3594private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3595runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003596 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003597 var hexstring imsi := f_gen_imsi(42);
3598 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003599 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003600
3601 /* Initialize NS/BSSGP side */
3602 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003603 /* Initialize GPRS MS side */
3604 f_init_gprs_ms();
3605 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003606
3607 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003608 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003609
3610 /* Establish BSSGP connection to the PCU */
3611 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003612 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003613
3614 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003615 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003616
3617 /* Send paging request with or without TMSI */
3618 if (use_ptmsi) {
3619 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3620 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3621 } else {
3622 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3623 }
3624
Pau Espin Pedrol00fec582022-11-29 16:03:13 +01003625 /* Now receive it on BTS side towards MS.
3626 * Skip any dummy blocks in case the PCUIF req arrives before the BSSP CS_PAGING:
3627 */
3628 f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
3629
3630 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
3631 setverdict(fail, "Failed to match Packet Paging Request: ",
3632 dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
3633 f_shutdown(__BFILE__, __LINE__);
3634 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003635
3636 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003637 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003638 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003639 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3640 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3641 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003642 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003643 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3644 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3645 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003646 }
3647
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003648 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003649}
3650
3651testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3652 f_tc_paging_cs_from_sgsn(0, true);
3653}
3654
3655testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3656 f_tc_paging_cs_from_sgsn(0);
3657}
3658
3659testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003660 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003661}
3662
3663/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3664 */
3665private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3666runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003667 var integer imsi_suff_tx := 423;
3668 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003669 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003670
3671 /* Initialize NS/BSSGP side */
3672 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003673 /* Initialize GPRS MS side */
3674 f_init_gprs_ms();
3675 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003676
Oliver Smith61b4e732021-07-22 08:14:29 +02003677 f_statsd_reset();
3678
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003679 /* Establish BSSGP connection to the PCU */
3680 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003681 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003682
3683 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3684 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3685 if (use_ptmsi) {
3686 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3687 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3688 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3689 } else {
3690 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3691 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3692 }
3693
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003694 var StatsDExpects expect := {
3695 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3696 /* After the PCU receives the paging request from SGSN,
3697 * and it doesn't have any errors, PCU sends it to the
3698 * BTS to do paging over PCH. */
3699 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3700 };
3701 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003702}
3703
3704testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3705 /* Initialize the PCU interface abstraction */
3706 f_init_raw(testcasename());
3707
3708 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003709
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003710 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003711}
3712
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003713testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003714 /* Initialize the PCU interface abstraction */
3715 f_init_raw(testcasename());
3716
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003717 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003718
3719 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003720}
3721
3722testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003723 /* Initialize the PCU interface abstraction */
3724 f_init_raw(testcasename());
3725
Harald Welte5339b2e2020-10-04 22:52:56 +02003726 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003727
3728 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003729}
3730
Oliver Smithe1a77c42021-07-28 13:36:09 +02003731testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3732 /* Initialize the PCU interface abstraction */
3733 f_init_raw(testcasename());
3734
3735 /* Set T3113 to 1s to shorten the test duration */
3736 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3737
3738 /* Reset stats and send paging PS request */
3739 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3740
3741 /* Verify that counter increases when T3113 times out (MS did not start
3742 * TBF to respond to paging). */
3743 f_sleep(1.2);
3744 var StatsDExpects expect := {
3745 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3746 };
3747 f_statsd_expect(expect);
3748
3749 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3750 f_shutdown(__BFILE__, __LINE__, final := true);
3751}
3752
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003753/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3754testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3755 var RlcmacDlBlock dl_block;
3756 var octetstring data := f_rnd_octstring(10);
3757 var uint32_t sched_fn;
3758 var uint32_t dl_fn;
3759 var GprsMS ms;
3760
3761 /* Initialize NS/BSSGP side */
3762 f_init_bssgp();
3763 /* Initialize GPRS MS side */
3764 f_init_gprs_ms();
3765 ms := g_ms[0]; /* We only use first MS in this test */
3766
3767 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003768 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003769
Daniel Willmann535aea62020-09-21 13:27:08 +02003770 f_statsd_reset();
3771
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003772 /* Establish BSSGP connection to the PCU */
3773 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003774 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003775
3776 /* Establish an Uplink TBF */
3777 f_ms_establish_ul_tbf(ms);
3778
3779 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003780 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 +02003781 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3782 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3783 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3784
3785 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003786 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003787
3788 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3789 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3790 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3791
3792 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3793 f_sleep(X2002);
3794 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3795
3796 /* ACK the DL block */
3797 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3798 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3799 f_dl_block_ack_fn(dl_block, dl_fn));
3800
Daniel Willmann535aea62020-09-21 13:27:08 +02003801 var StatsDExpects expect := {
3802 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3803 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3804 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3805 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003806 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003807 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003808 };
3809 f_statsd_expect(expect);
3810
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003811 f_shutdown(__BFILE__, __LINE__, final := true);
3812}
3813
3814/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3815testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3816 var RlcmacDlBlock dl_block;
3817 var octetstring data := f_rnd_octstring(10);
3818 var uint32_t sched_fn;
3819 var uint32_t dl_fn;
3820 var GprsMS ms;
3821
3822 /* Initialize NS/BSSGP side */
3823 f_init_bssgp();
3824 /* Initialize GPRS MS side */
3825 f_init_gprs_ms();
3826 ms := g_ms[0]; /* We only use first MS in this test */
3827
3828 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003829 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003830
3831 /* Establish BSSGP connection to the PCU */
3832 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003833 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003834
3835 /* Establish an Uplink TBF */
3836 f_ms_establish_ul_tbf(ms);
3837
3838 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003839 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 +02003840 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3841 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3842 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3843
3844 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003845 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003846
3847 /* Now SGSN sends some DL data with an invalid IMSI */
3848 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3849
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003850 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003851
3852 /* TODO: make sure no data is sent over PCU -> MS */
3853
3854 f_shutdown(__BFILE__, __LINE__, final := true);
3855}
3856
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003857private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3858 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3859 var octetstring data := f_rnd_octstring(6);
3860 var RlcmacDlBlock dl_block;
3861 var GprsMS ms;
3862 var uint32_t fn;
3863
3864 /* Initialize NS/BSSGP side */
3865 f_init_bssgp();
3866 /* Initialize GPRS MS side */
3867 f_init_gprs_ms();
3868 ms := g_ms[0]; /* We only use first MS in this test */
3869
3870 /* Initialize the PCU interface abstraction */
3871 f_init_raw(testcasename());
3872
3873 /* Establish BSSGP connection to the PCU */
3874 f_bssgp_establish();
3875 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3876
3877 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3878 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3879 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3880
3881 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3882 f_sleep(X2002);
3883
3884 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3885 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3886
3887 if (ischosen(dl_block.data_egprs)) {
3888 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3889 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3890 f_shutdown(__BFILE__, __LINE__);
3891 }
3892 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3893 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3894 f_shutdown(__BFILE__, __LINE__);
3895 }
3896 if (not match(dl_block.data_egprs.blocks[1].payload,
3897 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3898 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3899 f_shutdown(__BFILE__, __LINE__);
3900 }
3901 } else if (lengthof(dl_block.data.blocks) > 1) {
3902 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3903 f_shutdown(__BFILE__, __LINE__);
3904 }
3905
3906 f_shutdown(__BFILE__, __LINE__, final := true);
3907}
3908
3909/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3910 * containing llc data. See OS#4849 */
3911testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3912 f_tc_dl_data_no_llc_ui_dummy(omit);
3913}
3914
3915/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3916 * containing llc data. See OS#4849 */
3917testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003918 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003919}
3920
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02003921/* Scenario: MS creates one phase access, does contention resolution CV>0 and
3922 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
3923 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
3924 * has to assign a DL TBF (through PCH because of FINISHED state, TS 44.060 9.3.3.3.2).
3925 * Make sure the assignment is not done until we receive the PKT CTRL ACK from the MS
3926 * (at that time we know the MS is listening on PCH again). OS#5700.
3927 */
3928testcase TC_ul_tbf_finished_pkt_dl_ass_pch() runs on RAW_PCU_Test_CT {
3929 var RlcmacDlBlock dl_block;
3930 var octetstring data := f_rnd_octstring(10);
3931 var uint32_t sched_fn;
3932 var uint32_t dl_fn;
3933 var GprsMS ms;
3934 timer T;
3935 var octetstring payload;
3936
3937 /* Initialize NS/BSSGP side */
3938 f_init_bssgp();
3939 /* Initialize GPRS MS side */
3940 f_init_gprs_ms();
3941 ms := g_ms[0]; /* We only use first MS in this test */
3942
3943 /* Initialize the PCU interface abstraction */
3944 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3945
3946 /* Establish BSSGP connection to the PCU */
3947 f_bssgp_establish();
3948 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3949
3950 /* Establish an Uplink TBF */
3951 f_ms_establish_ul_tbf(ms);
3952
3953 /* Send one UL block (with TLLI since we are in One-Phase Access
3954 contention resolution) and make sure it is ACKED fine. */
3955 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
3956 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
3957 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
3958
3959 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3960 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
3961 f_ms_tx_ul_data_block(ms, payload, cv := 0);
3962 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3963
3964 /* 1 UL block should be received in SGSN */
3965 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3966 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3967 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3968
3969 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3970 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3971 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3972 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3973 f_sleep(X2002);
3974 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3975
3976 f_shutdown(__BFILE__, __LINE__, final := true);
3977}
3978
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02003979/* Scenario: MS creates a UL TBF and
3980 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
3981 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
3982 * has to assign a DL TBF on PCH. While the network is waiting for the MS to
3983 * move to PDCH before transmitting DL data (timer X2002), the MS finds out it
3984 * needs to send new UL data and hence sends a RACH request to create a new UL
3985 * TBF.
3986 * Make sure the the MS is assigned a DL TBF through PACCH in that case even if
3987 * no new DL data is received from the SGSN. OS#5700.
3988 * This test validates the specific case where the 2nd UL TBF is done through
3989 * 1phase-access.
3990 */
3991testcase TC_ul_tbf_1phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
3992 var RlcmacDlBlock dl_block;
3993 var octetstring data := f_rnd_octstring(10);
3994 var uint32_t sched_fn;
3995 var uint32_t poll_fn;
3996 var uint32_t dl_fn;
3997 var GprsMS ms;
3998 timer T;
3999 var octetstring payload;
4000
4001 /* Initialize NS/BSSGP side */
4002 f_init_bssgp();
4003 /* Initialize GPRS MS side */
4004 f_init_gprs_ms();
4005 ms := g_ms[0]; /* We only use first MS in this test */
4006
4007 /* Initialize the PCU interface abstraction */
4008 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4009
4010 /* Establish BSSGP connection to the PCU */
4011 f_bssgp_establish();
4012 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4013
4014 /* Establish an Uplink TBF */
4015 f_ms_establish_ul_tbf(ms);
4016
4017 /* Send one UL block (with TLLI since we are in One-Phase Access
4018 contention resolution) and make sure it is ACKED fine. */
4019 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4020 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4021 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4022
4023 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4024 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4025 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4026 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4027
4028 /* 1 UL block should be received in SGSN */
4029 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4030 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4031 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4032
4033 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4034 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4035 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4036
4037 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4038 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4039 f_ms_establish_ul_tbf(ms);
4040
4041 /* Send one UL block (with TLLI since we are in One-Phase Access
4042 * contention resolution) and make sure it is ACKED fine. */
4043 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4044 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4045 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4046
4047 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4048 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4049
4050 /* The PCU considers the MS to have gone over Contention Resolution
4051 * after having sent the first UL ACK/NACK to it, hence next it will try to
4052 * assign the DL-TBF to send the data it received from the SGSN previously: */
4053 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4054 /* the MS ACKs the PKT_DL_ASS: */
4055 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4056
4057 /* We should finally receive the DL-data that was received previously from the SGSN: */
4058 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4059
4060 f_shutdown(__BFILE__, __LINE__, final := true);
4061}
4062
4063/* Same as TC_ul_tbf_2phase_while_dl_ass_pch, but this test validates the
4064 * specific case where the 2nd UL TBF is done through 2phase-access. */
4065testcase TC_ul_tbf_2phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4066 var RlcmacDlBlock dl_block;
4067 var octetstring data := f_rnd_octstring(10);
4068 var uint32_t sched_fn;
4069 var uint32_t poll_fn;
4070 var uint32_t dl_fn;
4071 var GprsMS ms;
4072 timer T;
4073 var octetstring payload;
4074 var PollFnCtx pollctx;
4075
4076 /* Initialize NS/BSSGP side */
4077 f_init_bssgp();
4078 /* Initialize GPRS MS side */
4079 f_init_gprs_ms();
4080 ms := g_ms[0]; /* We only use first MS in this test */
4081
4082 /* Initialize the PCU interface abstraction */
4083 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4084
4085 /* Establish BSSGP connection to the PCU */
4086 f_bssgp_establish();
4087 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4088
4089 /* Establish an Uplink TBF */
4090 f_ms_establish_ul_tbf(ms);
4091
4092 /* Send one UL block (with TLLI since we are in One-Phase Access
4093 contention resolution) and make sure it is ACKED fine. */
4094 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4095 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4096 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4097
4098 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4099 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4100 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4101 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4102
4103 /* 1 UL block should be received in SGSN */
4104 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4105 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4106 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4107
4108 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4109 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4110 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4111
4112 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4113 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4114 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4115
4116 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4117 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4118
4119 /* Now that MS seized the UL-TBF, PCU sends DL-TBF Assignment on PACCH */
4120 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4121 /* the MS ACKs the PKT_DL_ASS: */
4122 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4123
4124 /* We should finally receive the DL-data that was received previously from the SGSN: */
4125 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4126
4127 f_shutdown(__BFILE__, __LINE__, final := true);
4128}
4129
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004130private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004131 template GsmRrMessage t_imm_ass := ?,
4132 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004133runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004134 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004135 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004136
4137 ra11 := enc_EGPRSPktChRequest2uint(req);
4138 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
4139
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07004140 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004141 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004142 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004143 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004144 }
4145
4146 setverdict(pass);
4147}
4148
4149testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
4150 var template GsmRrMessage imm_ass;
4151 var template IaRestOctets rest;
4152 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004153 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004154
4155 /* Initialize the PCU interface abstraction */
4156 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004157 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004158
4159 var EGPRSPktChRequest req := {
4160 /* NOTE: other fields are set in the loop */
4161 signalling := { tag := '110011'B }
4162 };
4163
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004164 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004165 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4166 req.signalling.random_bits := ext_ra;
4167
4168 /* For signalling, do we expect Multiblock UL TBF Assignment? */
4169 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4170 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4171 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4172
4173 f_TC_egprs_pkt_chan_req(req, imm_ass);
4174 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004175
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004176 var StatsDExpects expect := {
4177 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4178 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4179 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4180 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4181 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4182 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4183 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4184 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4185 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4186 };
4187 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004188
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004189 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004190}
4191
4192testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
4193 var template GsmRrMessage imm_ass;
4194 var template IaRestOctets rest;
4195 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004196 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004197
4198 /* Initialize the PCU interface abstraction */
4199 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004200 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004201
4202 var EGPRSPktChRequest req := {
4203 /* NOTE: other fields are set in the loop */
4204 one_phase := { tag := '0'B }
4205 };
4206
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004207 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004208 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4209 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
4210 var BIT2 priority := substr(ext_ra, 0, 2);
4211 var BIT3 rand := substr(ext_ra, 2, 3);
4212
4213 req.one_phase.multislot_class := mslot_class;
4214 req.one_phase.priority := priority;
4215 req.one_phase.random_bits := rand;
4216
4217 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
4218 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
4219 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4220 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4221
4222 f_TC_egprs_pkt_chan_req(req, imm_ass);
4223 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004224
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004225 var StatsDExpects expect := {
4226 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4227 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4228 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4229 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4230 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4231 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4232 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4233 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4234 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4235 };
4236 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004237
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004238 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004239}
4240
4241testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4242 var template GsmRrMessage imm_ass;
4243 var template IaRestOctets rest;
4244 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004245 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004246
4247 /* Initialize the PCU interface abstraction */
4248 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004249 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004250
4251 var EGPRSPktChRequest req := {
4252 /* NOTE: other fields are set in the loop */
4253 two_phase := { tag := '110000'B }
4254 };
4255
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004256 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004257 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4258 var BIT2 priority := substr(ext_ra, 0, 2);
4259 var BIT3 rand := substr(ext_ra, 2, 3);
4260
4261 req.two_phase.priority := priority;
4262 req.two_phase.random_bits := rand;
4263
4264 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4265 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4266 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4267 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4268
4269 f_TC_egprs_pkt_chan_req(req, imm_ass);
4270 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004271
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004272 var StatsDExpects expect := {
4273 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4274 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4275 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4276 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4277 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4278 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4279 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4280 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4281 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4282 };
4283 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004284
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004285 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004286}
4287
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004288private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4289 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004290 PCUIF_BurstType bt := BURST_TYPE_1,
4291 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004292runs on RAW_PCU_Test_CT {
4293 var template ReqRefWaitInd tr_ref;
4294 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004295
4296 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4297 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4298 ra := bit2int(ra11), is_11bit := 1,
4299 burst_type := bt, fn := fn,
4300 arfcn := 871));
4301
4302 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004303 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004304
4305 /* Just to have a short-name reference to the actual message */
4306 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4307
4308 /* Make sure that Request Reference list contains at least one entry
4309 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004310 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004311 if (not match(iar.payload, { *, tr_ref, * })) {
4312 setverdict(fail, "Request Reference list does not match");
4313 f_shutdown(__BFILE__, __LINE__);
4314 }
4315
4316 /* Match Feature Indicator (must indicate PS domain) */
4317 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4318 setverdict(fail, "Feature Indicator does not match");
4319 f_shutdown(__BFILE__, __LINE__);
4320 }
4321
4322 /* Match IAR Rest Octets */
4323 if (not match(iar.rest_octets, rest)) {
4324 setverdict(fail, "IAR Rest Octets does not match: ",
4325 iar.rest_octets, " vs expected ", rest);
4326 f_shutdown(__BFILE__, __LINE__);
4327 }
4328
4329 setverdict(pass);
4330}
4331
4332/* Verify the contents of RR Immediate Assignment Reject message and its
4333 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4334testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4335 var template IARRestOctets rest;
4336 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004337 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004338
4339 /* Initialize the PCU interface abstraction */
4340 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004341 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004342
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004343 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004344 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4345 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4346
4347 /* Intentionally incorrect message (see table 11.2.5a.2) */
4348 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4349 }
4350
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004351 var StatsDExpects expect := {
4352 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4353 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4354 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4355 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4356 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4357 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4358 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4359 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4360 };
4361 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004362
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004363 f_shutdown(__BFILE__, __LINE__, final := true);
4364}
4365
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004366/* At the moment, the IUT does not support any emergency services. Make sure
4367 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4368testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4369 var template IARRestOctets rest;
4370 var BIT5 ext_ra;
4371 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004372 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004373
4374 /* Initialize the PCU interface abstraction */
4375 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004376 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004377
4378 var EGPRSPktChRequest req := {
4379 /* NOTE: other fields are set in the loop */
4380 emergency := { tag := '110111'B }
4381 };
4382
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004383 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004384 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4385 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4386
4387 req.emergency.random_bits := ext_ra;
4388 ra11 := enc_EGPRSPktChRequest2bits(req);
4389
4390 /* Intentionally incorrect message (see table 11.2.5a.2) */
4391 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4392 }
4393
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004394 var StatsDExpects expect := {
4395 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4396 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4397 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4398 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4399 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4400 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4401 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4402 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4403 };
4404 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004405
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004406 f_shutdown(__BFILE__, __LINE__, final := true);
4407}
4408
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004409/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4410testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004411 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004412 var template IARRestOctets rest;
4413 var BIT11 ra11;
4414
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004415 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004416 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004417
4418 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004419 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4420 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004421
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004422 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004423 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004424 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004425
4426 var EGPRSPktChRequest req := {
4427 one_phase := {
4428 tag := '0'B,
4429 multislot_class := '10101'B,
4430 priority := '01'B,
4431 random_bits := '101'B
4432 }
4433 };
4434
4435 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4436 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4437 for (var integer i := 0; i < 7; i := i + 1) {
4438 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4439 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4440 }
4441
4442 ra11 := enc_EGPRSPktChRequest2bits(req);
4443 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4444
4445 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004446 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004447
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004448 var StatsDExpects expect := {
4449 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4450 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4451 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4452 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4453 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4454 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4455 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4456 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4457 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4458 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4459 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4460 };
4461 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004462
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004463 f_shutdown(__BFILE__, __LINE__, final := true);
4464}
4465
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004466/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004467private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004468return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004469 /* Pick a random MA length in range 2 .. max_ma_len */
4470 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4471
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004472 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4473 hsn := f_rnd_int(63),
4474 maio := f_rnd_int(63),
4475 ma := f_rnd_bitstring(ma_len));
4476}
4477
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004478private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4479 in GsmRrMessage rr_msg)
4480{
4481 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004482 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004483
4484 var template PacketChannelDescription tr_pkt_chan_desc := {
4485 channel_Type_spare := ?,
4486 tn := ?,
4487 tsc := ts.tsc,
4488 presence := '1'B,
4489 zero := omit,
4490 one := {
4491 maio := ts.maio,
4492 hsn := ts.hsn
4493 }
4494 };
4495
4496 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4497 setverdict(fail, "Packet Channel Description does not match: ",
4498 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4499 }
4500
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004501 /* Mobile Allocation is expected to be octet-aligned */
4502 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4503 var template MobileAllocationLV tr_ma := {
4504 len := ma_oct_len, /* in bytes */
4505 ma := substr(ts.ma, 0, ma_oct_len * 8)
4506 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004507
4508 if (not match(ia.mobile_allocation, tr_ma)) {
4509 setverdict(fail, "Mobile Allocation does not match: ",
4510 ia.mobile_allocation, " vs ", tr_ma);
4511 }
4512
4513 setverdict(pass);
4514}
4515
4516/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4517testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004518 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004519 var GprsMS ms := valueof(t_GprsMS_def);
4520
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004521 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004522 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004523
4524 /* Initialize the PCU interface abstraction */
4525 f_init_raw(testcasename(), info_ind);
4526
4527 /* EGPRS Packet Channel Request (cause=Signalling) */
4528 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4529
4530 /* Establish an Uplink EGPRS TBF */
4531 f_ms_establish_ul_tbf(ms);
4532
4533 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4534 f_shutdown(__BFILE__, __LINE__, final := true);
4535}
4536
4537/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4538testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004539 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004540 var GprsMS ms := valueof(t_GprsMS_def);
4541
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004542 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004543 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004544
4545 /* Initialize the PCU interface abstraction */
4546 f_init_raw(testcasename(), info_ind);
4547
4548 /* Establish an Uplink TBF */
4549 f_ms_establish_ul_tbf(ms);
4550
4551 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4552 f_shutdown(__BFILE__, __LINE__, final := true);
4553}
4554
4555/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4556testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004557 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004558 var GprsMS ms := valueof(t_GprsMS_def);
4559
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004560 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004561 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004562
4563 /* Initialize NS/BSSGP side */
4564 f_init_bssgp();
4565
4566 /* Initialize the PCU interface abstraction */
4567 f_init_raw(testcasename(), info_ind);
4568
4569 /* Establish BSSGP connection to the PCU */
4570 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004571 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004572
4573 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4574 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4575 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4576
4577 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4578 f_shutdown(__BFILE__, __LINE__, final := true);
4579}
4580
4581private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4582 in FrequencyParameters fp)
4583{
4584 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004585 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004586
4587 /* Table 12.8.1: Frequency Parameters information elements */
4588 var template FrequencyParameters tr_fp := {
4589 tsc := ts.tsc,
4590 presence := '10'B, /* Direct encoding 1 */
4591 arfcn := omit,
4592 indirect := omit,
4593 direct1 := {
4594 maio := ts.maio,
4595 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4596 mobile_allocation := {
4597 hsn := ts.hsn,
4598 rfl_number_list_present := '0'B,
4599 rfl_number_list := omit,
4600 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004601 ma_length := ts.ma_bit_len,
4602 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004603 }
4604 },
4605 direct2 := omit
4606 };
4607
4608 if (not match(fp, tr_fp)) {
4609 setverdict(fail, "Frequency Parameters IE does not match: ",
4610 fp, " vs ", tr_fp);
4611 }
4612
4613 setverdict(pass);
4614}
4615
4616/* Make sure that Packet Uplink Assignment contains hopping parameters */
4617testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004618 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004619 var GprsMS ms := valueof(t_GprsMS_def);
4620 var uint32_t poll_fn;
4621
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004622 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004623 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004624
4625 /* Initialize the PCU interface abstraction */
4626 f_init_raw(testcasename(), info_ind);
4627
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004628 /* Single block (two phase) packet access */
4629 var uint16_t ra := bit2int(chan_req_sb);
4630 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4631
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004632 /* Establish an Uplink TBF */
4633 f_ms_establish_ul_tbf(ms);
4634
4635 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004636 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4637 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004638
4639 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004640 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4641 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004642
4643 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4644 var template (omit) FrequencyParameters fp;
4645 if (ua.is_egprs == '1'B) {
4646 fp := ua.egprs.freq_par;
4647 } else {
4648 fp := ua.gprs.freq_par;
4649 }
4650
4651 /* This is an optional IE, so it's worth to check its presence */
4652 if (istemplatekind(fp, "omit")) {
4653 setverdict(fail, "Frequency Parameters IE is not present");
4654 f_shutdown(__BFILE__, __LINE__);
4655 }
4656
4657 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4658 f_shutdown(__BFILE__, __LINE__, final := true);
4659}
4660
4661/* Make sure that Packet Downlink Assignment contains hopping parameters */
4662testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004663 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004664 var octetstring data := f_rnd_octstring(10);
4665 var GprsMS ms := valueof(t_GprsMS_def);
4666 var RlcmacDlBlock dl_block;
4667 var uint32_t poll_fn;
4668
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004669 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004670 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004671
4672 /* Initialize NS/BSSGP side */
4673 f_init_bssgp();
4674
4675 /* Initialize the PCU interface abstraction */
4676 f_init_raw(testcasename(), info_ind);
4677
4678 /* Establish BSSGP connection to the PCU */
4679 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004680 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004681
4682 /* Establish an Uplink TBF */
4683 f_ms_establish_ul_tbf(ms);
4684
4685 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004686 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 +07004687
4688 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4689 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4690 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4691
4692 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4693 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4694
4695 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004696 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4697 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004698
4699 /* This is an optional IE, so it's worth to check its presence */
4700 if (not ispresent(da.freq_par)) {
4701 setverdict(fail, "Frequency Parameters IE is not present");
4702 f_shutdown(__BFILE__, __LINE__);
4703 }
4704
4705 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4706 f_shutdown(__BFILE__, __LINE__, final := true);
4707}
4708
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004709/* Check if the IUT handles subsequent INFO.ind messages */
4710testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004711 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004712 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004713
4714 /* Initialize the PCU interface abstraction */
4715 f_init_raw(testcasename(), info_ind);
4716
4717 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4718 for (var integer i := 0; i < 16; i := i + 1) {
4719 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004720 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004721 }
4722
4723 f_shutdown(__BFILE__, __LINE__, final := true);
4724}
4725
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004726/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4727testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4728 var PCUIF_info_ind info_ind;
4729 var integer i;
4730 const integer num_ms := 8;
4731
4732 /* Initialize NS/BSSGP side */
4733 f_init_bssgp();
4734 /* Initialize GPRS MS side */
4735 f_init_gprs_ms(num_ms);
4736
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004737 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004738 /* Only the 3 first TRX are enabled. The enabled ones all have same
4739 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004740 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4741 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4742 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4743 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004744
4745 /* Initialize the PCU interface abstraction */
4746 f_init_raw(testcasename(), info_ind);
4747
4748 /* Establish BSSGP connection to the PCU */
4749 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004750 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004751
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004752 /* Establish an Uplink TBF for each GprsMS instance */
4753 f_multi_ms_establish_tbf(do_activate := false);
4754
4755 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004756 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004757 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004758 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004759 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004760 f_shutdown(__BFILE__, __LINE__);
4761 }
4762 }
4763
4764 f_shutdown(__BFILE__, __LINE__, final := true);
4765}
4766
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004767/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4768 * downgraded to CS1-4 so that GPRS can read the USF).
4769 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4770 */
4771testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4772 var PCUIF_info_ind info_ind;
4773 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4774 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004775 var uint32_t sched_fn, dl_fn, ack_fn;
4776 var octetstring data := f_rnd_octstring(10);
4777 var RlcmacDlBlock dl_block;
4778 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004779 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004780 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4781 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4782
4783 /* Initialize NS/BSSGP side */
4784 f_init_bssgp();
4785 /* Initialize GPRS MS side */
4786 f_init_gprs_ms(num_ms);
4787
4788 info_ind := valueof(ts_PCUIF_INFO_default);
4789 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004790 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4791 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004792
4793 /* Initialize the PCU interface abstraction */
4794 f_init_raw(testcasename(), info_ind);
4795
4796 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4797 g_mcs_initial_dl := 5;
4798 g_mcs_max_dl := 5;
4799 f_pcuvty_set_allowed_cs_mcs();
4800
4801 /* Establish BSSGP connection to the PCU */
4802 f_bssgp_establish();
4803 f_multi_ms_bssgp_register();
4804
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004805 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004806 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 +01004807 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4808 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4809 f_shutdown(__BFILE__, __LINE__);
4810 }
4811 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4812 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4813
4814 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004815 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 +01004816 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4817 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4818 f_shutdown(__BFILE__, __LINE__);
4819 }
4820 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4821 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4822
4823 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4824 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4825 f_sleep(0.1);
4826 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4827 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4828 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4829 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4830 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4831 /* ACK the DL block */
4832 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4833 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4834 f_dl_block_ack_fn(dl_block, dl_fn));
4835
4836 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4837 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4838 f_sleep(0.1);
4839 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4840 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4841 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4842 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4843 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4844 /* ACK the DL block */
4845 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4846 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4847 f_dl_block_ack_fn(dl_block, dl_fn));
4848
4849 data := f_rnd_octstring(1400);
4850 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4851 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4852
4853 for (var integer i := 0; i < 800; i := i + 1) {
4854 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4855
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07004856 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004857 /* No more data to receive, done */
4858 break;
4859 }
4860
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004861 usf_ms := -1;
4862
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004863 if (ischosen(dl_block.ctrl)) {
4864 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4865 f_shutdown(__BFILE__, __LINE__);
4866 } else if (ischosen(dl_block.data_egprs)) {
4867 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4868 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4869 f_shutdown(__BFILE__, __LINE__);
4870 }
4871 tgt_ms := 1;
4872 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4873 if (dl_block.data_egprs.mcs > MCS_4) {
4874 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4875 f_shutdown(__BFILE__, __LINE__);
4876 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004877 usf_ms := 0;
4878 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004879 } else {
4880 if (dl_block.data_egprs.mcs <= MCS_4) {
4881 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4882 f_shutdown(__BFILE__, __LINE__);
4883 }
4884 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004885 usf_ms := 1;
4886 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004887 }
4888 }
4889 } else {
4890 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4891 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4892 f_shutdown(__BFILE__, __LINE__);
4893 }
4894 tgt_ms := 0;
4895 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 +01004896 usf_ms := 0;
4897 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004898 } 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 +01004899 usf_ms := 1;
4900 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004901 }
4902 }
4903
4904 /* Keep Ack/Nack description updated */
4905 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4906
4907 /* TDMA frame number on which we are supposed to send the ACK */
4908 if (f_dl_block_rrbp_valid(dl_block)) {
4909 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4910 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);
4911 if (tx_data_remain != 0) {
4912 /* Submit more data from time to time to keep the TBF ongoing */
4913 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4914 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4915 tx_data_remain := tx_data_remain - 1;
4916 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004917 } else if (tx_data_remain != 0) {
4918 /* keep sending UL blocks when requested by USF to avoid
4919 * UL TBF timeout and hence stop receival of USFs */
4920 if (usf_ms != -1) {
4921 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4922 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004923 }
4924 }
4925
4926 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 +01004927 /* He we check that DL blocks scheduled at GPRS can still request UL
4928 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4929 * condition also ensures the downgrade to <=MCS4 condition is tested
4930 * above */
4931 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4932 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004933 f_shutdown(__BFILE__, __LINE__);
4934 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004935 /* Here check for some level of fairness between them (at least ~40%): */
4936 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4937 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4938 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4939 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4940 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4941 f_shutdown(__BFILE__, __LINE__);
4942 }
4943 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4944 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4945 f_shutdown(__BFILE__, __LINE__);
4946 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004947
4948 f_shutdown(__BFILE__, __LINE__, final := true);
4949}
4950
4951
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004952private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4953 boolean exp_imsi, boolean exp_tmsi)
4954runs on RAW_PCU_Test_CT {
4955 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4956 var integer pending := lengthof(g_ms);
4957 var RlcmacDlBlock dl_block;
4958 var boolean f1, f2;
4959
4960 while (pending > 0) {
4961 var uint32_t poll_fn;
4962
4963 /* Obtain a Downlink block and make sure it is a paging request */
4964 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4965 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4966 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4967 break;
4968 }
4969
4970 /* This should not happen in general, but who knows... */
4971 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4972 if (not ispresent(req.repeated_pageinfo)) {
4973 setverdict(fail, "Repeated Page Info IE is absent?!?");
4974 break;
4975 }
4976
4977 /* A single message may contain several MIs depending on their type */
4978 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4979 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4980 ps_domain := false);
4981 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4982 ps_domain := false);
4983 if (not f1 and not f2)
4984 { continue; }
4985
4986 /* Detect duplicate MIs */
4987 if (mask[i] == '1'B) {
4988 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4989 continue;
4990 }
4991
4992 mask[i] := '1'B;
4993 }
4994
4995 pending := pending - lengthof(req.repeated_pageinfo);
4996 }
4997
4998 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4999 if (mask[i] != '1'B) {
5000 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
5001 log("===== mask := ", mask);
5002 }
5003 }
5004
5005 /* All messages must have been received by now, expect a dummy block */
5006 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
5007}
5008
5009private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
5010runs on RAW_PCU_Test_CT {
5011 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5012 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5013
5014 /* Initialize NS/BSSGP side */
5015 f_init_bssgp();
5016
5017 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005018 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005019
5020 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
5021 f_init_gprs_ms(7 * 8);
5022
5023 /* Initialize the PCU interface abstraction */
5024 f_init_raw(testcasename(), info_ind);
5025
5026 /* Establish BSSGP connection to the PCU */
5027 f_bssgp_establish();
5028 f_multi_ms_bssgp_register();
5029
5030 /* Establish an Uplink TBF for each GprsMS instance */
5031 f_multi_ms_establish_tbf(do_activate := true);
5032}
5033
5034testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
5035 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5036
5037 /* Common part: send INFO.ind, establish TBFs... */
5038 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5039
5040 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
5041 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5042 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5043 }
5044
5045 /* FIXME: work around a race condition between PCUIF and BSSGP */
5046 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5047
5048 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5049 * The IUT is expected to page on all PDCH slots of all transceivers. */
5050 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5051 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5052 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
5053 }
5054
5055 f_shutdown(__BFILE__, __LINE__, final := true);
5056}
5057
5058testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
5059 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5060
5061 /* Common part: send INFO.ind, establish TBFs... */
5062 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5063
5064 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
5065 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5066 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5067 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5068 }
5069
5070 /* FIXME: work around a race condition between PCUIF and BSSGP */
5071 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5072
5073 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5074 * The IUT is expected to page on all PDCH slots of all transceivers. */
5075 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5076 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5077 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
5078 }
5079
5080 f_shutdown(__BFILE__, __LINE__, final := true);
5081}
5082
5083testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
5084 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5085
5086 /* Common part: send INFO.ind, establish TBFs... */
5087 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5088
5089 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
5090 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5091 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5092 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
5093 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5094 } else {
5095 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5096 }
5097 }
5098
5099 /* FIXME: work around a race condition between PCUIF and BSSGP */
5100 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5101
5102 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5103 * The IUT is expected to page on all PDCH slots of all transceivers. */
5104 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5105 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5106 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
5107 }
5108
5109 f_shutdown(__BFILE__, __LINE__, final := true);
5110}
5111
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005112private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005113runs on RAW_PCU_Test_CT return RlcmacDlBlock {
5114 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005115 var integer i := 0;
5116 while (true) {
5117 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005118 if (not match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005119 break;
5120 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005121 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005122 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5123 f_shutdown(__BFILE__, __LINE__);
5124 }
5125 i := i + 1;
5126 }
5127 return dl_block;
5128}
5129
Vadim Yanitskiy03f74d42023-02-10 09:22:42 +07005130private const GsmMcc c_BssgpCellMcc := '623'H; /* MCC: Central African Republic */
5131private const GsmMnc c_BssgpCellMnc := '03'H; /* MNC: Celca (Socatel) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005132private template (value) BssgpCellId ts_BssgpCellIdDstAddr_default := {
5133 ra_id := {
5134 lai := {
5135 mcc_mnc := f_build_BcdMccMnc(c_BssgpCellMcc, c_BssgpCellMnc),
5136 lac := 423
5137 },
5138 rac := 2
5139 },
5140 cell_id := 5
5141}
5142
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005143private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
5144runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005145 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5146 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5147 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 +01005148 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005149 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005150 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005151 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5152 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5153 var template (value) RAN_Information_RIM_Container res_cont :=
5154 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5155 ts_RIM_Sequence_Number(2),
5156 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5157 ts_RIM_Protocol_Version_Number(1),
5158 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
5159 omit);
5160 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5161 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5162 res_cont));
5163}
5164
5165altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
5166runs on RAW_PCU_Test_CT {
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005167 /* Source Cell Identifier IE is generated by osmo-pcu based on the INFO.ind */
5168 var BcdMccMnc src_mcc_mnc := f_build_BcdMccMnc_int(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1);
5169 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 +01005170 info_ind.cell_id));
Vadim Yanitskiy88b87a42023-02-10 08:32:48 +07005171 /* Destination Cell Identifier IE is resolved by the testsuite itself (emulating BSC) */
Vadim Yanitskiy72956612023-02-10 08:53:51 +07005172 var BssgpCellId dst := valueof(ts_BssgpCellIdDstAddr_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005173 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5174 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5175 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5176 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5177 tr_RAN_Information_Request_RIM_Container)) {
5178 if (do_answer) {
5179 f_outbound_nacc_rim_tx_resp(info_ind);
5180 }
5181 if (do_repeat) {
5182 repeat;
5183 }
5184 }
5185}
5186
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005187private function f_ctrl_rx_nacc_rac_ci_req(out CtrlMessage ctrl_req,
5188 PCUIF_info_ind info_ind,
5189 GsmArfcn req_arfcn,
5190 uint6_t req_bsic)
5191runs on RAW_PCU_Test_CT {
5192 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5193 int2str(info_ind.lac) & "." &
5194 int2str(info_ind.cell_id) & "." &
5195 int2str(req_arfcn) & "." &
5196 int2str(req_bsic);
5197 f_ipa_ctrl_wait_link_up();
5198 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value ctrl_req;
5199}
5200
5201private function f_ctrl_tx_nacc_rac_ci_rsp(in CtrlMessage ctrl_req)
5202runs on RAW_PCU_Test_CT {
5203 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5204 IPA_CTRL.send(ts_CtrlMsgGetRepl(ctrl_req.cmd.id,
5205 ctrl_req.cmd.variable,
5206 hex2str(c_BssgpCellMcc) & "-" &
5207 hex2str(c_BssgpCellMnc) & "-" &
5208 int2str(addr.ra_id.lai.lac) & "-" &
5209 int2str(addr.ra_id.rac) & "-" &
5210 int2str(addr.cell_id)));
5211}
5212
5213private function f_pcuif_rx_nacc_rac_ci_req(out PCUIF_Message addr_req,
5214 PCUIF_info_ind info_ind,
5215 GsmArfcn req_arfcn,
5216 uint6_t req_bsic)
5217runs on RAW_PCU_Test_CT {
5218 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id,
5219 req_arfcn, req_bsic)) -> value addr_req;
5220}
5221
5222private function f_pcuif_tx_nacc_rac_ci_rsp(in PCUIF_Message addr_req)
5223runs on RAW_PCU_Test_CT {
5224 var BssgpCellId addr := valueof(ts_BssgpCellIdDstAddr_default);
5225 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, addr_req.u.container.u.neigh_addr_req, 0,
5226 str2int(hex2str(c_BssgpCellMcc)),
5227 str2int(hex2str(c_BssgpCellMnc)),
5228 lengthof(c_BssgpCellMnc) - 2,
5229 addr.ra_id.lai.lac,
5230 addr.ra_id.rac,
5231 addr.cell_id));
5232}
5233
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005234private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
5235 boolean answer := true, boolean use_old_ctrl_iface := false)
5236runs on RAW_PCU_Test_CT {
5237 if (use_old_ctrl_iface == true) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005238 var CtrlMessage ctrl_req;
5239 f_ctrl_rx_nacc_rac_ci_req(ctrl_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005240 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005241 f_ctrl_tx_nacc_rac_ci_rsp(ctrl_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005242 }
5243 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005244 var PCUIF_Message pcuif_req;
5245 f_pcuif_rx_nacc_rac_ci_req(pcuif_req, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005246 if (answer) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005247 f_pcuif_tx_nacc_rac_ci_rsp(pcuif_req);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005248 }
5249 }
5250}
5251
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005252/* Start NACC from MS side */
5253private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005254 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005255 boolean skip_final_ctrl_ack := false,
5256 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005257runs on RAW_PCU_Test_CT {
5258 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5259 var RlcmacDlBlock dl_block;
5260 var uint32_t sched_fn;
5261 var GsmArfcn req_arfcn := 862;
5262 var uint6_t req_bsic := 43;
5263
5264 /* Start NACC from MS side */
5265 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5266 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5267
5268 if (exp_rac_ci_query == true) {
5269 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005270 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 +01005271 }
5272
5273 if (exp_si_query == true) {
5274 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005275 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005276 }
5277
5278 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005279 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005280
5281 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5282 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5283 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5284 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5285 f_shutdown(__BFILE__, __LINE__);
5286 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005287 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005288 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005289 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5290 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5291 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005292}
5293
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005294/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
5295testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005296 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005297 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005298 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005299 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005300
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005301 if (use_old_ctrl_iface) {
5302 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5303 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5304 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005305
5306 /* Initialize NS/BSSGP side */
5307 f_init_bssgp();
5308 /* Initialize GPRS MS side */
5309 f_init_gprs_ms();
5310 ms := g_ms[0]; /* We only use first MS in this test */
5311
5312 /* Initialize the PCU interface abstraction */
5313 f_init_raw(testcasename(), info_ind);
5314
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005315 /* Make sure we are not affected by full cache from previous tests */
5316 f_pcuvty_flush_neigh_caches();
5317
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005318 /* Establish BSSGP connection to the PCU */
5319 f_bssgp_establish();
5320 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5321
5322 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005323 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 +01005324 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5325 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5326
5327 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005328 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005329
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005330 f_shutdown(__BFILE__, __LINE__, final := true);
5331}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005332
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005333/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5334testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5335 var PollFnCtx pollctx;
5336 var GprsMS ms;
5337 var RlcmacDlBlock dl_block;
5338 var uint32_t sched_fn;
5339 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005340 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005341
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005342 if (use_old_ctrl_iface) {
5343 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5344 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5345 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005346
5347 /* Initialize NS/BSSGP side */
5348 f_init_bssgp();
5349 /* Initialize GPRS MS side */
5350 f_init_gprs_ms();
5351 ms := g_ms[0]; /* We only use first MS in this test */
5352
5353 /* Initialize the PCU interface abstraction */
5354 f_init_raw(testcasename(), info_ind);
5355
5356 /* Make sure we are not affected by full cache from previous tests */
5357 f_pcuvty_flush_neigh_caches();
5358
5359 /* Establish BSSGP connection to the PCU */
5360 f_bssgp_establish();
5361 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5362
5363 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005364 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 +01005365 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5366 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5367
5368 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005369 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 +01005370
5371 /* Wait until we receive something non-dummy */
5372 dl_block := f_skip_dummy(0, sched_fn);
5373 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5374 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5375 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5376 }
5377 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5378 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5379 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5380 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5381 }
5382
5383 f_shutdown(__BFILE__, __LINE__, final := true);
5384}
5385
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005386/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5387testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5388 var PollFnCtx pollctx;
5389 var GprsMS ms;
5390 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005391 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005392 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005393
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005394 if (use_old_ctrl_iface) {
5395 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5396 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5397 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005398
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005399 /* Initialize NS/BSSGP side */
5400 f_init_bssgp();
5401 /* Initialize GPRS MS side */
5402 f_init_gprs_ms();
5403 ms := g_ms[0]; /* We only use first MS in this test */
5404
5405 /* Initialize the PCU interface abstraction */
5406 f_init_raw(testcasename(), info_ind);
5407
5408 /* Make sure we are not affected by full cache from previous tests */
5409 f_pcuvty_flush_neigh_caches();
5410 /* Set timeout values for caches so that entries will be in cache during second try */
5411 f_pcuvty_set_neigh_caches(10, 10);
5412
5413 /* Establish BSSGP connection to the PCU */
5414 f_bssgp_establish();
5415 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5416
5417 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005418 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 +01005419 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5420 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5421
5422 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005423 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005424
5425 /* 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 +02005426 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 +01005427
5428 f_shutdown(__BFILE__, __LINE__, final := true);
5429}
5430
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005431/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5432 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5433 */
5434testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5435 var PollFnCtx pollctx;
5436 var GprsMS ms;
5437 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005438 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005439 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005440
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005441 if (use_old_ctrl_iface) {
5442 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5443 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5444 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005445
5446 /* Initialize NS/BSSGP side */
5447 f_init_bssgp();
5448 /* Initialize GPRS MS side */
5449 f_init_gprs_ms();
5450 ms := g_ms[0]; /* We only use first MS in this test */
5451
5452 /* Initialize the PCU interface abstraction */
5453 f_init_raw(testcasename(), info_ind);
5454
5455 /* Make sure we are not affected by full cache from previous tests */
5456 f_pcuvty_flush_neigh_caches();
5457 /* Set timeout values for caches so that entries will be erased before the second try */
5458 f_pcuvty_set_neigh_caches(1, 1);
5459
5460 /* Establish BSSGP connection to the PCU */
5461 f_bssgp_establish();
5462 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5463
5464 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005465 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 +01005466 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5467 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5468
5469 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005470 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005471
5472 /* CTRL client should have disconnected from us */
5473 f_ipa_ctrl_wait_link_down();
5474 /* wait for cache entries to time out */
5475 f_sleep(2.0);
5476 /* 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 +02005477 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005478
5479 f_shutdown(__BFILE__, __LINE__, final := true);
5480}
5481
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005482/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005483testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5484 var RlcmacDlBlock dl_block;
5485 var PollFnCtx pollctx;
5486 var uint32_t sched_fn;
5487 var GprsMS ms;
5488 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5489 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005490 var GsmArfcn req_arfcn := 862;
5491 var uint6_t req_bsic := 43;
5492
5493 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5494 * resolution CTRL port, to trigger Conn Refused by socket:
5495 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5496 */
5497
5498 /* Initialize NS/BSSGP side */
5499 f_init_bssgp();
5500 /* Initialize GPRS MS side */
5501 f_init_gprs_ms();
5502 ms := g_ms[0]; /* We only use first MS in this test */
5503
5504 /* Initialize the PCU interface abstraction */
5505 f_init_raw(testcasename(), info_ind);
5506
5507 /* Make sure we are not affected by full cache from previous tests */
5508 f_pcuvty_flush_neigh_caches();
5509
5510 /* Establish BSSGP connection to the PCU */
5511 f_bssgp_establish();
5512 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5513
5514 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005515 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 +01005516 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5517 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5518
5519 /* Start NACC from MS side */
5520 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5521 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5522
5523 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005524 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005525 /* Make sure it is a Pkt Cell Chg Continue */
5526 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5527 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5528 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005529 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5530 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5531 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5532 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5533 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005534
5535 f_shutdown(__BFILE__, __LINE__, final := true);
5536}
5537
5538/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005539testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5540 var RlcmacDlBlock dl_block;
5541 var PollFnCtx pollctx;
5542 var uint32_t sched_fn;
5543 var GprsMS ms;
5544 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5545 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005546 var GsmArfcn req_arfcn := 862;
5547 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005548 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005549
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005550 if (use_old_ctrl_iface) {
5551 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5552 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5553 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005554
5555 /* Initialize NS/BSSGP side */
5556 f_init_bssgp();
5557 /* Initialize GPRS MS side */
5558 f_init_gprs_ms();
5559 ms := g_ms[0]; /* We only use first MS in this test */
5560
5561 /* Initialize the PCU interface abstraction */
5562 f_init_raw(testcasename(), info_ind);
5563
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005564 /* Make sure we are not affected by full cache from previous tests */
5565 f_pcuvty_flush_neigh_caches();
5566
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005567 /* Establish BSSGP connection to the PCU */
5568 f_bssgp_establish();
5569 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5570
5571 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005572 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 +01005573 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5574 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5575
5576 /* Start NACC from MS side */
5577 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5578 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5579
5580 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005581 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005582 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 +01005583
5584 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005585 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005586 /* Make sure it is a Pkt Cell Chg Continue */
5587 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5588 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5589 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005590 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5591 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5592 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5593 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5594 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005595
5596 f_shutdown(__BFILE__, __LINE__, final := true);
5597}
5598
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005599/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5600testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5601 var RlcmacDlBlock dl_block;
5602 var PollFnCtx pollctx;
5603 var uint32_t sched_fn;
5604 var GprsMS ms;
5605 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5606 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005607 var GsmArfcn req_arfcn := 862;
5608 var uint6_t req_bsic := 43;
5609
5610 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5611 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5612
5613 /* Initialize NS/BSSGP side */
5614 f_init_bssgp();
5615 /* Initialize GPRS MS side */
5616 f_init_gprs_ms();
5617 ms := g_ms[0]; /* We only use first MS in this test */
5618
5619 /* Initialize the PCU interface abstraction */
5620 f_init_raw(testcasename(), info_ind);
5621
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005622 /* Make sure we are not affected by full cache from previous tests */
5623 f_pcuvty_flush_neigh_caches();
5624
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005625 /* Establish BSSGP connection to the PCU */
5626 f_bssgp_establish();
5627 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5628
5629 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005630 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 +01005631 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5632 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5633
5634 /* Start NACC from MS side */
5635 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5636 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5637
5638 /* osmo-pcu should now ask for resolution: */
5639 f_ipa_ctrl_wait_link_up();
5640 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5641 int2str(info_ind.lac) & "." &
5642 int2str(info_ind.cell_id) & "." &
5643 int2str(req_arfcn) & "." &
5644 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005645 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005646 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5647
5648 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005649 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005650 /* Make sure it is a Pkt Cell Chg Continue */
5651 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5652 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5653 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005654 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5655 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5656 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5657 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5658 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005659
5660 f_shutdown(__BFILE__, __LINE__, final := true);
5661}
5662
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005663/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5664testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5665 var RlcmacDlBlock dl_block;
5666 var PollFnCtx pollctx;
5667 var uint32_t sched_fn;
5668 var GprsMS ms;
5669 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5670 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005671 var GsmArfcn req_arfcn := 862;
5672 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005673 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005674
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005675 if (use_old_ctrl_iface) {
5676 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5677 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5678 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005679
5680 /* Initialize NS/BSSGP side */
5681 f_init_bssgp();
5682 /* Initialize GPRS MS side */
5683 f_init_gprs_ms();
5684 ms := g_ms[0]; /* We only use first MS in this test */
5685
5686 /* Initialize the PCU interface abstraction */
5687 f_init_raw(testcasename(), info_ind);
5688
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005689 /* Make sure we are not affected by full cache from previous tests */
5690 f_pcuvty_flush_neigh_caches();
5691
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005692 /* Establish BSSGP connection to the PCU */
5693 f_bssgp_establish();
5694 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5695
5696 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005697 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 +01005698 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5699 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5700
5701 /* Start NACC from MS side */
5702 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5703 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5704
5705 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005706 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 +01005707
5708 /* RIM procedure: */
Vadim Yanitskiyd8aa5e82023-02-12 17:11:42 +07005709 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005710 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5711
5712 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005713 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005714 /* Make sure it is a Pkt Cell Chg Continue */
5715 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5716 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5717 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005718 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5719 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5720 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5721 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5722 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005723
5724 f_shutdown(__BFILE__, __LINE__, final := true);
5725}
5726
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005727/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5728testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5729 var PollFnCtx pollctx;
5730 var GprsMS ms;
5731 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5732 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5733 var RlcmacDlBlock dl_block;
5734 var uint32_t sched_fn;
5735 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005736 var charstring ctrl_var;
5737 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005738 var GsmArfcn req_arfcn := 862;
5739 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005740 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005741
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005742 if (use_old_ctrl_iface) {
5743 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5744 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5745 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005746
5747 /* Initialize NS/BSSGP side */
5748 f_init_bssgp();
5749 /* Initialize GPRS MS side */
5750 f_init_gprs_ms();
5751 ms := g_ms[0]; /* We only use first MS in this test */
5752
5753 /* Initialize the PCU interface abstraction */
5754 f_init_raw(testcasename(), info_ind);
5755
5756 /* Make sure we are not affected by full cache from previous tests */
5757 f_pcuvty_flush_neigh_caches();
5758
5759 /* Establish BSSGP connection to the PCU */
5760 f_bssgp_establish();
5761 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5762
5763 /* Send PACKET RESOURCE REQUEST */
5764 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5765 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5766 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5767
5768 /* Start NACC from MS side */
5769 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5770 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5771
5772 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005773 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005774 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005775 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005776 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005777 }
5778
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005779 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5780 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5781 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005782
5783 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005784 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005785 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07005786 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005787 }
5788
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005789 timer T := 2.0;
5790 T.start;
5791 alt {
5792 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005793 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005794 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5795 f_shutdown(__BFILE__, __LINE__);
5796 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005797 [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 {
5798 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5799 f_shutdown(__BFILE__, __LINE__);
5800 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005801 [] T.timeout {
5802 setverdict(pass);
5803 }
5804 }
5805
5806 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005807 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005808
5809 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5810 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5811 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5812 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5813 f_shutdown(__BFILE__, __LINE__);
5814 }
5815 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5816 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5817 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5818 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5819 }
5820
5821 f_shutdown(__BFILE__, __LINE__, final := true);
5822}
5823
5824/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5825testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5826 var PollFnCtx pollctx;
5827 var GprsMS ms;
5828 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5829 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5830 var RlcmacDlBlock dl_block;
5831 var uint32_t sched_fn;
5832 var CtrlMessage rx_ctrl;
5833 var GsmArfcn req_arfcn := 862;
5834 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005835 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005836
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005837 if (use_old_ctrl_iface) {
5838 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5839 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5840 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005841
5842 /* Initialize NS/BSSGP side */
5843 f_init_bssgp();
5844 /* Initialize GPRS MS side */
5845 f_init_gprs_ms();
5846 ms := g_ms[0]; /* We only use first MS in this test */
5847
5848 /* Initialize the PCU interface abstraction */
5849 f_init_raw(testcasename(), info_ind);
5850
5851 /* Make sure we are not affected by full cache from previous tests */
5852 f_pcuvty_flush_neigh_caches();
5853
5854 /* Establish BSSGP connection to the PCU */
5855 f_bssgp_establish();
5856 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5857
5858 /* Send PACKET RESOURCE REQUEST */
5859 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5860 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5861 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5862
5863 /* Start NACC from MS side */
5864 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5865 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5866
5867 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005868 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 +01005869 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5870 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5871 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5872 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5873 f_outbound_nacc_rim_tx_resp(info_ind);
5874 timer T := 1.0;
5875 T.start;
5876 alt {
5877 [] RIM.receive {
5878 setverdict(fail, "Received unexpected RIM message");
5879 f_shutdown(__BFILE__, __LINE__);
5880 }
5881 [] T.timeout {
5882 setverdict(pass);
5883 }
5884 }
5885
5886 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005887 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005888
5889 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5890 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5891 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5892 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5893 f_shutdown(__BFILE__, __LINE__);
5894 }
5895 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5896 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5897 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5898 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5899 }
5900
5901 f_shutdown(__BFILE__, __LINE__, final := true);
5902}
5903
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005904/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5905testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5906 var PollFnCtx pollctx;
5907 var GprsMS ms;
5908 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5909 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5910 var RlcmacDlBlock dl_block;
5911 var uint32_t sched_fn;
5912 var CtrlMessage rx_ctrl;
5913 var GsmArfcn req_arfcn := 862;
5914 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005915 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005916
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005917 if (use_old_ctrl_iface) {
5918 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5919 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5920 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005921
5922 /* Initialize NS/BSSGP side */
5923 f_init_bssgp();
5924 /* Initialize GPRS MS side */
5925 f_init_gprs_ms();
5926 ms := g_ms[0]; /* We only use first MS in this test */
5927
5928 /* Initialize the PCU interface abstraction */
5929 f_init_raw(testcasename(), info_ind);
5930
5931 /* Make sure we are not affected by full cache from previous tests */
5932 f_pcuvty_flush_neigh_caches();
5933
5934 /* Establish BSSGP connection to the PCU */
5935 f_bssgp_establish();
5936 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5937
5938 /* Send PACKET RESOURCE REQUEST */
5939 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5940 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5941 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5942
5943 /* Start NACC from MS side */
5944 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5945 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5946
5947 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005948 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 +01005949 /* RIM procedure: */
5950 as_outbound_nacc_rim_resolve(info_ind);
5951
5952 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5953 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5954 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5955
5956 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5957 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5958
5959 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5960 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5961 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5962 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5963 f_shutdown(__BFILE__, __LINE__);
5964 }
5965 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5966 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5967 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5968 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5969 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02005970
5971 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005972}
5973
5974/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5975testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5976 var PollFnCtx pollctx;
5977 var GprsMS ms;
5978 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5979 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5980 var RlcmacDlBlock dl_block;
5981 var uint32_t sched_fn;
5982 var CtrlMessage rx_ctrl;
5983 var GsmArfcn req_arfcn := 862;
5984 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005985 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005986
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005987 if (use_old_ctrl_iface) {
5988 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5989 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5990 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005991
5992 /* Initialize NS/BSSGP side */
5993 f_init_bssgp();
5994 /* Initialize GPRS MS side */
5995 f_init_gprs_ms();
5996 ms := g_ms[0]; /* We only use first MS in this test */
5997
5998 /* Initialize the PCU interface abstraction */
5999 f_init_raw(testcasename(), info_ind);
6000
6001 /* Make sure we are not affected by full cache from previous tests */
6002 f_pcuvty_flush_neigh_caches();
6003
6004 /* Establish BSSGP connection to the PCU */
6005 f_bssgp_establish();
6006 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6007
6008 /* Send PACKET RESOURCE REQUEST */
6009 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6010 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6011 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6012
6013 /* Start NACC from MS side */
6014 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6015 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6016
6017 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006018 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 +01006019 /* RIM procedure: */
6020 as_outbound_nacc_rim_resolve(info_ind);
6021
6022 /* Announce SI back to MS, continue NACC procedure */
6023 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6024
6025 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
6026 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6027
6028 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6029 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6030 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6031 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6032 f_shutdown(__BFILE__, __LINE__);
6033 }
6034 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6035 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6036 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6037 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6038 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006039
6040 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006041}
6042
6043/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
6044testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
6045 var PollFnCtx pollctx;
6046 var GprsMS ms;
6047 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6048 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6049 var RlcmacDlBlock dl_block;
6050 var uint32_t sched_fn;
6051 var CtrlMessage rx_ctrl;
6052 var GsmArfcn req_arfcn := 862;
6053 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006054 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006055
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006056 if (use_old_ctrl_iface) {
6057 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6058 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6059 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006060
6061 /* Initialize NS/BSSGP side */
6062 f_init_bssgp();
6063 /* Initialize GPRS MS side */
6064 f_init_gprs_ms();
6065 ms := g_ms[0]; /* We only use first MS in this test */
6066
6067 /* Initialize the PCU interface abstraction */
6068 f_init_raw(testcasename(), info_ind);
6069
6070 /* Make sure we are not affected by full cache from previous tests */
6071 f_pcuvty_flush_neigh_caches();
6072
6073 /* Establish BSSGP connection to the PCU */
6074 f_bssgp_establish();
6075 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6076
6077 /* Send PACKET RESOURCE REQUEST */
6078 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6079 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6080 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6081
6082 /* Start NACC from MS side */
6083 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6084 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6085
6086 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006087 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 +01006088 /* RIM procedure: */
6089 as_outbound_nacc_rim_resolve(info_ind);
6090
6091 /* Announce SI back to MS, continue NACC procedure */
6092 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6093
6094 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6095 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6096 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6097 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6098 f_shutdown(__BFILE__, __LINE__);
6099 }
6100 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
6101 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6102
6103 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6104 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6105 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6106 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6107 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006108
6109 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006110}
6111
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006112/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6113 * while waiting for CTRL resolution */
6114testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
6115 var PollFnCtx pollctx;
6116 var GprsMS ms;
6117 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6118 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6119 var RlcmacDlBlock dl_block;
6120 var uint32_t sched_fn;
6121 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006122 var charstring ctrl_var;
6123 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006124 var GsmArfcn req_arfcn := 862;
6125 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006126 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006127
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006128 if (use_old_ctrl_iface) {
6129 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6130 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6131 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006132
6133 /* Initialize NS/BSSGP side */
6134 f_init_bssgp();
6135 /* Initialize GPRS MS side */
6136 f_init_gprs_ms();
6137 ms := g_ms[0]; /* We only use first MS in this test */
6138
6139 /* Initialize the PCU interface abstraction */
6140 f_init_raw(testcasename(), info_ind);
6141
6142 /* Make sure we are not affected by full cache from previous tests */
6143 f_pcuvty_flush_neigh_caches();
6144
6145 /* Establish BSSGP connection to the PCU */
6146 f_bssgp_establish();
6147 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6148
6149 /* Send PACKET RESOURCE REQUEST */
6150 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6151 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6152 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6153
6154 /* Start NACC from MS side */
6155 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6156 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6157
6158 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006159 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006160 f_ctrl_rx_nacc_rac_ci_req(rx_ctrl, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006161 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006162 f_pcuif_rx_nacc_rac_ci_req(pcu_msg, info_ind, req_arfcn, req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006163 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006164 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
6165 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6166 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6167 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006168 if (use_old_ctrl_iface) {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006169 f_ctrl_tx_nacc_rac_ci_rsp(rx_ctrl);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006170 } else {
Vadim Yanitskiy8a15b452023-02-13 01:39:57 +07006171 f_pcuif_tx_nacc_rac_ci_rsp(pcu_msg);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006172 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006173 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006174 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 +01006175
6176 /* And finally everything continues as usual with RIN procedure */
6177 as_outbound_nacc_rim_resolve(info_ind);
6178
6179 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006180 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006181
6182 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6183 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6184 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6185 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6186 f_shutdown(__BFILE__, __LINE__);
6187 }
6188 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6189 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6190 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6191 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6192 }
6193
6194 f_shutdown(__BFILE__, __LINE__, final := true);
6195}
6196
6197/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6198 * while waiting for SI resolution */
6199testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
6200 var PollFnCtx pollctx;
6201 var GprsMS ms;
6202 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6203 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6204 var RlcmacDlBlock dl_block;
6205 var uint32_t sched_fn;
6206 var CtrlMessage rx_ctrl;
6207 var GsmArfcn req_arfcn := 862;
6208 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006209 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006210
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006211 if (use_old_ctrl_iface) {
6212 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6213 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6214 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006215
6216 /* Initialize NS/BSSGP side */
6217 f_init_bssgp();
6218 /* Initialize GPRS MS side */
6219 f_init_gprs_ms();
6220 ms := g_ms[0]; /* We only use first MS in this test */
6221
6222 /* Initialize the PCU interface abstraction */
6223 f_init_raw(testcasename(), info_ind);
6224
6225 /* Make sure we are not affected by full cache from previous tests */
6226 f_pcuvty_flush_neigh_caches();
6227
6228 /* Establish BSSGP connection to the PCU */
6229 f_bssgp_establish();
6230 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6231
6232 /* Send PACKET RESOURCE REQUEST */
6233 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6234 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6235 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6236
6237 /* Start NACC from MS side */
6238 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6239 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6240
6241 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006242 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 +01006243 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6244 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
6245 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6246 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6247 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6248 f_outbound_nacc_rim_tx_resp(info_ind);
6249
6250 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006251 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 +01006252
6253 /* And finally everything continues as usual with RIN procedure */
6254 as_outbound_nacc_rim_resolve(info_ind);
6255
6256 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006257 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006258
6259 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6260 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6261 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6262 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6263 f_shutdown(__BFILE__, __LINE__);
6264 }
6265 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6266 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6267 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6268 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6269 }
6270
6271 f_shutdown(__BFILE__, __LINE__, final := true);
6272}
6273
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006274/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6275 * while sending Pkt Neigh Data Change */
6276testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6277 var PollFnCtx pollctx;
6278 var GprsMS ms;
6279 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6280 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6281 var RlcmacDlBlock dl_block;
6282 var uint32_t sched_fn;
6283 var CtrlMessage rx_ctrl;
6284 var GsmArfcn req_arfcn := 862;
6285 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006286 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006287
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006288 if (use_old_ctrl_iface) {
6289 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6290 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6291 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006292
6293 /* Initialize NS/BSSGP side */
6294 f_init_bssgp();
6295 /* Initialize GPRS MS side */
6296 f_init_gprs_ms();
6297 ms := g_ms[0]; /* We only use first MS in this test */
6298
6299 /* Initialize the PCU interface abstraction */
6300 f_init_raw(testcasename(), info_ind);
6301
6302 /* Make sure we are not affected by full cache from previous tests */
6303 f_pcuvty_flush_neigh_caches();
6304
6305 /* Establish BSSGP connection to the PCU */
6306 f_bssgp_establish();
6307 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6308
6309 /* Send PACKET RESOURCE REQUEST */
6310 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6311 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6312 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6313
6314 /* Start NACC from MS side */
6315 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6316 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6317
6318 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006319 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 +01006320 /* RIM procedure: */
6321 as_outbound_nacc_rim_resolve(info_ind);
6322
6323 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6324 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6325 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6326 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6327
6328 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006329 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 +01006330 /* RIM procedure: */
6331 as_outbound_nacc_rim_resolve(info_ind);
6332 /* Transmit SI back to MS */
6333 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6334
6335 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6336 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6337 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6338 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6339 f_shutdown(__BFILE__, __LINE__);
6340 }
6341 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6342 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6343 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6344 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6345 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006346
6347 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006348}
6349
6350/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6351testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6352 var PollFnCtx pollctx;
6353 var GprsMS ms;
6354 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6355 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6356 var RlcmacDlBlock dl_block;
6357 var uint32_t sched_fn;
6358 var CtrlMessage rx_ctrl;
6359 var GsmArfcn req_arfcn := 862;
6360 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006361 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006362
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006363 if (use_old_ctrl_iface) {
6364 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6365 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6366 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006367
6368 /* Initialize NS/BSSGP side */
6369 f_init_bssgp();
6370 /* Initialize GPRS MS side */
6371 f_init_gprs_ms();
6372 ms := g_ms[0]; /* We only use first MS in this test */
6373
6374 /* Initialize the PCU interface abstraction */
6375 f_init_raw(testcasename(), info_ind);
6376
6377 /* Make sure we are not affected by full cache from previous tests */
6378 f_pcuvty_flush_neigh_caches();
6379
6380 /* Establish BSSGP connection to the PCU */
6381 f_bssgp_establish();
6382 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6383
6384 /* Send PACKET RESOURCE REQUEST */
6385 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6386 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6387 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6388
6389 /* Start NACC from MS side */
6390 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6391 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6392
6393 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006394 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 +01006395 /* RIM procedure: */
6396 as_outbound_nacc_rim_resolve(info_ind);
6397
6398 /* Announce SI back to MS, continue NACC procedure */
6399 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6400
6401 /* trigger a Pkt Cell Change Notif with different tgt cell */
6402 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6403 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6404
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006405 /* It should trigger RAC_CI resolution to start again: */
6406 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6407
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006408 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6409 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6410
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006411 /* RIM procedure: */
6412 as_outbound_nacc_rim_resolve(info_ind);
6413 /* Transmit SI back to MS */
6414 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6415
6416 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6417 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6418 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6419 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6420 f_shutdown(__BFILE__, __LINE__);
6421 }
6422 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6423 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6424 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6425 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6426 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006427
6428 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006429}
6430
6431/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6432testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6433 var PollFnCtx pollctx;
6434 var GprsMS ms;
6435 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6436 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6437 var RlcmacDlBlock dl_block;
6438 var uint32_t sched_fn;
6439 var CtrlMessage rx_ctrl;
6440 var GsmArfcn req_arfcn := 862;
6441 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006442 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006443
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006444 if (use_old_ctrl_iface) {
6445 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6446 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6447 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006448
6449 /* Initialize NS/BSSGP side */
6450 f_init_bssgp();
6451 /* Initialize GPRS MS side */
6452 f_init_gprs_ms();
6453 ms := g_ms[0]; /* We only use first MS in this test */
6454
6455 /* Initialize the PCU interface abstraction */
6456 f_init_raw(testcasename(), info_ind);
6457
6458 /* Make sure we are not affected by full cache from previous tests */
6459 f_pcuvty_flush_neigh_caches();
6460
6461 /* Establish BSSGP connection to the PCU */
6462 f_bssgp_establish();
6463 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6464
6465 /* Send PACKET RESOURCE REQUEST */
6466 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6467 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6468 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6469
6470 /* Start NACC from MS side */
6471 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6472 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6473
6474 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006475 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 +01006476 /* RIM procedure: */
6477 as_outbound_nacc_rim_resolve(info_ind);
6478
6479 /* Announce SI back to MS, continue NACC procedure */
6480 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6481
6482 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6483 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6484 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6485 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6486 f_shutdown(__BFILE__, __LINE__);
6487 }
6488
6489 /* trigger a Pkt Cell Change Notif with different tgt cell */
6490 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6491 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6492
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006493 /* It should trigger RAC_CI resolution to start again: */
6494 /* When using new PCUIF interface for resolution, we must
6495 * PCUIF.receive() here since that's the first message in the PCUIF
6496 * queue that PCU will have sent. Calling other functions doing
6497 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6498 * due to unexpected message receive. */
6499 if (not use_old_ctrl_iface) {
6500 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6501 }
6502
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006503 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6504 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6505 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6506 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6507 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006508
6509 /* When using CTRL interface, we must schedule the ACK before (see
6510 * above) blocking here waiting for the resoltion, otherwise we'll be
6511 * too late scheduling by the time the resolution is done. */
6512 if (use_old_ctrl_iface) {
6513 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6514 }
6515
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006516 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6517 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6518
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006519 /* RIM procedure: */
6520 as_outbound_nacc_rim_resolve(info_ind);
6521 /* Transmit SI back to MS */
6522 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6523
6524 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6525 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6526 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6527 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6528 f_shutdown(__BFILE__, __LINE__);
6529 }
6530 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6531 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6532 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6533 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6534 }
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006535
6536 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006537}
6538
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006539/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6540testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6541 var PollFnCtx pollctx;
6542 var GprsMS ms;
6543 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6544 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6545 var RlcmacDlBlock dl_block;
6546 var uint32_t sched_fn, dl_fn;
6547 var CtrlMessage rx_ctrl;
6548 var GsmArfcn req_arfcn := 862;
6549 var uint6_t req_bsic := 43;
6550 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006551 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006552
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006553 if (use_old_ctrl_iface) {
6554 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6555 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6556 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006557
6558 /* Initialize NS/BSSGP side */
6559 f_init_bssgp();
6560 /* Initialize GPRS MS side */
6561 f_init_gprs_ms();
6562 ms := g_ms[0]; /* We only use first MS in this test */
6563
6564 /* Initialize the PCU interface abstraction */
6565 f_init_raw(testcasename(), info_ind);
6566
6567 /* Make sure we are not affected by full cache from previous tests */
6568 f_pcuvty_flush_neigh_caches();
6569
6570 /* Establish BSSGP connection to the PCU */
6571 f_bssgp_establish();
6572 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6573
6574 /* Send PACKET RESOURCE REQUEST */
6575 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6576 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6577 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6578
6579 /* Start NACC from MS side */
6580 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6581 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6582
6583 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006584 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 +01006585 /* RIM procedure: */
6586 as_outbound_nacc_rim_resolve(info_ind);
6587
6588 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6589 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6590 f_sleep(0.1);
6591 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6592 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6593
6594 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6595 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6596 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6597 * Data with unassigned DL TBF in line above): */
6598 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6599 /* Continue receiving Pkt Cell Neighbor Data */
6600 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6601
6602 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6603 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6604 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6605 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6606 f_shutdown(__BFILE__, __LINE__);
6607 }
6608 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6609 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6610 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6611 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6612 }
6613
6614 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6615 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6616 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6617 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6618 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol002658a2023-04-12 18:13:56 +02006619
6620 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006621}
6622
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006623
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006624function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6625runs on RAW_PCU_Test_CT
6626{
6627 var template (value) RAN_Information_Request_RIM_Container req_cont;
6628 var template (value) PDU_BSSGP bssgp_rim_pdu;
6629 var template PDU_BSSGP bssgp_rim_pdu_expect;
6630 var template RAN_Information_RIM_Container rim_cont_expect;
6631 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006632
6633 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006634 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 +01006635 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006636 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 +01006637 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006638 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);
6639 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006640 f_sleep(1.0);
6641
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006642 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006643
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006644 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6645 ts_RIM_Sequence_Number(1),
6646 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6647 ts_RIM_Protocol_Version_Number(1),
6648 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6649 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006650 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6651 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006652
6653 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6654 tr_RIM_Sequence_Number(1),
6655 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6656 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006657 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 +01006658 omit);
6659
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006660 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6661 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006662 rim_cont_expect);
6663 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006664 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006665 T.start;
6666 alt {
6667 [] RIM.receive(bssgp_rim_pdu_expect) { }
6668 [] RIM.receive {
6669 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6670 }
6671 [] T.timeout {
6672 setverdict(fail, "No BSSGP RIM PDU received");
6673 mtc.stop;
6674 }
6675 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006676}
6677/* Send a RIM RAN info request to the PCU and verify the response, we expect
6678 * getting the system information back which we have transfered to the PCU via
6679 * PCUIF on startup. */
6680testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6681 /* Initialize NS/BSSGP side */
6682 f_init_bssgp();
6683
6684 /* Initialize the PCU interface abstraction */
6685 f_init_raw(testcasename());
6686
6687 /* Establish BSSGP connection to the PCU */
6688 f_bssgp_establish();
6689
6690 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6691 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6692
6693 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6694 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6695
6696 f_shutdown(__BFILE__, __LINE__, final := true);
6697}
6698
6699/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6700 * Routing information, to verify PCU handles that kind of address just fine
6701 */
6702testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6703 /* Initialize NS/BSSGP side */
6704 f_init_bssgp();
6705
6706 /* Initialize the PCU interface abstraction */
6707 f_init_raw(testcasename());
6708
6709 /* Establish BSSGP connection to the PCU */
6710 f_bssgp_establish();
6711
6712 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6713 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6714
6715 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6716 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006717
6718 f_shutdown(__BFILE__, __LINE__, final := true);
6719}
6720
6721/* Same as above, but in this case we simulate the rare case in which the PCU
6722 * has no system information available. We expect getting a response back but
6723 * with no system information inside. */
6724testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006725 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006726 var PCUIF_Message pcu_msg;
6727 timer T := 2.0;
6728
6729 /* Initialize NS/BSSGP side */
6730 f_init_bssgp();
6731
6732 /* Initialize the PCU interface abstraction */
6733 f_init_raw(testcasename(), info_ind);
6734
6735 /* Establish BSSGP connection to the PCU */
6736 f_bssgp_establish();
6737
6738 /* Clear sysinfo from the PCU */
6739 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);
6740 BTS.send(si1_data_ind);
6741 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);
6742 BTS.send(si3_data_ind);
6743 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);
6744 BTS.send(si16_data_ind);
6745 f_sleep(1.0);
6746
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006747 var RIM_Routing_Address dst_addr;
6748 var RIM_Routing_Address src_addr;
6749 var template (value) RAN_Information_Request_RIM_Container req_cont;
6750 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006751 var template PDU_BSSGP bssgp_rim_pdu_expect;
6752 var template RAN_Information_RIM_Container rim_cont_expect;
6753
6754 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 +01006755 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6756 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006757
6758 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6759 ts_RIM_Sequence_Number(1),
6760 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6761 ts_RIM_Protocol_Version_Number(1),
6762 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6763 omit);
6764 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6765 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6766 req_cont);
6767
6768
6769 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6770 tr_RIM_Sequence_Number(1),
6771 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6772 tr_RIM_Protocol_Version_Number(1),
6773 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6774 omit);
6775
6776 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6777 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6778 rim_cont_expect);
6779 RIM.send(bssgp_rim_pdu);
6780 T.start;
6781 alt {
6782 [] RIM.receive(bssgp_rim_pdu_expect) { }
6783 [] RIM.receive {
6784 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6785 }
6786 [] T.timeout {
6787 setverdict(fail, "No BSSGP RIM PDU received");
6788 mtc.stop;
6789 }
6790 }
6791
6792 f_shutdown(__BFILE__, __LINE__, final := true);
6793}
6794
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006795/* 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 +02006796testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6797 var PCUIF_info_ind info_ind;
6798 var template (value) TsTrxBtsNum nr;
6799 var RlcmacDlBlock dl_block;
6800 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006801 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006802 timer T;
6803
6804 /* Initialize NS/BSSGP side */
6805 f_init_bssgp();
6806
6807 info_ind := valueof(ts_PCUIF_INFO_default);
6808 /* The 2 first TRX are enabled. */
6809 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6810 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6811 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6812
6813 /* Initialize the PCU interface abstraction */
6814 f_init_raw(testcasename(), info_ind);
6815
6816 /* Establish BSSGP connection to the PCU */
6817 f_bssgp_establish();
6818
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006819 for (ts := 0; ts < 2; ts := ts + 1) {
6820 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006821
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006822 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6823 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6824 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6825 T.start(0.5);
6826 alt {
6827 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6828 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6829 omit)) -> value data_msg {
6830 setverdict(pass);
6831 T.stop;
6832 }
6833 [] as_rx_fail_dummy(nr);
6834 [] BTS.receive {
6835 setverdict(fail, "Unexpected block from BTS");
6836 f_shutdown(__BFILE__, __LINE__);
6837 }
6838 [] T.timeout {
6839 setverdict(fail, "Expected IDLE block from BTS");
6840 f_shutdown(__BFILE__, __LINE__);
6841 }
6842 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006843 }
6844
6845 f_shutdown(__BFILE__, __LINE__, final := true);
6846}
6847
Oliver Smith3d174882021-09-03 11:38:51 +02006848/* Test stats for available and occupied PDCHs */
6849testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6850 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6851 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6852
6853 /* Initialize NS/BSSGP side */
6854 f_init_bssgp();
6855
Oliver Smithedcded22021-09-14 09:26:55 +02006856 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6857 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6858 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6859 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6860 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6861 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006862
Oliver Smith72d0c692021-09-08 10:03:52 +02006863 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006864 f_init_gprs_ms(4);
6865
6866 /* Initialize the PCU interface abstraction */
6867 f_init_raw(testcasename(), info_ind);
6868
6869 /* Reset stats */
6870 f_statsd_reset();
6871
6872 /* Establish BSSGP */
6873 f_bssgp_establish();
6874
6875 /* 8 PDCHs available, 0 occupied */
6876 var StatsDExpects expect := {
6877 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006878 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6879 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6880 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006881 };
6882 f_statsd_expect(expect);
6883
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006884 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006885 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006886 f_ms_establish_ul_tbf(g_ms[0]);
6887 f_ms_establish_ul_tbf(g_ms[1]);
6888 f_ms_establish_ul_tbf(g_ms[2]);
6889 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 +02006890
6891 /* 4 PDCHs occupied */
6892 expect := {
6893 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006894 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6895 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6896 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006897 };
6898 f_statsd_expect(expect);
6899
6900 f_shutdown(__BFILE__, __LINE__, final := true);
6901}
6902
Oliver Smithf04762d2021-09-14 17:20:38 +02006903/* Test stats for available and occupied PDCHs, for MS which is not known by
6904 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6905 * data arrives from SGSN) */
6906function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6907 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6908 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6909
6910 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6911 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6912 gprsmultislotclass := '00001'B,
6913 gprsextendeddynalloccap := '0'B
6914 };
6915 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6916 egprsmultislotclass := '00001'B,
6917 egprsextendeddynalloccap := '0'B
6918 };
6919 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6920 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6921 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6922 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6923
6924 /* Initialize NS/BSSGP side */
6925 f_init_bssgp();
6926
6927 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6928 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6929 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6930 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6931 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6932 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6933
6934 /* Allocate 1 GprsMS instance */
6935 f_init_gprs_ms(1);
6936
6937 /* Initialize the PCU interface abstraction */
6938 f_init_raw(testcasename(), info_ind);
6939
6940 /* Reset stats */
6941 f_statsd_reset();
6942
6943 /* Establish BSSGP */
6944 f_bssgp_establish();
6945
6946 /* 8 PDCHs available, 0 occupied */
6947 var StatsDExpects expect := {
6948 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6949 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6950 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6951 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6952 };
6953 f_statsd_expect(expect);
6954
6955 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6956 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6957
6958 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6959 var octetstring data := f_rnd_octstring(1400);
6960 if (egprs) {
6961 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6962 } else {
6963 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6964 }
6965 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6966
6967 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6968 f_sleep(X2002);
6969
6970 /* 1 PDCH occupied */
6971 if (egprs) {
6972 expect := {
6973 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6974 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6975 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6976 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6977 };
6978 } else {
6979 expect := {
6980 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6981 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6982 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6983 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6984 };
6985 }
6986 f_statsd_expect(expect);
6987
6988 /* Clean up */
6989 f_shutdown(__BFILE__, __LINE__, final := true);
6990}
6991testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6992 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6993}
6994testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6995 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6996}
6997
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006998/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6999testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
7000 var PCUIF_info_ind info_ind;
7001 var template IARRestOctets rest;
7002 var BIT11 ra11;
7003
7004 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007005
7006 /* Only the first TRX is enabled. */
7007 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
7008 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
7009
7010 /* Initialize the PCU interface abstraction */
7011 f_init_raw(testcasename(), info_ind);
7012 f_statsd_reset();
7013
7014 var EGPRSPktChRequest req := {
7015 one_phase := {
7016 tag := '0'B,
7017 multislot_class := '10101'B,
7018 priority := '01'B,
7019 random_bits := '101'B
7020 }
7021 };
7022
7023 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
7024 for (var integer i := 0; i < 7; i := i + 1) {
7025 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
7026 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
7027 }
7028
7029 ra11 := enc_EGPRSPktChRequest2bits(req);
7030 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
7031
7032 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01007033 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007034
7035 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
7036 f_sleep(2.0);
7037 var StatsDExpects expect := {
7038 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
7039 };
7040 f_statsd_expect(expect);
7041
7042 f_shutdown(__BFILE__, __LINE__, final := true);
7043}
7044
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007045control {
7046 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01007047 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007048 execute( TC_ta_ptcch_idle() );
7049 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02007050 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007051 execute( TC_ta_idle_dl_tbf_ass() );
7052 execute( TC_ta_ptcch_ul_multi_tbf() );
7053 execute( TC_cs_lqual_ul_tbf() );
7054 execute( TC_cs_initial_ul() );
7055 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01007056 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01007057 execute( TC_cs_max_dl() );
7058 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01007059 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01007060 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01007061 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01007062 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02007063 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01007064 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02007065 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01007066 execute( TC_x2031_t3191() );
7067 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007068 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01007069 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01007070 execute( TC_t3172_wait_ind_size0() );
7071 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02007072 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02007073 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02007074 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007075 execute( TC_mo_ping_pong() );
7076 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02007077 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007078 execute( TC_mt_ping_pong() );
7079 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007080 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007081 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07007082 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007083 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01007084 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02007085 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007086 execute( TC_paging_cs_from_bts() );
7087 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
7088 execute( TC_paging_cs_from_sgsn_sign() );
7089 execute( TC_paging_cs_from_sgsn_ptp() );
7090 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
7091 execute( TC_paging_ps_from_sgsn_sign() );
7092 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01007093 execute( TC_paging_pch_timeout() );
7094
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07007095 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
7096 execute( TC_paging_cs_multi_ms_imsi() );
7097 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02007098 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
7099 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01007100 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
7101 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007102
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007103 execute( TC_ul_tbf_finished_pkt_dl_ass_pch() );
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02007104 execute( TC_ul_tbf_1phase_while_dl_ass_pch() );
7105 execute( TC_ul_tbf_2phase_while_dl_ass_pch() );
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007106
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007107 /* EGPRS specific test cases */
7108 execute( TC_egprs_pkt_chan_req_signalling() );
7109 execute( TC_egprs_pkt_chan_req_one_phase() );
7110 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07007111 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07007112 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07007113 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02007114
7115 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07007116
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007117 /* Immediate Assignment on AGCH/PCH */
7118 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
7119 execute( TC_pcuif_fh_imm_ass_ul() );
7120 execute( TC_pcuif_fh_imm_ass_dl() );
7121 /* Packet Uplink/Downlink Assignment on PACCH */
7122 execute( TC_pcuif_fh_pkt_ass_ul() );
7123 execute( TC_pcuif_fh_pkt_ass_dl() );
7124 execute( TC_multitrx_multims_alloc() );
7125 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
7126 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
7127 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02007128 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrol9584ef22023-06-12 14:21:28 +02007129 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_t3168() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01007130 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
7131 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007132
Pau Espin Pedrole1303052020-11-16 11:13:51 +01007133 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07007134
7135 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01007136 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01007137 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01007138 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01007139 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01007140 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01007141 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01007142 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
7143 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01007144 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
7145 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
7146 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01007147 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
7148 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01007149 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
7150 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
7151 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007152 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02007153 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
7154 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
7155 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
7156 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007157
7158 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007159 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007160 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007161
7162 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02007163
7164 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02007165 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
7166 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007167 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007168}
7169
Harald Weltea419df22019-03-21 17:23:04 +01007170}