blob: 876b282db5b30ae8d94ba91a8a7e4842819ef15c [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 }
563}
564
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200565/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
566 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
567 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
568 * no active TBF exists at the moment of establishment (idle mode). */
569testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100570 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200571
572 /* Initialize NS/BSSGP side */
573 f_init_bssgp();
574
575 /* Initialize the PCU interface abstraction */
576 f_init_raw(testcasename());
577
578 /* Establish BSSGP connection to the PCU */
579 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100580 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200581
582 /* SGSN sends some DL data, PCU will initiate Packet Downlink
583 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100584 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
585 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200586
587 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
588 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
589 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100590 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700591 setverdict(fail, "Timing Advance value doesn't match");
592 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700593
594 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200595}
596
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200597/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200598 * while neither Uplink nor Downlink TBF is established. */
599testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100600 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200601 timer T;
602
603 /* Initialize the PCU interface abstraction */
604 f_init_raw(testcasename());
605
606 /* Sent an RTS.req for PTCCH/D */
607 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
608 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
609 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100610
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200611 T.start(5.0);
612 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200613 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
614 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
615 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200616 }
617 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100618 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
619 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200620 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200621 [] BTS.receive(PCUIF_Message:?) { repeat; }
622 [] T.timeout {
623 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700624 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200625 }
626 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100627 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700628
629 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200630}
631
632/* Test of correct Timing Advance during an active Uplink TBF.
633 *
634 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
635 * are not continuous and there can be long time gaps between them. This happens
636 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
637 * significantly change between such rare Uplink transmissions, so GPRS introduces
638 * additional mechanisms to control Timing Advance, and thus reduce interference
639 * between neighboring TDMA time-slots.
640 *
641 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
642 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
643 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
644 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
645 * among with the initial Timing Advance value. And here PTCCH comes to play.
646 *
647 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
648 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
649 * continuously. To ensure continuous measurements of the signal propagation
650 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
651 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
652 *
653 * The purpose of this test case is to verify the assignment of Timing Advance
654 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
655 * first establishes several Uplink TBFs, but does not transmit any Uplink
656 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
657 * indications to the PCU, checking the correctness of two received PTCCH/D
658 * messages (period of PTCCH/D is two multi-frames).
659 */
660
661/* List of ToA values for Access Bursts to be sent on PTCCH/U,
662 * each ToA (Timing of Arrival) value is in units of 1/4 of
663 * a symbol (i.e. 1 symbol is 4 QTA units). */
664type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
665const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
666 0, 0, 0, 0,
667 0, 0, 0, 0,
668 0, 0, 0, 0,
669 0, 0, 0, 0
670};
671
672private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
673 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
674runs on RAW_PCU_Test_CT {
675 var RAW_PCU_Event event;
676 var integer ss;
677
678 /* Send Access Bursts on PTCCH/U for every TA Index */
679 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
680 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700681 if (ss < 0) { /* Shall not happen */
682 f_shutdown(__BFILE__, __LINE__);
683 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200684
685 log("Sending an Access Burst on PTCCH/U",
686 ", sub-slot=", ss, " (TAI)",
687 ", fn=", event.data.tdma_fn,
688 ", ToA=", toa_map[ss], " (QTA)");
689 /* TODO: do we care about RA and burst format? */
690 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
691 ra := oct2int('3A'O),
692 is_11bit := 0,
693 burst_type := BURST_TYPE_0,
694 fn := event.data.tdma_fn,
695 arfcn := 871,
696 qta := toa_map[ss],
697 sapi := PCU_IF_SAPI_PTCCH));
698 repeat;
699 }
700}
701
702private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
703 template PTCCHDownlinkMsg t_ta_msg)
704runs on RAW_PCU_Test_CT {
705 var PTCCHDownlinkMsg ta_msg;
706 var PCUIF_Message pcu_msg;
707 timer T;
708
709 /* First, send an RTS.req for the upcoming PTCCH/D block */
710 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
711 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
712 arfcn := 871, block_nr := 0));
713 T.start(2.0);
714 alt {
715 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
716 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
717 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
718 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
719 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
720 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
721 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
722 log("Rx PTCCH/D message: ", ta_msg);
723
724 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700725 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200726 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
727 }
728 }
729 [] BTS.receive { repeat; }
730 [] T.timeout {
731 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200732 }
733 }
734}
735
736testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
737 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200738 var GprsMS ms;
739
740 /* Initialize GPRS MS side */
741 f_init_gprs_ms();
742 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200743
744 /* Initialize the PCU interface abstraction */
745 f_init_raw(testcasename());
746
747 /* Enable forwarding of PTCCH/U TDMA events to us */
748 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
749
750 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
751 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200752 /* Establish an Uplink TBF */
753 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200754
755 /* We expect incremental TFI/USF assignment (dynamic allocation) */
756 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200757 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200758 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700759 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200760 }
761
762 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200763 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200764 setverdict(fail, "Failed to match Timing Advance Index for #", i);
765 /* Keep going, the current OsmoPCU does not assign TA Index */
766 }
767 }
768
769 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
770 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
771 for (var integer i := 0; i < 7; i := i + 1) {
772 /* ToA in units of 1/4 of a symbol */
773 toa_map[i] := (i + 1) * 7 * 4;
774 }
775
776 /* Now we have all 7 TBFs established in one-phase access mode,
777 * however we will not be sending any data on them. Instead, we
778 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
779 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
780 *
781 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
782 * time-slots, so at the moment of scheduling a PTCCH/D block
783 * the PCU has odd number of PTCCH/U Access Bursts received. */
784 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
785 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
786 /* Other values are not known (yet) */
787 tai3_ta := ?));
788 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
789 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
790 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
791 /* Other values are out of our interest */
792 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700793
794 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200795}
796
797/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
798 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
799 *
800 * NOTE: the ranges are intentionally overlapping because OsmoPCU
801 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
802private template integer CS1_lqual_dB_range := (-infinity .. 6);
803private template integer CS2_lqual_dB_range := (5 .. 8);
804private template integer CS3_lqual_dB_range := (7 .. 13);
805private template integer CS4_lqual_dB_range := (12 .. infinity);
806
807testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200808 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200809 var GprsMS ms;
810 var uint32_t unused_fn, sched_fn;
811 var uint4_t cv;
812
813 /* Initialize GPRS MS side */
814 f_init_gprs_ms();
815 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200816
817 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100818 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200819
820 f_pcuvty_set_allowed_cs_mcs();
821 f_pcuvty_set_link_quality_ranges();
822
823 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200824 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200825
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200826
827 /* The actual / old link quality values. We need to keep track of the old
828 * (basically previous) link quality value, because OsmoPCU actually
829 * changes the coding scheme if not only the actual, but also the old
830 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200831 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200832 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200833
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200834 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200835 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200836 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
837 /* 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 +0200838 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 +0200839 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
840 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
841 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200842
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200843 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
844 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200845 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200846 lqual_old := ms.lqual_cb;
847 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200848
849 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200850 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
851 if (i > g_bs_cv_max) {
852 cv := 15;
853 } else {
854 cv := i;
855 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200856
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200857 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
858
859 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
860 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700861 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200862 continue;
863 }
864 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
865 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
866 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
867 f_shutdown(__BFILE__, __LINE__);
868 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200869
870 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
871 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
872
873 /* Match the received Channel Coding Command. Since we are increasing
874 * the link quality value on each iteration and not decreasing, there
875 * is no need to check the both old and current link quality values. */
876 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200877 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200878 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
879 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
880 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
881 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
882 }
883
884 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
885 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200886 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200887 }
888 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700889
890 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200891}
892
893/* Test the max UL CS set by VTY works fine */
894testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200895 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200896 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200897 var uint32_t unused_fn, sched_fn;
898 var GprsMS ms;
899
900 /* Initialize GPRS MS side */
901 f_init_gprs_ms();
902 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200903
904 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100905 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200906
907 /* Set initial UL CS to 3 */
908 g_cs_initial_ul := 3;
909 f_pcuvty_set_allowed_cs_mcs();
910 f_pcuvty_set_link_quality_ranges();
911
912 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200913 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200914
915 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200916 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200917
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200918 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200919 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200920 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
921 /* 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 +0200922 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 +0200923 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
924 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
925 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200926
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200927 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
928 while (true) {
929 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
930 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +0700931 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200932 continue;
933 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200934
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200935 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
936 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
937 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
938 f_shutdown(__BFILE__, __LINE__);
939 break;
940 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200941
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200942 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200943 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200944 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200945 if (last_ch_coding != CH_CODING_CS3) {
946 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200947 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200948 }
949
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200950 /* Remaining UL blocks are used to make sure regardless of initial
951 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200952 /* 0 dB, make sure we downgrade CS */
953 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200954 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200955 f_ms_tx_ul_data_block_multi(ms, 5);
956 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
957 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
958 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200959
960 if (last_ch_coding != CH_CODING_CS1) {
961 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200962 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200963 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700964
965 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200966}
967
968/* Test the max UL CS set by VTY works fine */
969testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200970 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200971 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200972 var uint32_t unused_fn, sched_fn;
973 var GprsMS ms;
974
975 /* Initialize GPRS MS side */
976 f_init_gprs_ms();
977 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200978
979 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100980 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200981
982 /* Set maximum allowed UL CS to 3 */
983 g_cs_max_ul := 3;
984 f_pcuvty_set_allowed_cs_mcs();
985 f_pcuvty_set_link_quality_ranges();
986
987 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200988 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200989
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200990 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +0200991 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200992 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
993 /* 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 +0200994 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 +0200995 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
996 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
997 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200998
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200999 ms.lqual_cb := 40*10; /* 40 dB */
1000 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001001
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001002 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1003 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001004
1005 if (last_ch_coding != CH_CODING_CS3) {
1006 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001007 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001008 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001009
1010 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001011}
1012
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001013/* Test the initial DL CS set by VTY works fine */
1014testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1015 var octetstring data := f_rnd_octstring(10);
1016 var CodingScheme exp_dl_cs_mcs;
1017 var RlcmacDlBlock dl_block;
1018 var uint32_t poll_fn;
1019 var GprsMS ms;
1020
1021 /* Initialize NS/BSSGP side */
1022 f_init_bssgp();
1023 /* Initialize GPRS MS side */
1024 f_init_gprs_ms();
1025 ms := g_ms[0]; /* We only use first MS in this test */
1026
1027 /* Initialize the PCU interface abstraction */
1028 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1029
1030 /* Set initial allowed DL CS to 3 */
1031 g_cs_initial_dl := 3;
1032 exp_dl_cs_mcs := CS_3;
1033 /* Set maximum allowed UL CS to 4 */
1034 g_cs_max_dl := 4;
1035 f_pcuvty_set_allowed_cs_mcs();
1036 f_pcuvty_set_link_quality_ranges();
1037
1038 /* Establish BSSGP connection to the PCU */
1039 f_bssgp_establish();
1040 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1041
1042 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1043 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1044 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1045
1046 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1047 f_sleep(X2002);
1048 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1049
1050 /* ACK the DL block */
1051 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1052 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1053 f_dl_block_ack_fn(dl_block, poll_fn));
1054
1055 f_shutdown(__BFILE__, __LINE__, final := true);
1056}
1057
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001058/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001059function 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 +01001060 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001061 var RlcmacDlBlock prev_dl_block, dl_block;
1062 var uint32_t ack_fn;
1063 var uint32_t fn;
1064 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001065 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001066 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001067 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1068 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001069 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001070
1071 if (using_egprs) {
1072 exp_tmp_csmcs := mcs_egprs_any;
1073 bsn_mod := 2048;
1074 } else {
1075 exp_tmp_csmcs := cs_gprs_any;
1076 bsn_mod := 128;
1077 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001078
1079 /* Establish BSSGP connection to the PCU */
1080 f_bssgp_establish();
1081
1082 ms := g_ms[0]; /* We only use first MS in this test */
1083 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1084
1085 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001086 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001087 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1088
1089 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1090 f_sleep(X2002);
1091
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001092 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
1093 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
1094
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001095 for (var integer i := 0; i < 800; i := i + 1) {
1096 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001097
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001098 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001099 /* No more data to receive, done */
1100 break;
1101 }
1102
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001103 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001104
1105 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001106 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001107
1108 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001109 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001110 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001111 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 +01001112 if (tx_data_remain != 0) {
1113 /* Submit more data from time to time to keep the TBF ongoing */
1114 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1115 tx_data_remain := tx_data_remain - 1;
1116 }
1117 }
1118 prev_dl_block := dl_block;
Pau Espin Pedrole3e2bf62022-11-29 14:32:48 +01001119 f_rx_rlcmac_dl_block(dl_block, fn);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001120 }
1121
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001122 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1123 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001124
1125
1126 f_shutdown(__BFILE__, __LINE__, final := true);
1127}
1128
1129/* Verify DL CS above "cs max" set by VTY is never used */
1130testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1131 /* Initialize NS/BSSGP side */
1132 f_init_bssgp();
1133 /* Initialize GPRS MS side */
1134 f_init_gprs_ms();
1135
1136 /* Initialize the PCU interface abstraction */
1137 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1138
1139 /* Set maximum allowed DL CS to 3 */
1140 g_cs_initial_dl := 1;
1141 g_cs_max_dl := 3;
1142 f_pcuvty_set_allowed_cs_mcs();
1143 f_pcuvty_set_link_quality_ranges();
1144
1145 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1146}
1147
1148/* Check DL CS4 is used in good link conditions if allowed by config */
1149testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1150 /* Initialize NS/BSSGP side */
1151 f_init_bssgp();
1152 /* Initialize GPRS MS side */
1153 f_init_gprs_ms();
1154
1155 /* Initialize the PCU interface abstraction */
1156 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1157
1158 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1159 g_cs_initial_dl := 1;
1160 g_cs_max_dl := 4;
1161 f_pcuvty_set_allowed_cs_mcs();
1162 f_pcuvty_set_link_quality_ranges();
1163
1164 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1165}
1166
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001167/* Test the initial UL MCS set by VTY works fine */
1168testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1169 var RlcmacDlBlock dl_block;
1170 var PollFnCtx pollctx;
1171 var EgprsChCodingCommand last_ch_coding;
1172 var uint32_t unused_fn, sched_fn;
1173 var GprsMS ms;
1174 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001175
1176 /* Initialize GPRS MS side */
1177 f_init_gprs_ms();
1178 ms := g_ms[0]; /* We only use first MS in this test */
1179
1180 /* Initialize the PCU interface abstraction */
1181 f_init_raw(testcasename());
1182
1183 /* Set initial UL MCS to 3 */
1184 g_mcs_initial_ul := 3;
1185 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1186 f_pcuvty_set_allowed_cs_mcs();
1187 f_pcuvty_set_link_quality_ranges();
1188
1189 /* Take lqual (dB->cB) so that we stay in that MCS */
1190 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1191
1192 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001193 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 +01001194
1195 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1196 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1197 f_shutdown(__BFILE__, __LINE__);
1198 }
1199
1200 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1201 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1202
1203 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1204 while (true) {
1205 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1206 f_rx_rlcmac_dl_block(dl_block, unused_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001207 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001208 continue;
1209 }
1210
1211 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1212 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1213 f_shutdown(__BFILE__, __LINE__);
1214 break;
1215 }
1216
1217 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1218 break;
1219 }
1220 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1221 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1222 f_shutdown(__BFILE__, __LINE__);
1223 }
1224
1225 /* Remaining UL blocks are used to make sure regardless of initial
1226 * lqual, we can go lower at any time
1227 * 0 dB, make sure we downgrade MCS */
1228 ms.lqual_cb := 0;
1229 /* 5 UL blocks, check we are in same initial MCS: */
1230 f_ms_tx_ul_data_block_multi(ms, 5);
1231 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1232 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1233 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1234
1235 if (last_ch_coding != CH_CODING_MCS1) {
1236 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1237 f_shutdown(__BFILE__, __LINE__);
1238 }
1239
1240 f_shutdown(__BFILE__, __LINE__, final := true);
1241}
1242
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001243/* Test the maximum UL MCS set by VTY works fine */
1244testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1245 var RlcmacDlBlock dl_block;
1246 var EgprsChCodingCommand last_ch_coding;
1247 var PollFnCtx pollctx;
1248 var uint32_t unused_fn, sched_fn;
1249 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001250
1251 /* Initialize GPRS MS side */
1252 f_init_gprs_ms();
1253 ms := g_ms[0]; /* We only use first MS in this test */
1254
1255 /* Initialize the PCU interface abstraction */
1256 f_init_raw(testcasename());
1257
1258 /* Set maximum allowed UL MCS to 5 */
1259 g_mcs_max_ul := 5;
1260 f_pcuvty_set_allowed_cs_mcs();
1261 f_pcuvty_set_link_quality_ranges();
1262
1263 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001264 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 +01001265 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1266 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1267
1268 ms.lqual_cb := 40*10; /* 40 dB */
1269 f_ms_tx_ul_data_block_multi(ms, 16);
1270
1271 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1272 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1273
1274 if (last_ch_coding != CH_CODING_MCS5) {
1275 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1276 f_shutdown(__BFILE__, __LINE__);
1277 }
1278
1279 f_shutdown(__BFILE__, __LINE__, final := true);
1280}
1281
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001282/* Test the initial DL CS set by VTY works fine */
1283testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1284 var octetstring data := f_rnd_octstring(10);
1285 var CodingScheme exp_dl_cs_mcs;
1286 var RlcmacDlBlock dl_block;
1287 var uint32_t poll_fn;
1288 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001289
1290 /* Initialize NS/BSSGP side */
1291 f_init_bssgp();
1292 /* Initialize GPRS MS side */
1293 f_init_gprs_ms();
1294 ms := g_ms[0]; /* We only use first MS in this test */
1295
1296 /* Initialize the PCU interface abstraction */
1297 f_init_raw(testcasename());
1298
1299 /* Set initial allowed DL MCS to 3 */
1300 g_mcs_initial_dl := 3;
1301 exp_dl_cs_mcs := MCS_3;
1302 /* Set maximum allowed DL MCS to 4 */
1303 g_mcs_max_dl := 4;
1304 f_pcuvty_set_allowed_cs_mcs();
1305 f_pcuvty_set_link_quality_ranges();
1306
1307 /* Establish BSSGP connection to the PCU */
1308 f_bssgp_establish();
1309 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1310
1311 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001312 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001313 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1314
1315 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1316 f_sleep(X2002);
1317 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1318
1319 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001320 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1321 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 +01001322 f_dl_block_ack_fn(dl_block, poll_fn));
1323
1324 f_shutdown(__BFILE__, __LINE__, final := true);
1325}
1326
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001327/* Verify DL MCS above "mcs max" set by VTY is never used */
1328testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1329 /* Initialize NS/BSSGP side */
1330 f_init_bssgp();
1331 /* Initialize GPRS MS side */
1332 f_init_gprs_ms();
1333
1334 /* Initialize the PCU interface abstraction */
1335 f_init_raw(testcasename());
1336
1337 /* Set maximum allowed DL CS to 3 */
1338 g_mcs_initial_dl := 1;
1339 g_mcs_max_dl := 3;
1340 f_pcuvty_set_allowed_cs_mcs();
1341 f_pcuvty_set_link_quality_ranges();
1342
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001343 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_mcs_max_dl, true), bssgp_ms_racap_egprs_def);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001344}
1345
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001346/* Verify PCU drops TBF after some time of inactivity. */
1347testcase TC_t3141() runs on RAW_PCU_Test_CT {
1348 var PCUIF_info_ind info_ind;
1349 var template (value) TsTrxBtsNum nr;
1350 var BTS_PDTCH_Block data_msg;
1351 var GprsMS ms;
1352 var uint3_t rx_usf;
1353 timer T_3141 := 1.0;
1354 var boolean ul_tbf_usf_req := false;
1355
1356 /* Initialize NS/BSSGP side */
1357 f_init_bssgp();
1358 /* Initialize GPRS MS side */
1359 f_init_gprs_ms();
1360 ms := g_ms[0]; /* We only use first MS in this test */
1361
1362 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1363 /* Only use 1 PDCH to simplify test: */
1364 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1365 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1366 /* Initialize the PCU interface abstraction */
1367 f_init_raw(testcasename(), info_ind);
1368
1369 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1370
1371 /* Establish BSSGP connection to the PCU */
1372 f_bssgp_establish();
1373 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1374
1375 /* Establish a one-phase access Uplink TBF */
1376 f_ms_establish_ul_tbf(ms);
1377
1378 T_3141.start;
1379
1380 /* Now we wait for PCU to transmit our USF */
1381 nr := ts_TsTrxBtsNum;
1382 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1383 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1384 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1385 block_nr := nr.blk_nr));
1386
1387 alt {
1388 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1389 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1390 ?)) -> value data_msg {
1391 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1392 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1393 f_shutdown(__BFILE__, __LINE__);
1394 }
1395
1396 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1397 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1398 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1399 ul_tbf_usf_req := true;
1400 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))
1401 } else if (rx_usf == USF_UNUSED) {
1402 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1403 if (ul_tbf_usf_req) {
1404 /* TBF was dropped by T3141, success */
1405 setverdict(pass);
1406 break;
1407 } else {
1408 log("PCU never requested USF, unexpected");
1409 f_shutdown(__BFILE__, __LINE__);
1410 }
1411 } /* else: Keep waiting for TBF to be active by network */
1412 } else {
1413 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1414 f_shutdown(__BFILE__, __LINE__);
1415 }
1416
1417 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1418 if (match(data_msg.dl_block,
1419 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1420 tr_UlAckNackGprs(tlli := ?,
1421 acknack_desc := ?,
1422 rel99 := *))))
1423 {
1424 log("Received UL ACK/NACK with TLLI set");
1425 f_shutdown(__BFILE__, __LINE__);
1426 }
1427
1428 nr := ts_TsTrxBtsNum;
1429 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1430 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1431 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1432 block_nr := nr.blk_nr));
1433 repeat;
1434 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001435 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1436 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1437 omit)) {
1438 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1439 our last RTS.req because there's no longer any MS listening on
1440 the TS. */
1441 setverdict(pass);
1442 break;
1443 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001444 [] T_3141.timeout {
1445 log("T_3141 expired but TBF is still active, unexpected");
1446 f_shutdown(__BFILE__, __LINE__);
1447 }
1448 [] BTS.receive {
1449 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1450 * because we never sent the TLLI to the PCU */
1451 setverdict(fail, "Unexpected BTS message");
1452 f_shutdown(__BFILE__, __LINE__);
1453 }
1454 }
1455
1456 f_shutdown(__BFILE__, __LINE__, final := true);
1457}
1458
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001459/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1460 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1461 * T3169. See OS#5033 */
1462testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1463 var PCUIF_info_ind info_ind;
1464 var template (value) TsTrxBtsNum nr;
1465 var BTS_PDTCH_Block data_msg;
1466 var GprsMS ms;
1467 var uint3_t rx_usf;
1468 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1469 var integer n3101 := 0;
1470 timer T_3169 := 1.0;
1471
1472 /* Initialize NS/BSSGP side */
1473 f_init_bssgp();
1474 /* Initialize GPRS MS side */
1475 f_init_gprs_ms();
1476 ms := g_ms[0]; /* We only use first MS in this test */
1477
1478 /* Initialize the PCU interface abstraction */
1479 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1480 info_ind.n3101 := N3101_MAX;
1481 info_ind.t3169 := 1;
1482 f_init_raw(testcasename(), info_ind);
1483
1484 /* Establish BSSGP connection to the PCU */
1485 f_bssgp_establish();
1486 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1487
1488 /* Establish UL TBF */
1489 f_ms_establish_ul_tbf(ms);
1490
1491 /* Now we wait for PCU to transmit our USF */
1492 nr := ts_TsTrxBtsNum;
1493 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1494 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1495 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1496 block_nr := nr.blk_nr));
1497
1498 alt {
1499 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1500 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1501 ?)) -> value data_msg {
1502 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1503 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1504 f_shutdown(__BFILE__, __LINE__);
1505 }
1506
1507 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1508 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1509 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1510 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001511 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1512 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001513 f_shutdown(__BFILE__, __LINE__);
1514 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001515 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001516 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1517 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1518 if (not T_3169.running) {
1519 log("T3169 started");
1520 T_3169.start;
1521 }
1522 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1523 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1524 f_shutdown(__BFILE__, __LINE__);
1525 } else {
1526 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1527 }
1528 nr := ts_TsTrxBtsNum;
1529 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1530 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1531 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1532 block_nr := nr.blk_nr));
1533 repeat;
1534 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001535 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1536 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001537 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001538 [] T_3169.timeout {
1539 log("T_3169 expired");
1540 /* Done in alt */
1541 }
1542 [] BTS.receive {
1543 setverdict(fail, "Unexpected BTS message");
1544 f_shutdown(__BFILE__, __LINE__);
1545 }
1546 }
1547
1548 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1549 /* USFs as per previous TBF since they were freed at expiration time: */
1550 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1551 var uint5_t old_tfi := ms.ul_tbf.tfi;
1552 f_ms_establish_ul_tbf(ms);
1553 if (old_tfi != ms.ul_tbf.tfi) {
1554 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1555 f_shutdown(__BFILE__, __LINE__);
1556 }
1557 for (var integer i := 0; i < 8; i := i +1) {
1558 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1559 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1560 f_shutdown(__BFILE__, __LINE__);
1561 }
1562 }
1563
1564 f_shutdown(__BFILE__, __LINE__, final := true);
1565}
1566
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001567
1568/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1569 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1570 the final UL ACK sent at us. */
1571testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1572 var PCUIF_info_ind info_ind;
1573 var BTS_PDTCH_Block data_msg;
1574 var RlcmacDlBlock dl_block;
1575 var uint32_t sched_fn;
1576 var template (value) TsTrxBtsNum nr;
1577 var template RlcmacDlBlock exp_ul_ack;
1578 var template UlAckNackGprs exp_ul_ack_sub;
1579 var GprsMS ms;
1580 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1581 var integer N3103 := 0;
1582 timer T_3169 := 1.0;
1583
1584 /* Initialize GPRS MS side */
1585 f_init_gprs_ms();
1586 ms := g_ms[0]; /* We only use first MS in this test */
1587
1588 /* Initialize the PCU interface abstraction */
1589 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1590 info_ind.n3103 := N3103_MAX;
1591 info_ind.t3169 := 1;
1592 f_init_raw(testcasename(), info_ind);
1593
1594 /* Establish an Uplink TBF */
1595 f_ms_establish_ul_tbf(ms);
1596
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001597 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001598 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1599 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1600
1601 nr := ts_TsTrxBtsNum;
1602 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1603 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1604 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1605 block_nr := nr.blk_nr));
1606 alt {
1607 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1608 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1609 exp_ul_ack)) -> value data_msg {
1610 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1611 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1612 f_shutdown(__BFILE__, __LINE__);
1613 }
1614
1615 nr := ts_TsTrxBtsNum;
1616 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1617 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1618 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1619 block_nr := nr.blk_nr));
1620 N3103 := N3103 + 1;
1621 if (N3103 == N3103_MAX) {
1622 /* At this point in time (N3103_MAX reached), PCU is
1623 * moving the TBF to RELEASE state so no data/ctrl for
1624 * it is tx'ed, hence the dummy blocks: */
1625 T_3169.start;
1626 }
1627 repeat;
1628 }
1629 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1630 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1631 exp_ul_ack)) -> value data_msg {
1632 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1633 f_shutdown(__BFILE__, __LINE__);
1634 }
1635 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001636 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001637 [T_3169.running] T_3169.timeout {
1638 log("T_3169 timeout");
1639 /* Done in alt, wait for pending RTS initiated previously in
1640 * above case before continuing (expect /* Dummy block): */
1641 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1642 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001643 tr_RLCMAC_DL_DUMMY_CTRL));
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001644 }
1645 [] BTS.receive {
1646 setverdict(fail, "Unexpected BTS message");
1647 f_shutdown(__BFILE__, __LINE__);
1648 }
1649 }
1650
1651 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1652 * USFs as per previous TBF since they were freed at expiration time: */
1653 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1654 var uint5_t old_tfi := ms.ul_tbf.tfi;
1655 f_ms_establish_ul_tbf(ms);
1656 if (old_tfi != ms.ul_tbf.tfi) {
1657 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1658 f_shutdown(__BFILE__, __LINE__);
1659 }
1660 for (var integer i := 0; i < 8; i := i +1) {
1661 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1662 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1663 f_shutdown(__BFILE__, __LINE__);
1664 }
1665 }
1666
1667 f_shutdown(__BFILE__, __LINE__, final := true);
1668}
1669
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001670/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1671 * point the TBF is no longer available. In order to get to start of T3191, we
1672 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1673 * until TBF release procedure starts after draining DL queue. */
1674testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1675 var PCUIF_info_ind info_ind;
1676 var RlcmacDlBlock dl_block;
1677 var octetstring data1 := f_rnd_octstring(200);
1678 var octetstring data2 := f_rnd_octstring(10);
1679 var uint32_t dl_fn;
1680 var template (value) TsTrxBtsNum nr;
1681 var BTS_PDTCH_Block data_msg;
1682 var GprsMS ms;
1683
1684 /* Initialize NS/BSSGP side */
1685 f_init_bssgp();
1686 /* Initialize GPRS MS side */
1687 f_init_gprs_ms();
1688 ms := g_ms[0]; /* We only use first MS in this test */
1689
1690 /* Initialize the PCU interface abstraction */
1691 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1692 /* Set timer to 1 sec (default 5) to speedup test: */
1693 info_ind.t3191 := 1;
1694 f_init_raw(testcasename(), info_ind);
1695
1696 /* Establish BSSGP connection to the PCU */
1697 f_bssgp_establish();
1698 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1699
1700 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1701 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1702 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1703
1704 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1705 f_sleep(X2002);
1706
1707 while (true) {
1708 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1709
1710 /* Keep Ack/Nack description updated (except for last BSN) */
1711 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1712
1713 if (f_dl_block_rrbp_valid(dl_block)) {
1714 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1715 f_dl_block_ack_fn(dl_block, dl_fn));
1716 break;
1717 }
1718 }
1719
1720 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1721 nr := ts_TsTrxBtsNum;
1722 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1723 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1724 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1725 block_nr := nr.blk_nr));
1726 alt {
1727 [] as_ms_rx_ignore_dummy(ms, nr);
1728 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1729 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1730 ?)) -> value data_msg {
1731 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1732 log("Received FINAL_ACK");
1733 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1734 break;
1735 }
1736 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1737 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1738 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1739 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1740 }
1741 nr := ts_TsTrxBtsNum;
1742 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1743 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1744 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1745 block_nr := nr.blk_nr));
1746 repeat;
1747 }
1748 [] BTS.receive {
1749 setverdict(fail, "Unexpected BTS message");
1750 f_shutdown(__BFILE__, __LINE__);
1751 }
1752 }
1753
1754 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1755 to time out. We simply sleep instead of requesting blocks because
1756 otherwise retransmissions would keep restarting the timer. */
1757 f_sleep(int2float(info_ind.t3191));
1758
1759 /* The TBF should be freed now, so new data should trigger an Assignment: */
1760 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1761 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1762
1763 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1764 f_sleep(X2002);
1765 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1766 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1767 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1768 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1769 f_dl_block_ack_fn(dl_block, dl_fn));
1770
1771 f_shutdown(__BFILE__, __LINE__, final := true);
1772}
1773
1774/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1775testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1776 var PCUIF_info_ind info_ind;
1777 var RlcmacDlBlock dl_block;
1778 var octetstring data1 := f_rnd_octstring(1400);
1779 var octetstring data2 := f_rnd_octstring(10);
1780 var uint32_t dl_fn;
1781 var GprsMS ms;
1782
1783 /* Initialize NS/BSSGP side */
1784 f_init_bssgp();
1785 /* Initialize GPRS MS side */
1786 f_init_gprs_ms();
1787 ms := g_ms[0]; /* We only use first MS in this test */
1788
1789 /* Initialize the PCU interface abstraction */
1790 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1791 /* Set timer to 1 sec (default 5) to speedup test: */
1792 info_ind.t3191 := 1;
1793 f_init_raw(testcasename(), info_ind);
1794
1795 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1796
1797 /* Establish BSSGP connection to the PCU */
1798 f_bssgp_establish();
1799 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1800
1801 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1802 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1803 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1804
1805 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1806 f_sleep(X2002);
1807
1808 /* Send enough DL data to at least be able to DL ACK once (excl the
1809 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1810 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1811 while (true) {
1812 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1813
1814 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1815 log("Received FINAL_ACK");
1816 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1817 break;
1818 }
1819
1820 /* Keep Ack/Nack description updated (except for last BSN) */
1821 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1822
1823 if (f_dl_block_rrbp_valid(dl_block)) {
1824 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1825 f_dl_block_ack_fn(dl_block, dl_fn));
1826 }
1827 }
1828
1829 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1830 to time out. We simply sleep instead of requesting blocks because
1831 otherwise retransmissions would keep restarting the timer. */
1832 f_sleep(int2float(info_ind.t3191));
1833
1834 /* The TBF should be freed now, so new data should trigger an Assignment: */
1835 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1836 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1837
1838 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1839 f_sleep(X2002);
1840 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1841 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1842 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1843 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1844 f_dl_block_ack_fn(dl_block, dl_fn));
1845
1846 f_shutdown(__BFILE__, __LINE__, final := true);
1847}
1848
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001849/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1850 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1851 * T3193) after DL TBF release */
1852testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001853 var RlcmacDlBlock dl_block;
1854 var octetstring data := f_rnd_octstring(10);
1855 var boolean ok;
1856 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001857 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001858 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001859 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1860
1861 /* Initialize NS/BSSGP side */
1862 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001863 /* Initialize GPRS MS side */
1864 f_init_gprs_ms();
1865 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001866
1867 /* Initialize the PCU interface abstraction */
1868 f_init_raw(testcasename());
1869
1870 /* Establish BSSGP connection to the PCU */
1871 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001872 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001873
1874 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001875 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1876 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001877
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001878 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1879 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001880 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001881
1882 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001883 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1884 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1885 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001886
1887 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001888 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001889 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001890 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001891 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001892
1893 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001894
1895 /* 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 +07001896 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001897 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1898 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1899 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001900
1901 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001902}
1903
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001904/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1905 freed and no longer available. Trigger it by sending DL blocks and never DL
1906 ACKing the data (which are requested through RRBP) */
1907testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1908 var PCUIF_info_ind info_ind;
1909 var RlcmacDlBlock dl_block;
1910 var octetstring data1 := f_rnd_octstring(1000);
1911 var octetstring data2 := f_rnd_octstring(10);
1912 var uint32_t dl_fn;
1913 var template (value) TsTrxBtsNum nr;
1914 var BTS_PDTCH_Block data_msg;
1915 var GprsMS ms;
1916 const integer N3105_MAX := 2;
1917 var integer N3105 := 0;
1918 timer T_3195 := 1.0;
1919 var integer num_poll_recv := 0;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001920 var template RlcmacDlBlock dl_block_exp;
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001921
1922 /* Initialize NS/BSSGP side */
1923 f_init_bssgp();
1924 /* Initialize GPRS MS side */
1925 f_init_gprs_ms();
1926 ms := g_ms[0]; /* We only use first MS in this test */
1927
1928 /* Initialize the PCU interface abstraction */
1929 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1930 /* Speedup test: */
1931 info_ind.n3105 := N3105_MAX;
1932 info_ind.t3195 := 1;
1933 f_init_raw(testcasename(), info_ind);
1934
1935 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1936 * MS and retransmitted after the TBF is released and later on created
1937 * (because the MS is reused) */
1938 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1939
1940 /* Establish BSSGP connection to the PCU */
1941 f_bssgp_establish();
1942 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1943
1944 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1945 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1946 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1947
1948 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1949 f_sleep(X2002);
1950
1951 /* Now we go on receiving DL data and not answering RRBP: */
1952 nr := ts_TsTrxBtsNum;
1953 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1954 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1955 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1956 block_nr := nr.blk_nr));
1957 alt {
1958 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1959 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1960 tr_RLCMAC_DATA)) -> value data_msg {
1961 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1962 if (num_poll_recv == 0) {
1963 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1964 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1965 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1966 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1967 } else {
1968 log("Ignoring RRBP ", num_poll_recv);
1969 N3105 := N3105 + 1;
1970 }
1971 num_poll_recv := num_poll_recv + 1;
1972 }
1973
1974 nr := ts_TsTrxBtsNum;
1975 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1976 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1977 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1978 block_nr := nr.blk_nr));
1979 repeat;
1980 }
1981 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001982 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001983 */
1984 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1985 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07001986 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001987 if (not T_3195.running) {
1988 T_3195.start;
1989 /* We even send some new data, nothing should be sent to MS */
1990 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1991 }
1992 nr := ts_TsTrxBtsNum;
1993 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1994 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1995 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1996 block_nr := nr.blk_nr));
1997 repeat;
1998 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01001999 /* We may already receive idle blocks before our own TTCN3 timer
2000 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002001 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002002 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002003 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002004 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002005 * above case before continuing (expect empty block): */
2006 dl_block_exp := omit;
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002007 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2008 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002009 dl_block_exp));
2010 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002011 [] BTS.receive {
2012 setverdict(fail, "Unexpected BTS message");
2013 f_shutdown(__BFILE__, __LINE__);
2014 }
2015 }
2016
2017 /* after T_3195 timeout, TBF is released */
2018 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
2019 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2020
2021 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2022 f_sleep(X2002);
2023 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2024
2025 /* ACK the DL block */
2026 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2027 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2028 f_dl_block_ack_fn(dl_block, dl_fn));
2029
2030 f_shutdown(__BFILE__, __LINE__, final := true);
2031}
2032
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002033/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2034function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2035 var PCUIF_info_ind info_ind;
2036 var template IARRestOctets rest;
2037 var BIT11 ra11;
2038 var GprsMS ms;
2039 var octetstring data := f_rnd_octstring(10);
2040 var RlcmacDlBlock dl_block;
2041 var template RlcmacDlBlock rej_tmpl;
2042 var uint32_t dl_fn;
2043 var uint32_t sched_fn;
2044 var uint8_t wait_ind_val;
2045
2046 /* Initialize NS/BSSGP side */
2047 f_init_bssgp();
2048 /* Initialize GPRS MS side */
2049 f_init_gprs_ms();
2050 ms := g_ms[0]; /* We only use first MS in this test */
2051
2052 info_ind := valueof(ts_PCUIF_INFO_default);
2053
2054 /* Only the first TRX is enabled. */
2055 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2056 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2057
2058 /* Initialize the PCU interface abstraction */
2059 f_init_raw(testcasename(), info_ind);
2060
2061 f_pcuvty_set_timer(3172, t3172_ms);
2062
2063 /* Establish BSSGP connection to the PCU */
2064 f_bssgp_establish();
2065 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2066
2067 var EGPRSPktChRequest req := {
2068 one_phase := {
2069 tag := '0'B,
2070 multislot_class := '10101'B,
2071 priority := '01'B,
2072 random_bits := '101'B
2073 }
2074 };
2075
2076 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2077 for (var integer i := 0; i < 7; i := i + 1) {
2078 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2079 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2080 }
2081
2082 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2083 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2084 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2085
2086 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2087 f_sleep(X2002);
2088 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2089
2090 /* ACK the DL block */
2091 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2092 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2093 f_dl_block_ack_fn(dl_block, dl_fn));
2094
2095 /* Since all USF are taken, we should receive a Reject: */
2096
2097 if (wait_ind_size == '0'B) {
2098 wait_ind_val := t3172_ms / 1000;
2099 } else {
2100 wait_ind_val := t3172_ms / 20;
2101 }
2102 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2103 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2104 wait_ind_val,
2105 wait_ind_size)));
2106 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2107 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2108 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2109 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2110 block_nr := nr.blk_nr));
2111 alt {
2112 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2113 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2114 rej_tmpl));
2115 [] BTS.receive {
2116 setverdict(fail, "Unexpected BTS message");
2117 f_shutdown(__BFILE__, __LINE__);
2118 }
2119 }
2120 f_shutdown(__BFILE__, __LINE__, final := true);
2121}
2122testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2123 /* size=0 means value is provided in seconds. Due to value being 8
2124 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2125 * = 5100. Hence, values above it should use size=0 to be able to
2126 * provide values in range. Let's use 6 seconds, 6000ms
2127 */
2128 f_TC_t3172(6000, '0'B);
2129}
2130testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2131 f_TC_t3172(3000, '1'B);
2132}
2133
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002134/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2135testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002136 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002137 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002138 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002139 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002140
2141 /* Initialize NS/BSSGP side */
2142 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002143 /* Initialize GPRS MS side */
2144 f_init_gprs_ms();
2145 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002146
2147 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002148 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002149
2150 /* Establish BSSGP connection to the PCU */
2151 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002152 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002153
2154 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002155 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002156
2157 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002158 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002159 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002160 /* 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 +02002161 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 +02002162 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2163 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002164 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002165
2166 /* Send enough blocks to test whole procedure: Until Nth block
2167 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2168 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002169 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
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 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002175 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 +07002176
2177 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002178}
2179
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002180/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2181testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2182 var RlcmacDlBlock dl_block;
2183 var uint32_t dl_fn, sched_fn;
2184 var octetstring payload;
2185 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002186 var template (value) LlcBlockHdr blk_hdr;
2187 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002188 var integer blk_len;
2189 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002190 var GprsMS ms;
2191
2192 /* Initialize NS/BSSGP side */
2193 f_init_bssgp();
2194 /* Initialize GPRS MS side */
2195 f_init_gprs_ms();
2196 ms := g_ms[0]; /* We only use first MS in this test */
2197
2198 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002199 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002200
2201 /* Establish BSSGP connection to the PCU */
2202 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002203 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002204
2205 /* Establish an Uplink TBF */
2206 f_ms_establish_ul_tbf(ms);
2207
2208 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002209 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002210 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002211 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2212 more := false, e := true);
2213 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002214 /* 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 +01002215 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2216 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002217 cv := 15,
2218 bsn := ms.ul_tbf.bsn,
2219 blocks := blocks,
2220 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002221 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002222 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002223
2224 /* ACK and check it was received fine */
2225 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2226 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2227 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2228 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002229 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 +02002230
2231 /* Test sending LLC PDUS of incrementing size */
2232 var integer max_size := 49;
2233 for (var integer i := 1; i <= max_size; i := i + 1) {
2234 var integer cv;
2235 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2236 log("Sending DATA.ind with LLC payload size ", i);
2237 if (i < max_size - g_bs_cv_max) {
2238 cv := 15;
2239 } else {
2240 cv := max_size - i;
2241 }
2242
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002243 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2244 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002245 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002246 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2247 more := false, e := true);
2248 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002249 /* 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 +01002250 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2251 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002252 cv := cv,
2253 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002254 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002255 f_ultbf_inc_bsn(ms.ul_tbf);
2256 f_ms_tx_ul_block(ms, ul_data);
2257
2258 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002259 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 +02002260
2261 /* we will receive UL ACK/NACK from time to time, handle it. */
2262 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07002263 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002264 continue;
2265 }
2266 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2267 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2268 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2269 f_shutdown(__BFILE__, __LINE__);
2270 }
2271
2272 log("Rx Packet Uplink ACK / NACK");
2273 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2274 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2275 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2276 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002277
2278 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002279}
2280
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002281function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2282 var octetstring payload;
2283 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002284 var template (value) LlcBlockHdr blk_hdr;
2285 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002286 var integer block_len, max_valid_data_len;
2287 timer T;
2288
2289 block_len := f_rlcmac_cs_mcs2block_len(cs);
2290 /* We need to send with TLLI since we are in One-Phase Access Contenion
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002291 * resolution), so that's -4 bytes of data, -3 for headers, -1 for LI
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002292 * indicator, -1 for spare bits octet at the end */
2293 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2294 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 +07002295 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2296 more := false, e := true);
2297 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002298 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2299 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002300 cv := cv,
2301 bsn := ms.ul_tbf.bsn,
2302 blocks := blocks,
2303 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002304 f_ultbf_inc_bsn(ms.ul_tbf);
2305 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2306
2307 T.start(0.5);
2308 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002309 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002310 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2311 f_shutdown(__BFILE__, __LINE__);
2312 }
2313 [] T.timeout {
2314 setverdict(pass);
2315 }
2316 }
2317}
2318/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2319 blocks intentionally contain last byte of data placed in last byte of RLC
2320 containing padding/spare bits, which is incorrect. Spare bits exist and are
2321 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2322 discounting padding in octet" */
2323testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2324 var GprsMS ms;
2325 var integer block_len, max_valid_data_len;
2326
2327 /* Initialize NS/BSSGP side */
2328 f_init_bssgp();
2329 /* Initialize GPRS MS side */
2330 f_init_gprs_ms();
2331 ms := g_ms[0]; /* We only use first MS in this test */
2332
2333 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002334 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002335
2336 /* Establish BSSGP connection to the PCU */
2337 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002338 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002339
2340 /* Establish an Uplink TBF */
2341 f_ms_establish_ul_tbf(ms);
2342
2343 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2344 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2345 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2346
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002347 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002348}
2349
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002350/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2351 * answered, so TBFs for uplink and later for downlink are created.
2352 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002353private 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 +02002354 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002355 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002356 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002357 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002358 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002359
2360 /* Initialize NS/BSSGP side */
2361 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002362 /* Initialize GPRS MS side */
2363 f_init_gprs_ms();
2364 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002365
2366 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002367 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002368
2369 /* Establish BSSGP connection to the PCU */
2370 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002371 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002372
2373 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002374 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002375
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002376 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002377 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002378 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 +02002379 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2380 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002381 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002382
2383 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002384 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002385
2386 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002387 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2388 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002389
2390 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2391 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002392 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002393
2394 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002395 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2396 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2397 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002398
2399 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002400}
2401
2402/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2403 * answered, so TBFs for uplink and later for downlink are created.
2404 */
2405testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002406 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002407 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002408}
2409
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002410/* 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 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002413private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2414 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002415 template (present) CodingScheme exp_ul_cs_mcs := ?,
2416 template (present) CodingScheme exp_dl_cs_mcs := ?)
2417runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002418 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002419 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002420 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002421 var uint32_t sched_fn;
2422 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002423 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002424 var GprsMS ms;
2425
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002426 /* Initialize NS/BSSGP side */
2427 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002428 /* Initialize GPRS MS side */
2429 f_init_gprs_ms();
2430 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002431
2432 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002433 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002434
2435 /* Establish BSSGP connection to the PCU */
2436 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002437 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002438
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002439 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2440 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 +02002441
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002442 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2443 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 +02002444 f_shutdown(__BFILE__, __LINE__);
2445 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002446
2447 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2448 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002449 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002450
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002451 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002452 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 +02002453
2454 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002455 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002456
2457 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002458 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002459 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2460 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002461 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002462 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002463 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002464
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002465 /* PCU acks the UL data after having received CV=0) */
2466 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2467
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002468 /* 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 +02002469 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 +02002470
2471 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002472 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2473 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 +02002474 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002475
2476 f_shutdown(__BFILE__, __LINE__, final := true);
2477}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002478
2479testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002480 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2481 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002482
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002483 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 +01002484
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002485 var StatsDExpects expect := {
2486 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2487 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2488 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2489 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2490 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2491 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2492 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2493 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2494 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2495 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2496 };
2497 f_statsd_expect(expect);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002498}
2499
2500testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002501 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2502 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002503
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002504 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 +01002505
2506 var StatsDExpects expect := {
2507 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2508 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2509 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2510 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2511 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2512 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2513 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2514 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2515 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2516 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2517 };
2518 f_statsd_expect(expect);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002519}
2520
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002521testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2522 /* Configure PCU to force two phase access */
2523 g_force_two_phase_access := true;
2524
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002525 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002526 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002527
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002528 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 +01002529
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002530 var StatsDExpects expect := {
2531 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2532 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2533 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2534 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2535 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2536 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2537 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2538 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2539 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2540 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2541 };
2542 f_statsd_expect(expect);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002543}
2544
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002545/* Test scenario where SGSN wants to send some data against MS and it is
2546 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2547 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002548private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2549 template (present) CodingScheme exp_cs_mcs := ?)
2550runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002551 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002552 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002553 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002554 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002555 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002556
2557 /* Initialize NS/BSSGP side */
2558 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002559 /* Initialize GPRS MS side */
2560 f_init_gprs_ms();
2561 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002562
2563 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002564 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002565
2566 /* Establish BSSGP connection to the PCU */
2567 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002568 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002569
2570 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002571 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2572 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002573
2574 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2575 f_sleep(X2002);
Pau Espin Pedrol3f2b5e42022-11-29 14:54:34 +01002576 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2577 dl_fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
2578
2579 f_rlcmac_dl_block_exp_data(dl_block, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002580
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002581 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002582 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2583 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 +02002584 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002585
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002586 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002587 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002588
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002589 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002590 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002591 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002592 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2593 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002594 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002595
2596 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002597 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002598
2599 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002600}
2601
2602testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002603 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002604 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2605}
2606
2607/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2608/* information about the MS */
2609testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002610 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002611 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002612}
2613
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002614/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2615 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2616 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2617 * be transferred).
2618 */
2619testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002620 var RlcmacDlBlock dl_block;
2621 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002622 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002623 var octetstring total_payload;
2624 var octetstring payload;
2625 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002626 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002627 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002628 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002629
2630 /* Initialize NS/BSSGP side */
2631 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002632 /* Initialize GPRS MS side */
2633 f_init_gprs_ms();
2634 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002635
2636 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002637 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002638
2639 /* Establish BSSGP connection to the PCU */
2640 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002641 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002642
2643 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002644 f_ms_establish_ul_tbf(ms);
2645 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002646
2647 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02002648 contention resolution) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002649 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 +02002650 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 +02002651
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002652 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2653 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002654 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002655 total_payload := payload;
2656
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002657 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2658
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002659 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002660 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002661 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002662 total_payload := total_payload & payload;
2663
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002664 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002665 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002666 total_payload := total_payload & payload;
2667
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002668 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002669 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 +02002670 total_payload := total_payload & lost_payload;
2671
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002672 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002673 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002674 total_payload := total_payload & payload;
2675
2676 /* 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 +02002677 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002678
2679 /* On CV=0, we'll receive a UL ACK asking about missing block */
2680 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2681 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002682 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2683 tfi := tfi,
2684 cv := 15,
2685 bsn := 3,
2686 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002687 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002688
2689 /* Now final ack is recieved */
2690 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2691 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002692 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002693
2694 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002695 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 +07002696
2697 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002698}
2699
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002700/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2701 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2702 * timeout occurs (specified by sent RRBP on DL block). */
2703testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002704 var RlcmacDlBlock dl_block;
2705 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002706 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002707 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002708
2709 /* Initialize NS/BSSGP side */
2710 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002711 /* Initialize GPRS MS side */
2712 f_init_gprs_ms();
2713 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002714
2715 /* Initialize the PCU interface abstraction */
2716 f_init_raw(testcasename());
2717
2718 /* Establish BSSGP connection to the PCU */
2719 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002720 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002721
2722 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002723 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2724 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002725
2726 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2727 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002728 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002729
2730 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2731 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2732 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002733 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002734
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002735 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2736 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002737 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002738
2739 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002740 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2741 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2742 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002743
2744 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002745}
2746
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002747/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2748testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2749 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2750 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002751 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002752 var RlcmacDlBlock dl_block;
2753 var uint32_t ack_fn;
2754 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002755 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002756 timer T := 5.0;
2757
2758 /* Initialize NS/BSSGP side */
2759 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002760 /* Initialize GPRS MS side */
2761 f_init_gprs_ms();
2762 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002763
2764 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002765 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002766
Daniel Willmann535aea62020-09-21 13:27:08 +02002767 f_statsd_reset();
2768
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002769 /* Establish BSSGP connection to the PCU */
2770 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002771 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002772
2773 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002774 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2775 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002776
2777 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2778 f_sleep(X2002);
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002779 /* Skip potential dummy blocks before X2002 triggers at PCU after us: */
2780 fn := f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002781
2782 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
Pau Espin Pedrol45b98aa2022-11-29 14:50:39 +01002783 f_rlcmac_dl_block_exp_data(dl_block, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002784 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002785
2786 /* TDMA frame number on which we are supposed to send the ACK */
2787 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2788
2789 /* SGSN sends more blocks during the indicated RRBP */
2790 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2791 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002792 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002793
2794 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2795
2796 /* Make sure this block has the same TFI as was assigned
2797 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002798 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002799 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2800 dl_block.data.mac_hdr.hdr_ext.tfi);
2801 f_shutdown(__BFILE__, __LINE__);
2802 }
2803
2804 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002805 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002806
2807 /* Break if this is the end of RRBP */
2808 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002809 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002810 break;
2811 }
2812 }
2813
2814 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002815 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 +07002816
2817 /* Make sure that the next block (after the Ack) is dummy */
2818 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2819
Daniel Willmann535aea62020-09-21 13:27:08 +02002820 var StatsDExpects expect := {
2821 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2822 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2823 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2824 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2825 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002826 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002827 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2828 };
2829 f_statsd_expect(expect);
2830
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002831 f_shutdown(__BFILE__, __LINE__, final := true);
2832}
2833
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002834/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2835 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2836 * Check "3GPP TS 44.060" Annex B. */
2837testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2838 var RlcmacDlBlock dl_block;
2839 var octetstring dataA := f_rnd_octstring(20);
2840 var octetstring dataB := f_rnd_octstring(13);
2841 var octetstring dataC := f_rnd_octstring(3);
2842 var octetstring dataD := f_rnd_octstring(12);
2843 var uint32_t sched_fn;
2844 var GprsMS ms;
2845 var template (value) RlcmacUlBlock ul_data;
2846
2847 /* Initialize NS/BSSGP side */
2848 f_init_bssgp();
2849 /* Initialize GPRS MS side */
2850 f_init_gprs_ms();
2851 ms := g_ms[0]; /* We only use first MS in this test */
2852
2853 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002854 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002855
2856 /* Establish BSSGP connection to the PCU */
2857 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002858 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002859
2860 /* Establish an Uplink TBF */
2861 f_ms_establish_ul_tbf(ms);
2862
2863 /* Summary of what's transmitted:
2864 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2865 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2866 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2867 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2868 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2869 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2870 */
2871
2872 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002873 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2874 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002875 cv := 3,
2876 bsn := ms.ul_tbf.bsn,
2877 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2878 tlli := ms.tlli);
2879 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2880 * RLCMAC block being sent. */
2881 ul_data.data.mac_hdr.e := true;
2882 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002883 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002884
2885 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002886 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2887 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002888 cv := 2,
2889 bsn := ms.ul_tbf.bsn,
2890 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2891 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2892 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2893 },
2894 tlli := ms.tlli);
2895 f_ultbf_inc_bsn(ms.ul_tbf);
2896 f_ms_tx_ul_block(ms, ul_data);
2897
2898 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002899 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 +02002900
2901 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002902 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2903 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002904 cv := 1,
2905 bsn := ms.ul_tbf.bsn,
2906 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2907 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2908 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2909 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2910 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2911 },
2912 tlli := ms.tlli);
2913 f_ultbf_inc_bsn(ms.ul_tbf);
2914 f_ms_tx_ul_block(ms, ul_data);
2915
2916 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002917 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2918 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 +02002919
2920 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002921 ul_data := t_RLCMAC_UL_DATA_TLLI(
2922 cs := CS_1,
2923 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002924 cv := 0,
2925 bsn := ms.ul_tbf.bsn,
2926 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2927 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2928 },
2929 tlli := ms.tlli);
2930 f_ultbf_inc_bsn(ms.ul_tbf);
2931 f_ms_tx_ul_block(ms, ul_data);
2932
2933 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002934 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 +02002935
2936 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2937 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2938 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2939
2940 f_shutdown(__BFILE__, __LINE__, final := true);
2941}
2942
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002943/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2944 * ACK/NACK is not answered */
2945testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2946 var RlcmacDlBlock dl_block;
2947 var octetstring data1 := f_rnd_octstring(200);
2948 var octetstring data2 := f_rnd_octstring(10);
2949 var uint32_t dl_fn;
2950 var GprsMS ms;
2951 var template (value) TsTrxBtsNum nr;
2952 var BTS_PDTCH_Block data_msg;
2953
2954 /* Initialize NS/BSSGP side */
2955 f_init_bssgp();
2956 /* Initialize GPRS MS side */
2957 f_init_gprs_ms();
2958 ms := g_ms[0]; /* We only use first MS in this test */
2959
2960 /* Initialize the PCU interface abstraction */
2961 f_init_raw(testcasename())
2962
2963 /* Establish BSSGP connection to the PCU */
2964 f_bssgp_establish();
2965 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2966
2967 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2968 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2969 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2970
2971 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2972 f_sleep(X2002);
2973
2974 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2975 while (true) {
2976 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2977
2978 /* Keep Ack/Nack description updated (except for last BSN) */
2979 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2980
2981 if (f_dl_block_rrbp_valid(dl_block)) {
2982 /* Don't transmit DL ACK here on purpose ignore it */
2983 break;
2984 }
2985 }
2986
2987 /* PCU starts whole process again */
2988 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2989
2990 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2991 f_sleep(X2002);
2992
2993 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
2994 /* DL data), after that we receive only DUMMY blocks so we are done */
2995 var boolean data_received := false;
2996 nr := ts_TsTrxBtsNum;
2997 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2998 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2999 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3000 block_nr := nr.blk_nr));
3001 alt {
3002 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3003 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003004 tr_RLCMAC_DL_DUMMY_CTRL)) { /* done */ }
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01003005 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3006 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3007 tr_RLCMAC_DATA)) -> value data_msg {
3008 data_received := true;
3009 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3010 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3011 log("Received FINAL_ACK");
3012 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3013 }
3014 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3015 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3016 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3017 }
3018 nr := ts_TsTrxBtsNum;
3019 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3020 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3021 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3022 block_nr := nr.blk_nr));
3023 repeat;
3024 }
3025 [] BTS.receive {
3026 setverdict(fail, "Unexpected BTS message");
3027 f_shutdown(__BFILE__, __LINE__);
3028 }
3029 }
3030
3031 f_shutdown(__BFILE__, __LINE__, final := true);
3032}
3033
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003034/* OS#5508: Verify scheduling of LLC frames with SAPI=1 (GMM) takes precedence
3035 * over SAPI2/7/8 which in turn take prececende over others */
3036testcase TC_dl_llc_sapi_priority() runs on RAW_PCU_Test_CT {
3037 var octetstring data_sapi1 := f_pad_oct('01'O, 19, 'ff'O);
3038 var octetstring data_sapi2 := f_pad_oct('02'O, 19, 'ff'O);
3039 var octetstring data_sapi7 := f_pad_oct('07'O, 19, 'ff'O);
3040 var octetstring data_sapi8 := f_pad_oct('08'O, 19, 'ff'O);
3041 var octetstring data_sapi_other := f_pad_oct('03'O, 19, 'ff'O);
3042 var RlcmacDlBlock dl_block;
3043 var uint32_t dl_fn;
3044 var GprsMS ms;
3045 var integer state := 1;
3046
3047 /* Initialize NS/BSSGP side */
3048 f_init_bssgp();
3049 /* Initialize GPRS MS side */
3050 f_init_gprs_ms();
3051 ms := g_ms[0]; /* We only use first MS in this test */
3052
3053 /* Initialize the PCU interface abstraction */
3054 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3055
3056 /* Lock to CS1 to keep same DL RLCMAC data block size: */
3057 g_cs_initial_dl := 1;
3058 g_mcs_max_dl := 1;
3059 f_pcuvty_set_allowed_cs_mcs();
3060
3061 /* Establish BSSGP connection to the PCU */
3062 f_bssgp_establish();
3063 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3064
3065 /* SGSN sends some low prio DL data, PCU will page on CCCH (PCH) */
3066 for (var integer i := 0; i < 10; i := i + 1) {
3067 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi_other));
3068 }
3069 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi2));
3070 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi7));
3071 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi8));
3072 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi1));
3073 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3074
3075 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3076 f_sleep(X2002);
3077
3078 while (state != 0) {
3079 var OCT1 rx_sapi;
3080 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3081 rx_sapi := dl_block.data.blocks[0].payload[0];
3082
3083 select (state) {
3084 case(1) { /* We expect the first GMM LLC frame here (SAPI=1, highest prio) */
3085 if (rx_sapi != '01'O) {
3086 setverdict(fail, "Wrong prio: Expected LLC SAPI 1 (GMM) but got ", rx_sapi);
3087 f_shutdown(__BFILE__, __LINE__);
3088 }
3089 state := 2;
3090 }
3091 case(2) { /* We expect the second LLC frame here (SAPI=2, middle prio) */
3092 if (rx_sapi != '02'O) {
3093 setverdict(fail, "Wrong prio: Expected LLC SAPI 2 but got ", rx_sapi);
3094 f_shutdown(__BFILE__, __LINE__);
3095 }
3096 state := 7;
3097 }
3098 case(7) { /* We expect the third LLC frame here (SAPI=7, middle prio) */
3099 if (rx_sapi != '07'O) {
3100 setverdict(fail, "Wrong prio: Expected LLC SAPI 7 but got ", rx_sapi);
3101 f_shutdown(__BFILE__, __LINE__);
3102 }
3103 state := 8;
3104 }
3105 case(8) { /* We expect the fourth LLC frame here (SAPI=8, middle prio) */
3106 if (rx_sapi != '08'O) {
3107 setverdict(fail, "Wrong prio: Expected LLC SAPI 8 but got ", rx_sapi);
3108 f_shutdown(__BFILE__, __LINE__);
3109 }
3110 state := 3;
3111 }
3112 case(3) { /* We expect the other LLC frame here (SAPI=3, lower prio) */
3113 if (rx_sapi != '03'O) {
3114 setverdict(fail, "Wrong prio: Expected LLC SAPI 3 but got ", rx_sapi);
3115 f_shutdown(__BFILE__, __LINE__);
3116 }
3117 state := 0; /* Done, break */
3118 }
3119 }
3120 /* Keep Ack/Nack description updated (except for last BSN) */
3121 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3122
3123 if (f_dl_block_rrbp_valid(dl_block)) {
3124 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3125 f_dl_block_ack_fn(dl_block, dl_fn));
3126 }
3127 }
3128
3129 f_shutdown(__BFILE__, __LINE__, final := true);
3130}
3131
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003132/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3133testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003134 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003135 var octetstring data := f_rnd_octstring(10);
3136 var PacketDlAssign dl_tbf_ass;
3137 var RlcmacDlBlock dl_block;
3138 var uint32_t poll_fn;
3139 var uint32_t sched_fn;
3140 var GprsMS ms;
3141 timer T := 5.0;
3142
3143 /* Initialize NS/BSSGP side */
3144 f_init_bssgp();
3145 /* Initialize GPRS MS side */
3146 f_init_gprs_ms();
3147 ms := g_ms[0]; /* We only use first MS in this test */
3148
3149 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003150 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3151 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003152
3153 /* Initialize the PCU interface abstraction */
3154 f_init_raw(testcasename(), info_ind);
3155
3156 /* Establish BSSGP connection to the PCU */
3157 f_bssgp_establish();
3158 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3159
3160 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3161 through PDCH (no multiblock assignment possible through PCH) */
3162 f_ms_establish_ul_tbf(ms);
3163
3164 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003165 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003166 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
3167 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003168 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3169 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3170
3171 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3172 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3173 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3174 gprsextendeddynalloccap := '0'B
3175 };
3176 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3177 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3178 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3179 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3180 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3181 f_shutdown(__BFILE__, __LINE__);
3182 }
3183 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3184
3185 f_shutdown(__BFILE__, __LINE__, final := true);
3186}
3187
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003188testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003189 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003190 var RlcmacDlBlock dl_block;
3191 var octetstring data := f_rnd_octstring(10);
3192 var PollFnCtx pollctx;
3193 var uint32_t sched_fn;
3194 var GprsMS ms;
3195
3196 var MultislotCap_GPRS mscap_gprs := {
3197 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3198 gprsextendeddynalloccap := '0'B
3199 };
3200 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3201
3202
3203 /* Initialize NS/BSSGP side */
3204 f_init_bssgp();
3205 /* Initialize GPRS MS side */
3206 f_init_gprs_ms();
3207 ms := g_ms[0]; /* We only use first MS in this test */
3208
3209 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003210 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3211 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003212
3213 /* Initialize the PCU interface abstraction */
3214 f_init_raw(testcasename(), info_ind);
3215
3216 /* Establish BSSGP connection to the PCU */
3217 f_bssgp_establish();
3218 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3219
3220 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3221 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3222
3223 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3224 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3225
3226 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3227 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3228 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3229 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3230 f_shutdown(__BFILE__, __LINE__);
3231 }
3232 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3233
3234 f_shutdown(__BFILE__, __LINE__, final := true);
3235}
3236
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003237testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3238 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3239 var RlcmacDlBlock dl_block;
3240 var octetstring data := f_rnd_octstring(10);
3241 var PollFnCtx pollctx;
3242 var uint32_t sched_fn;
3243 var GprsMS ms;
3244
3245 var MultislotCap_GPRS mscap_gprs := {
3246 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3247 gprsextendeddynalloccap := '0'B
3248 };
3249 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3250
3251
3252 /* Initialize NS/BSSGP side */
3253 f_init_bssgp();
3254 /* Initialize GPRS MS side */
3255 f_init_gprs_ms();
3256 ms := g_ms[0]; /* We only use first MS in this test */
3257
3258 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003259 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3260 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003261
3262 /* Initialize the PCU interface abstraction */
3263 f_init_raw(testcasename(), info_ind);
3264
3265 /* Establish BSSGP connection to the PCU */
3266 f_bssgp_establish();
3267 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3268
3269 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3270 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3271
3272 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3273 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3274 f_shutdown(__BFILE__, __LINE__);
3275 }
3276
3277 f_shutdown(__BFILE__, __LINE__, final := true);
3278}
3279
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003280/* Test scenario where MS wants to request a new TBF once the current one is
3281 * ending, by means of sending a Packet Resource Request on ul slot provided by
3282 * last Pkt Ul ACK's RRBP.
3283 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3284testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003285 var RlcmacDlBlock dl_block;
3286 var octetstring data := f_rnd_octstring(10);
3287 var uint32_t sched_fn;
3288 var uint32_t dl_fn;
3289 var template RlcmacDlBlock acknack_tmpl;
3290 var GprsMS ms;
3291
3292 /* Initialize NS/BSSGP side */
3293 f_init_bssgp();
3294 /* Initialize GPRS MS side */
3295 f_init_gprs_ms();
3296 ms := g_ms[0]; /* We only use first MS in this test */
3297
3298 /* Initialize the PCU interface abstraction */
3299 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003300 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003301
3302 /* Establish BSSGP connection to the PCU */
3303 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003304 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003305
3306 /* Establish an Uplink TBF */
3307 f_ms_establish_ul_tbf(ms);
3308
3309 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003310 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003311 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 +02003312
3313 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003314 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003315
3316 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3317 tr_UlAckNackGprs(ms.tlli,
3318 tr_AckNackDescription(final_ack := '1'B),
3319 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3320 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3321
3322 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3323
3324 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003325 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 +07003326 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003327 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3328 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3329
3330 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3331 and make sure it is ACKED fine */
3332 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3333
3334 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003335 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003336
3337 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3338 /* ACK the ACK */
3339 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3340
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003341 var StatsDExpects expect := {
3342 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3343 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3344 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3345 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3346 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3347 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3348 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3349 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3350 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3351 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3352 };
3353 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003354
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003355 f_shutdown(__BFILE__, __LINE__, final := true);
3356}
3357
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003358/* Test scenario where MS wants to request a new TBF once the current one is
3359 * ending, by means of sending a Packet Resource Request on ul slot provided by
3360 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3361 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3362testcase TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() runs on RAW_PCU_Test_CT {
3363 var PCUIF_info_ind info_ind;
3364 var RlcmacDlBlock dl_block;
3365 var octetstring data := f_rnd_octstring(10);
3366 var uint32_t sched_fn;
3367 var uint32_t dl_fn;
3368 var template (value) TsTrxBtsNum nr;
3369 var BTS_PDTCH_Block data_msg;
3370 var template RlcmacDlBlock acknack_tmpl;
3371 var GprsMS ms;
3372 const integer N3105_MAX := 2;
3373 var integer N3105 := 0;
3374 timer T_3195 := 1.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
3375
3376 /* Initialize NS/BSSGP side */
3377 f_init_bssgp();
3378 /* Initialize GPRS MS side */
3379 f_init_gprs_ms();
3380 ms := g_ms[0]; /* We only use first MS in this test */
3381
3382 /* Initialize the PCU interface abstraction */
3383 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3384 /* Speedup test: */
3385 info_ind.n3105 := N3105_MAX;
3386 info_ind.t3195 := 1;
3387 f_init_raw(testcasename(), info_ind);
3388
3389 /* Establish BSSGP connection to the PCU */
3390 f_bssgp_establish();
3391 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3392
3393 /* Establish an Uplink TBF */
3394 f_ms_establish_ul_tbf(ms);
3395
3396 /* Send one UL block (with TLLI since we are in One-Phase Access
Pau Espin Pedrol15b2b942022-10-28 15:08:44 +02003397 contention resolution) and make sure it is ACKED fine */
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003398 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3399
3400 /* UL block should be received in SGSN */
3401 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3402
3403 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3404 tr_UlAckNackGprs(ms.tlli,
3405 tr_AckNackDescription(final_ack := '1'B),
3406 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3407 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3408
3409 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3410
3411 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
3412 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3413
3414 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3415 /* Now we go on receiving DL data and not answering RRBP: */
3416 nr := ts_TsTrxBtsNum;
3417 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3418 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3419 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3420 block_nr := nr.blk_nr));
3421 alt {
3422 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3423 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3424 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
3425 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3426 log("Ignoring RRBP N3105 ", N3105);
3427 N3105 := N3105 + 1;
3428 }
3429 nr := ts_TsTrxBtsNum;
3430 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3431 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3432 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3433 block_nr := nr.blk_nr));
3434 repeat;
3435 }
3436 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
3437 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
3438 */
3439 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3440 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003441 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003442 if (not T_3195.running) {
3443 T_3195.start;
3444 }
3445 nr := ts_TsTrxBtsNum;
3446 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3447 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3448 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3449 block_nr := nr.blk_nr));
3450 repeat;
3451 }
3452 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3453 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3454 omit)) -> value data_msg {
3455 /* We may already receive idle blocks before our own TTCN3 timer
3456 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
3457 nr := ts_TsTrxBtsNum;
3458 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3459 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3460 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3461 block_nr := nr.blk_nr));
3462 repeat;
3463 }
3464 /* We receive Dummy blocks in between Pkt Ul Ass while PCU waits for us to ack it */
3465 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3466 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07003467 tr_RLCMAC_DL_DUMMY_CTRL)) -> value data_msg {
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003468 log("Ignoring Dummy block FN ", data_msg.raw.fn);
3469 nr := ts_TsTrxBtsNum;
3470 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3471 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3472 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3473 block_nr := nr.blk_nr));
3474 repeat;
3475 }
3476 [T_3195.running] T_3195.timeout {
3477 log("T_3195 timeout");
3478 /* Done in alt, wait for pending RTS initiated previously in
3479 * above case before continuing (expect nothing to be sent since there's no active TBF): */
3480 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3481 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3482 omit));
3483 }
3484 [] BTS.receive {
3485 setverdict(fail, "Unexpected BTS message");
3486 f_shutdown(__BFILE__, __LINE__);
3487 }
3488 }
3489
3490 f_shutdown(__BFILE__, __LINE__, final := true);
3491}
3492
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003493/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3494 * transmitted on ul slot provided by its DL TBF.
3495 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3496function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3497 var GprsMS ms;
3498 var octetstring data := f_rnd_octstring(10);
3499 var RlcmacDlBlock dl_block;
3500 var template RlcmacDlBlock rej_tmpl;
3501 var uint32_t dl_fn;
3502 var uint32_t sched_fn;
3503 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3504
3505 if (use_egprs == true) {
3506 racap_tmpl := bssgp_ms_racap_egprs_def;
3507 } else {
3508 racap_tmpl := bssgp_ms_racap_gprs_def;
3509 }
3510
3511 /* Initialize NS/BSSGP side */
3512 f_init_bssgp();
3513 /* Initialize GPRS MS side */
3514 f_init_gprs_ms();
3515 ms := g_ms[0]; /* We only use first MS in this test */
3516 /* Initialize the PCU interface abstraction */
3517 f_init_raw(testcasename());
3518
3519 /* Establish BSSGP connection to the PCU */
3520 f_bssgp_establish();
3521 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3522
3523 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3524 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3525 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3526
3527 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3528 f_sleep(X2002);
3529 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3530
3531 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3532 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3533 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3534 f_dl_block_ack_fn(dl_block, dl_fn));
3535
3536 /* We should receive a Pkt Ul ASS */
3537 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3538 f_shutdown(__BFILE__, __LINE__, final := true);
3539}
3540testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3541 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3542}
3543testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3544 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3545}
3546
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003547/* Test CS paging over the BTS<->PCU socket.
3548 * 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.
3549 * Paging should be send on the PACCH.
3550 *
3551 * 1. Send a Paging Request over PCU socket.
3552 * 2. Send a Ready-To-Send message over PCU socket
3553 * 3. Expect a Paging Frame
3554 */
3555testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003556 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003557 var MobileIdentityLV mi;
3558 var octetstring mi_enc_lv;
3559 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003560 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003561
3562 /* Initialize NS/BSSGP side */
3563 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003564 /* Initialize GPRS MS side */
3565 f_init_gprs_ms();
3566 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003567
3568 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003569 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003570
3571 /* Establish BSSGP connection to the PCU */
3572 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003573 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003574
3575 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003576 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003577
3578 /* build mobile Identity */
3579 mi := valueof(ts_MI_IMSI_LV(imsi));
3580 mi_enc_lv := enc_MobileIdentityLV(mi);
3581 /* Send paging request */
3582 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3583 sapi :=PCU_IF_SAPI_PDTCH));
3584
3585 /* Receive it on BTS side towards MS */
3586 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3587
3588 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003589 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3590 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3591 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3592 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003593
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003594 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003595}
3596
3597/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3598 */
3599private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3600runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003601 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003602 var hexstring imsi := f_gen_imsi(42);
3603 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003604 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003605
3606 /* Initialize NS/BSSGP side */
3607 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003608 /* Initialize GPRS MS side */
3609 f_init_gprs_ms();
3610 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003611
3612 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003613 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003614
3615 /* Establish BSSGP connection to the PCU */
3616 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003617 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003618
3619 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003620 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003621
3622 /* Send paging request with or without TMSI */
3623 if (use_ptmsi) {
3624 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3625 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3626 } else {
3627 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3628 }
3629
Pau Espin Pedrol00fec582022-11-29 16:03:13 +01003630 /* Now receive it on BTS side towards MS.
3631 * Skip any dummy blocks in case the PCUIF req arrives before the BSSP CS_PAGING:
3632 */
3633 f_rx_rlcmac_dl_block_skip_dummy(dl_block, max_dummy := 10);
3634
3635 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
3636 setverdict(fail, "Failed to match Packet Paging Request: ",
3637 dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
3638 f_shutdown(__BFILE__, __LINE__);
3639 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003640
3641 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003642 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003643 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003644 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3645 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3646 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003647 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003648 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3649 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3650 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003651 }
3652
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003653 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003654}
3655
3656testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3657 f_tc_paging_cs_from_sgsn(0, true);
3658}
3659
3660testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3661 f_tc_paging_cs_from_sgsn(0);
3662}
3663
3664testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003665 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003666}
3667
3668/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3669 */
3670private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3671runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003672 var integer imsi_suff_tx := 423;
3673 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003674 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003675
3676 /* Initialize NS/BSSGP side */
3677 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003678 /* Initialize GPRS MS side */
3679 f_init_gprs_ms();
3680 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003681
Oliver Smith61b4e732021-07-22 08:14:29 +02003682 f_statsd_reset();
3683
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003684 /* Establish BSSGP connection to the PCU */
3685 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003686 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003687
3688 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3689 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3690 if (use_ptmsi) {
3691 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3692 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3693 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3694 } else {
3695 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3696 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3697 }
3698
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003699 var StatsDExpects expect := {
3700 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3701 /* After the PCU receives the paging request from SGSN,
3702 * and it doesn't have any errors, PCU sends it to the
3703 * BTS to do paging over PCH. */
3704 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3705 };
3706 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003707}
3708
3709testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3710 /* Initialize the PCU interface abstraction */
3711 f_init_raw(testcasename());
3712
3713 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003714
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003715 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003716}
3717
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003718testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003719 /* Initialize the PCU interface abstraction */
3720 f_init_raw(testcasename());
3721
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003722 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003723
3724 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003725}
3726
3727testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003728 /* Initialize the PCU interface abstraction */
3729 f_init_raw(testcasename());
3730
Harald Welte5339b2e2020-10-04 22:52:56 +02003731 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003732
3733 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003734}
3735
Oliver Smithe1a77c42021-07-28 13:36:09 +02003736testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3737 /* Initialize the PCU interface abstraction */
3738 f_init_raw(testcasename());
3739
3740 /* Set T3113 to 1s to shorten the test duration */
3741 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3742
3743 /* Reset stats and send paging PS request */
3744 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3745
3746 /* Verify that counter increases when T3113 times out (MS did not start
3747 * TBF to respond to paging). */
3748 f_sleep(1.2);
3749 var StatsDExpects expect := {
3750 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3751 };
3752 f_statsd_expect(expect);
3753
3754 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3755 f_shutdown(__BFILE__, __LINE__, final := true);
3756}
3757
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003758/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3759testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3760 var RlcmacDlBlock dl_block;
3761 var octetstring data := f_rnd_octstring(10);
3762 var uint32_t sched_fn;
3763 var uint32_t dl_fn;
3764 var GprsMS ms;
3765
3766 /* Initialize NS/BSSGP side */
3767 f_init_bssgp();
3768 /* Initialize GPRS MS side */
3769 f_init_gprs_ms();
3770 ms := g_ms[0]; /* We only use first MS in this test */
3771
3772 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003773 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003774
Daniel Willmann535aea62020-09-21 13:27:08 +02003775 f_statsd_reset();
3776
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003777 /* Establish BSSGP connection to the PCU */
3778 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003779 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003780
3781 /* Establish an Uplink TBF */
3782 f_ms_establish_ul_tbf(ms);
3783
3784 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003785 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 +02003786 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3787 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3788 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3789
3790 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003791 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003792
3793 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3794 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3795 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3796
3797 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3798 f_sleep(X2002);
3799 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3800
3801 /* ACK the DL block */
3802 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3803 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3804 f_dl_block_ack_fn(dl_block, dl_fn));
3805
Daniel Willmann535aea62020-09-21 13:27:08 +02003806 var StatsDExpects expect := {
3807 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3808 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3809 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3810 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003811 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003812 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003813 };
3814 f_statsd_expect(expect);
3815
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003816 f_shutdown(__BFILE__, __LINE__, final := true);
3817}
3818
3819/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3820testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3821 var RlcmacDlBlock dl_block;
3822 var octetstring data := f_rnd_octstring(10);
3823 var uint32_t sched_fn;
3824 var uint32_t dl_fn;
3825 var GprsMS ms;
3826
3827 /* Initialize NS/BSSGP side */
3828 f_init_bssgp();
3829 /* Initialize GPRS MS side */
3830 f_init_gprs_ms();
3831 ms := g_ms[0]; /* We only use first MS in this test */
3832
3833 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003834 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003835
3836 /* Establish BSSGP connection to the PCU */
3837 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003838 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003839
3840 /* Establish an Uplink TBF */
3841 f_ms_establish_ul_tbf(ms);
3842
3843 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003844 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 +02003845 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3846 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3847 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3848
3849 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003850 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003851
3852 /* Now SGSN sends some DL data with an invalid IMSI */
3853 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3854
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003855 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003856
3857 /* TODO: make sure no data is sent over PCU -> MS */
3858
3859 f_shutdown(__BFILE__, __LINE__, final := true);
3860}
3861
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003862private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3863 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3864 var octetstring data := f_rnd_octstring(6);
3865 var RlcmacDlBlock dl_block;
3866 var GprsMS ms;
3867 var uint32_t fn;
3868
3869 /* Initialize NS/BSSGP side */
3870 f_init_bssgp();
3871 /* Initialize GPRS MS side */
3872 f_init_gprs_ms();
3873 ms := g_ms[0]; /* We only use first MS in this test */
3874
3875 /* Initialize the PCU interface abstraction */
3876 f_init_raw(testcasename());
3877
3878 /* Establish BSSGP connection to the PCU */
3879 f_bssgp_establish();
3880 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3881
3882 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3883 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3884 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3885
3886 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3887 f_sleep(X2002);
3888
3889 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3890 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3891
3892 if (ischosen(dl_block.data_egprs)) {
3893 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3894 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3895 f_shutdown(__BFILE__, __LINE__);
3896 }
3897 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3898 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3899 f_shutdown(__BFILE__, __LINE__);
3900 }
3901 if (not match(dl_block.data_egprs.blocks[1].payload,
3902 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3903 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3904 f_shutdown(__BFILE__, __LINE__);
3905 }
3906 } else if (lengthof(dl_block.data.blocks) > 1) {
3907 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3908 f_shutdown(__BFILE__, __LINE__);
3909 }
3910
3911 f_shutdown(__BFILE__, __LINE__, final := true);
3912}
3913
3914/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3915 * containing llc data. See OS#4849 */
3916testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3917 f_tc_dl_data_no_llc_ui_dummy(omit);
3918}
3919
3920/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3921 * containing llc data. See OS#4849 */
3922testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003923 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003924}
3925
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02003926/* Scenario: MS creates one phase access, does contention resolution CV>0 and
3927 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
3928 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
3929 * has to assign a DL TBF (through PCH because of FINISHED state, TS 44.060 9.3.3.3.2).
3930 * Make sure the assignment is not done until we receive the PKT CTRL ACK from the MS
3931 * (at that time we know the MS is listening on PCH again). OS#5700.
3932 */
3933testcase TC_ul_tbf_finished_pkt_dl_ass_pch() runs on RAW_PCU_Test_CT {
3934 var RlcmacDlBlock dl_block;
3935 var octetstring data := f_rnd_octstring(10);
3936 var uint32_t sched_fn;
3937 var uint32_t dl_fn;
3938 var GprsMS ms;
3939 timer T;
3940 var octetstring payload;
3941
3942 /* Initialize NS/BSSGP side */
3943 f_init_bssgp();
3944 /* Initialize GPRS MS side */
3945 f_init_gprs_ms();
3946 ms := g_ms[0]; /* We only use first MS in this test */
3947
3948 /* Initialize the PCU interface abstraction */
3949 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3950
3951 /* Establish BSSGP connection to the PCU */
3952 f_bssgp_establish();
3953 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3954
3955 /* Establish an Uplink TBF */
3956 f_ms_establish_ul_tbf(ms);
3957
3958 /* Send one UL block (with TLLI since we are in One-Phase Access
3959 contention resolution) and make sure it is ACKED fine. */
3960 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
3961 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
3962 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
3963
3964 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3965 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
3966 f_ms_tx_ul_data_block(ms, payload, cv := 0);
3967 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3968
3969 /* 1 UL block should be received in SGSN */
3970 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3971 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3972 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3973
3974 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3975 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3976 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3977 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3978 f_sleep(X2002);
3979 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3980
3981 f_shutdown(__BFILE__, __LINE__, final := true);
3982}
3983
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02003984/* Scenario: MS creates a UL TBF and
3985 * finishes sending data (CV=0), which is forwarded to SGSN by PCU. PCU acks with
3986 * FINAL_ACK=1 (hence UL TBF moves to FINISHED state). Then SGSN answers and PCU
3987 * has to assign a DL TBF on PCH. While the network is waiting for the MS to
3988 * move to PDCH before transmitting DL data (timer X2002), the MS finds out it
3989 * needs to send new UL data and hence sends a RACH request to create a new UL
3990 * TBF.
3991 * Make sure the the MS is assigned a DL TBF through PACCH in that case even if
3992 * no new DL data is received from the SGSN. OS#5700.
3993 * This test validates the specific case where the 2nd UL TBF is done through
3994 * 1phase-access.
3995 */
3996testcase TC_ul_tbf_1phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
3997 var RlcmacDlBlock dl_block;
3998 var octetstring data := f_rnd_octstring(10);
3999 var uint32_t sched_fn;
4000 var uint32_t poll_fn;
4001 var uint32_t dl_fn;
4002 var GprsMS ms;
4003 timer T;
4004 var octetstring payload;
4005
4006 /* Initialize NS/BSSGP side */
4007 f_init_bssgp();
4008 /* Initialize GPRS MS side */
4009 f_init_gprs_ms();
4010 ms := g_ms[0]; /* We only use first MS in this test */
4011
4012 /* Initialize the PCU interface abstraction */
4013 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4014
4015 /* Establish BSSGP connection to the PCU */
4016 f_bssgp_establish();
4017 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4018
4019 /* Establish an Uplink TBF */
4020 f_ms_establish_ul_tbf(ms);
4021
4022 /* Send one UL block (with TLLI since we are in One-Phase Access
4023 contention resolution) and make sure it is ACKED fine. */
4024 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4025 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4026 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4027
4028 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4029 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4030 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4031 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4032
4033 /* 1 UL block should be received in SGSN */
4034 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4035 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4036 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4037
4038 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4039 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4040 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4041
4042 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4043 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4044 f_ms_establish_ul_tbf(ms);
4045
4046 /* Send one UL block (with TLLI since we are in One-Phase Access
4047 * contention resolution) and make sure it is ACKED fine. */
4048 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4049 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4050 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4051
4052 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4053 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4054
4055 /* The PCU considers the MS to have gone over Contention Resolution
4056 * after having sent the first UL ACK/NACK to it, hence next it will try to
4057 * assign the DL-TBF to send the data it received from the SGSN previously: */
4058 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4059 /* the MS ACKs the PKT_DL_ASS: */
4060 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4061
4062 /* We should finally receive the DL-data that was received previously from the SGSN: */
4063 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4064
4065 f_shutdown(__BFILE__, __LINE__, final := true);
4066}
4067
4068/* Same as TC_ul_tbf_2phase_while_dl_ass_pch, but this test validates the
4069 * specific case where the 2nd UL TBF is done through 2phase-access. */
4070testcase TC_ul_tbf_2phase_while_dl_ass_pch() runs on RAW_PCU_Test_CT {
4071 var RlcmacDlBlock dl_block;
4072 var octetstring data := f_rnd_octstring(10);
4073 var uint32_t sched_fn;
4074 var uint32_t poll_fn;
4075 var uint32_t dl_fn;
4076 var GprsMS ms;
4077 timer T;
4078 var octetstring payload;
4079 var PollFnCtx pollctx;
4080
4081 /* Initialize NS/BSSGP side */
4082 f_init_bssgp();
4083 /* Initialize GPRS MS side */
4084 f_init_gprs_ms();
4085 ms := g_ms[0]; /* We only use first MS in this test */
4086
4087 /* Initialize the PCU interface abstraction */
4088 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
4089
4090 /* Establish BSSGP connection to the PCU */
4091 f_bssgp_establish();
4092 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4093
4094 /* Establish an Uplink TBF */
4095 f_ms_establish_ul_tbf(ms);
4096
4097 /* Send one UL block (with TLLI since we are in One-Phase Access
4098 contention resolution) and make sure it is ACKED fine. */
4099 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
4100 dl_fn := f_rx_rlcmac_dl_block_exp_dummy(dl_block);
4101 f_ms_tx_ul_data_block(ms, payload, cv := 1, with_tlli := true, fn := f_next_pdch_block(dl_fn));
4102
4103 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4104 payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, false));
4105 f_ms_tx_ul_data_block(ms, payload, cv := 0);
4106 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
4107
4108 /* 1 UL block should be received in SGSN */
4109 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
4110 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
4111 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4112
4113 /* UL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4114 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4115 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4116
4117 /* Now the PCU is waiting for the MS to move to PDCH in order to send data to it (timer X2002).
4118 * The MS decides it want to send new Ul TBF so it send RACH req to ask for it: */
4119 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4120
4121 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4122 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4123
4124 /* Now that MS seized the UL-TBF, PCU sends DL-TBF Assignment on PACCH */
4125 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4126 /* the MS ACKs the PKT_DL_ASS: */
4127 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4128
4129 /* We should finally receive the DL-data that was received previously from the SGSN: */
4130 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
4131
4132 f_shutdown(__BFILE__, __LINE__, final := true);
4133}
4134
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004135private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004136 template GsmRrMessage t_imm_ass := ?,
4137 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004138runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004139 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004140 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004141
4142 ra11 := enc_EGPRSPktChRequest2uint(req);
4143 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
4144
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07004145 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07004146 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004147 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004148 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004149 }
4150
4151 setverdict(pass);
4152}
4153
4154testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
4155 var template GsmRrMessage imm_ass;
4156 var template IaRestOctets rest;
4157 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004158 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004159
4160 /* Initialize the PCU interface abstraction */
4161 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004162 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004163
4164 var EGPRSPktChRequest req := {
4165 /* NOTE: other fields are set in the loop */
4166 signalling := { tag := '110011'B }
4167 };
4168
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004169 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004170 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4171 req.signalling.random_bits := ext_ra;
4172
4173 /* For signalling, do we expect Multiblock UL TBF Assignment? */
4174 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4175 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4176 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4177
4178 f_TC_egprs_pkt_chan_req(req, imm_ass);
4179 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004180
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004181 var StatsDExpects expect := {
4182 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4183 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4184 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4185 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4186 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4187 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4188 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4189 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4190 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4191 };
4192 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004193
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004194 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004195}
4196
4197testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
4198 var template GsmRrMessage imm_ass;
4199 var template IaRestOctets rest;
4200 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004201 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004202
4203 /* Initialize the PCU interface abstraction */
4204 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004205 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004206
4207 var EGPRSPktChRequest req := {
4208 /* NOTE: other fields are set in the loop */
4209 one_phase := { tag := '0'B }
4210 };
4211
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004212 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004213 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4214 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
4215 var BIT2 priority := substr(ext_ra, 0, 2);
4216 var BIT3 rand := substr(ext_ra, 2, 3);
4217
4218 req.one_phase.multislot_class := mslot_class;
4219 req.one_phase.priority := priority;
4220 req.one_phase.random_bits := rand;
4221
4222 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
4223 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
4224 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4225 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4226
4227 f_TC_egprs_pkt_chan_req(req, imm_ass);
4228 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004229
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004230 var StatsDExpects expect := {
4231 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4232 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4233 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4234 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4235 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4236 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4237 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4238 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4239 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4240 };
4241 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004242
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004243 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004244}
4245
4246testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4247 var template GsmRrMessage imm_ass;
4248 var template IaRestOctets rest;
4249 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004250 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004251
4252 /* Initialize the PCU interface abstraction */
4253 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004254 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004255
4256 var EGPRSPktChRequest req := {
4257 /* NOTE: other fields are set in the loop */
4258 two_phase := { tag := '110000'B }
4259 };
4260
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004261 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004262 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4263 var BIT2 priority := substr(ext_ra, 0, 2);
4264 var BIT3 rand := substr(ext_ra, 2, 3);
4265
4266 req.two_phase.priority := priority;
4267 req.two_phase.random_bits := rand;
4268
4269 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4270 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4271 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4272 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4273
4274 f_TC_egprs_pkt_chan_req(req, imm_ass);
4275 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004276
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004277 var StatsDExpects expect := {
4278 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4279 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4280 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4281 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4282 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4283 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4284 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4285 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4286 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4287 };
4288 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004289
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004290 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004291}
4292
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004293private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4294 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004295 PCUIF_BurstType bt := BURST_TYPE_1,
4296 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004297runs on RAW_PCU_Test_CT {
4298 var template ReqRefWaitInd tr_ref;
4299 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004300
4301 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4302 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4303 ra := bit2int(ra11), is_11bit := 1,
4304 burst_type := bt, fn := fn,
4305 arfcn := 871));
4306
4307 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004308 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004309
4310 /* Just to have a short-name reference to the actual message */
4311 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4312
4313 /* Make sure that Request Reference list contains at least one entry
4314 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004315 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004316 if (not match(iar.payload, { *, tr_ref, * })) {
4317 setverdict(fail, "Request Reference list does not match");
4318 f_shutdown(__BFILE__, __LINE__);
4319 }
4320
4321 /* Match Feature Indicator (must indicate PS domain) */
4322 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4323 setverdict(fail, "Feature Indicator does not match");
4324 f_shutdown(__BFILE__, __LINE__);
4325 }
4326
4327 /* Match IAR Rest Octets */
4328 if (not match(iar.rest_octets, rest)) {
4329 setverdict(fail, "IAR Rest Octets does not match: ",
4330 iar.rest_octets, " vs expected ", rest);
4331 f_shutdown(__BFILE__, __LINE__);
4332 }
4333
4334 setverdict(pass);
4335}
4336
4337/* Verify the contents of RR Immediate Assignment Reject message and its
4338 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4339testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4340 var template IARRestOctets rest;
4341 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004342 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004343
4344 /* Initialize the PCU interface abstraction */
4345 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004346 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004347
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004348 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004349 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4350 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4351
4352 /* Intentionally incorrect message (see table 11.2.5a.2) */
4353 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4354 }
4355
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004356 var StatsDExpects expect := {
4357 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4358 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4359 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4360 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4361 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4362 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4363 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4364 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4365 };
4366 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004367
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004368 f_shutdown(__BFILE__, __LINE__, final := true);
4369}
4370
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004371/* At the moment, the IUT does not support any emergency services. Make sure
4372 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4373testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4374 var template IARRestOctets rest;
4375 var BIT5 ext_ra;
4376 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004377 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004378
4379 /* Initialize the PCU interface abstraction */
4380 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004381 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004382
4383 var EGPRSPktChRequest req := {
4384 /* NOTE: other fields are set in the loop */
4385 emergency := { tag := '110111'B }
4386 };
4387
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004388 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004389 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4390 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4391
4392 req.emergency.random_bits := ext_ra;
4393 ra11 := enc_EGPRSPktChRequest2bits(req);
4394
4395 /* Intentionally incorrect message (see table 11.2.5a.2) */
4396 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4397 }
4398
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004399 var StatsDExpects expect := {
4400 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4401 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4402 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4403 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4404 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4405 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4406 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4407 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4408 };
4409 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004410
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004411 f_shutdown(__BFILE__, __LINE__, final := true);
4412}
4413
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004414/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4415testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004416 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004417 var template IARRestOctets rest;
4418 var BIT11 ra11;
4419
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004420 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004421 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004422
4423 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004424 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4425 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004426
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004427 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004428 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004429 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004430
4431 var EGPRSPktChRequest req := {
4432 one_phase := {
4433 tag := '0'B,
4434 multislot_class := '10101'B,
4435 priority := '01'B,
4436 random_bits := '101'B
4437 }
4438 };
4439
4440 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4441 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4442 for (var integer i := 0; i < 7; i := i + 1) {
4443 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4444 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4445 }
4446
4447 ra11 := enc_EGPRSPktChRequest2bits(req);
4448 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4449
4450 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004451 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004452
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004453 var StatsDExpects expect := {
4454 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4455 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4456 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4457 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4458 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4459 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4460 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4461 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4462 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4463 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4464 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4465 };
4466 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004467
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004468 f_shutdown(__BFILE__, __LINE__, final := true);
4469}
4470
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004471/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004472private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004473return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004474 /* Pick a random MA length in range 2 .. max_ma_len */
4475 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4476
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004477 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4478 hsn := f_rnd_int(63),
4479 maio := f_rnd_int(63),
4480 ma := f_rnd_bitstring(ma_len));
4481}
4482
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004483private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4484 in GsmRrMessage rr_msg)
4485{
4486 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004487 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004488
4489 var template PacketChannelDescription tr_pkt_chan_desc := {
4490 channel_Type_spare := ?,
4491 tn := ?,
4492 tsc := ts.tsc,
4493 presence := '1'B,
4494 zero := omit,
4495 one := {
4496 maio := ts.maio,
4497 hsn := ts.hsn
4498 }
4499 };
4500
4501 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4502 setverdict(fail, "Packet Channel Description does not match: ",
4503 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4504 }
4505
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004506 /* Mobile Allocation is expected to be octet-aligned */
4507 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4508 var template MobileAllocationLV tr_ma := {
4509 len := ma_oct_len, /* in bytes */
4510 ma := substr(ts.ma, 0, ma_oct_len * 8)
4511 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004512
4513 if (not match(ia.mobile_allocation, tr_ma)) {
4514 setverdict(fail, "Mobile Allocation does not match: ",
4515 ia.mobile_allocation, " vs ", tr_ma);
4516 }
4517
4518 setverdict(pass);
4519}
4520
4521/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4522testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004523 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004524 var GprsMS ms := valueof(t_GprsMS_def);
4525
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004526 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004527 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004528
4529 /* Initialize the PCU interface abstraction */
4530 f_init_raw(testcasename(), info_ind);
4531
4532 /* EGPRS Packet Channel Request (cause=Signalling) */
4533 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4534
4535 /* Establish an Uplink EGPRS TBF */
4536 f_ms_establish_ul_tbf(ms);
4537
4538 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4539 f_shutdown(__BFILE__, __LINE__, final := true);
4540}
4541
4542/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4543testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004544 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004545 var GprsMS ms := valueof(t_GprsMS_def);
4546
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004547 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004548 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004549
4550 /* Initialize the PCU interface abstraction */
4551 f_init_raw(testcasename(), info_ind);
4552
4553 /* Establish an Uplink TBF */
4554 f_ms_establish_ul_tbf(ms);
4555
4556 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4557 f_shutdown(__BFILE__, __LINE__, final := true);
4558}
4559
4560/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4561testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004562 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004563 var GprsMS ms := valueof(t_GprsMS_def);
4564
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004565 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004566 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004567
4568 /* Initialize NS/BSSGP side */
4569 f_init_bssgp();
4570
4571 /* Initialize the PCU interface abstraction */
4572 f_init_raw(testcasename(), info_ind);
4573
4574 /* Establish BSSGP connection to the PCU */
4575 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004576 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004577
4578 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4579 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4580 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4581
4582 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4583 f_shutdown(__BFILE__, __LINE__, final := true);
4584}
4585
4586private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4587 in FrequencyParameters fp)
4588{
4589 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004590 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004591
4592 /* Table 12.8.1: Frequency Parameters information elements */
4593 var template FrequencyParameters tr_fp := {
4594 tsc := ts.tsc,
4595 presence := '10'B, /* Direct encoding 1 */
4596 arfcn := omit,
4597 indirect := omit,
4598 direct1 := {
4599 maio := ts.maio,
4600 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4601 mobile_allocation := {
4602 hsn := ts.hsn,
4603 rfl_number_list_present := '0'B,
4604 rfl_number_list := omit,
4605 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004606 ma_length := ts.ma_bit_len,
4607 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004608 }
4609 },
4610 direct2 := omit
4611 };
4612
4613 if (not match(fp, tr_fp)) {
4614 setverdict(fail, "Frequency Parameters IE does not match: ",
4615 fp, " vs ", tr_fp);
4616 }
4617
4618 setverdict(pass);
4619}
4620
4621/* Make sure that Packet Uplink Assignment contains hopping parameters */
4622testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004623 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004624 var GprsMS ms := valueof(t_GprsMS_def);
4625 var uint32_t poll_fn;
4626
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004627 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004628 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004629
4630 /* Initialize the PCU interface abstraction */
4631 f_init_raw(testcasename(), info_ind);
4632
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004633 /* Single block (two phase) packet access */
4634 var uint16_t ra := bit2int(chan_req_sb);
4635 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4636
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004637 /* Establish an Uplink TBF */
4638 f_ms_establish_ul_tbf(ms);
4639
4640 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004641 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4642 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004643
4644 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004645 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4646 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004647
4648 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4649 var template (omit) FrequencyParameters fp;
4650 if (ua.is_egprs == '1'B) {
4651 fp := ua.egprs.freq_par;
4652 } else {
4653 fp := ua.gprs.freq_par;
4654 }
4655
4656 /* This is an optional IE, so it's worth to check its presence */
4657 if (istemplatekind(fp, "omit")) {
4658 setverdict(fail, "Frequency Parameters IE is not present");
4659 f_shutdown(__BFILE__, __LINE__);
4660 }
4661
4662 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4663 f_shutdown(__BFILE__, __LINE__, final := true);
4664}
4665
4666/* Make sure that Packet Downlink Assignment contains hopping parameters */
4667testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004668 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004669 var octetstring data := f_rnd_octstring(10);
4670 var GprsMS ms := valueof(t_GprsMS_def);
4671 var RlcmacDlBlock dl_block;
4672 var uint32_t poll_fn;
4673
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004674 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004675 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004676
4677 /* Initialize NS/BSSGP side */
4678 f_init_bssgp();
4679
4680 /* Initialize the PCU interface abstraction */
4681 f_init_raw(testcasename(), info_ind);
4682
4683 /* Establish BSSGP connection to the PCU */
4684 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004685 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004686
4687 /* Establish an Uplink TBF */
4688 f_ms_establish_ul_tbf(ms);
4689
4690 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004691 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 +07004692
4693 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4694 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4695 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4696
4697 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4698 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4699
4700 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004701 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4702 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004703
4704 /* This is an optional IE, so it's worth to check its presence */
4705 if (not ispresent(da.freq_par)) {
4706 setverdict(fail, "Frequency Parameters IE is not present");
4707 f_shutdown(__BFILE__, __LINE__);
4708 }
4709
4710 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4711 f_shutdown(__BFILE__, __LINE__, final := true);
4712}
4713
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004714/* Check if the IUT handles subsequent INFO.ind messages */
4715testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004716 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004717 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004718
4719 /* Initialize the PCU interface abstraction */
4720 f_init_raw(testcasename(), info_ind);
4721
4722 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4723 for (var integer i := 0; i < 16; i := i + 1) {
4724 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004725 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004726 }
4727
4728 f_shutdown(__BFILE__, __LINE__, final := true);
4729}
4730
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004731/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4732testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4733 var PCUIF_info_ind info_ind;
4734 var integer i;
4735 const integer num_ms := 8;
4736
4737 /* Initialize NS/BSSGP side */
4738 f_init_bssgp();
4739 /* Initialize GPRS MS side */
4740 f_init_gprs_ms(num_ms);
4741
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004742 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004743 /* Only the 3 first TRX are enabled. The enabled ones all have same
4744 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004745 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4746 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4747 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4748 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004749
4750 /* Initialize the PCU interface abstraction */
4751 f_init_raw(testcasename(), info_ind);
4752
4753 /* Establish BSSGP connection to the PCU */
4754 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004755 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004756
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004757 /* Establish an Uplink TBF for each GprsMS instance */
4758 f_multi_ms_establish_tbf(do_activate := false);
4759
4760 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004761 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004762 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004763 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004764 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004765 f_shutdown(__BFILE__, __LINE__);
4766 }
4767 }
4768
4769 f_shutdown(__BFILE__, __LINE__, final := true);
4770}
4771
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004772/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4773 * downgraded to CS1-4 so that GPRS can read the USF).
4774 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4775 */
4776testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4777 var PCUIF_info_ind info_ind;
4778 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4779 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004780 var uint32_t sched_fn, dl_fn, ack_fn;
4781 var octetstring data := f_rnd_octstring(10);
4782 var RlcmacDlBlock dl_block;
4783 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004784 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004785 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4786 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4787
4788 /* Initialize NS/BSSGP side */
4789 f_init_bssgp();
4790 /* Initialize GPRS MS side */
4791 f_init_gprs_ms(num_ms);
4792
4793 info_ind := valueof(ts_PCUIF_INFO_default);
4794 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004795 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4796 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004797
4798 /* Initialize the PCU interface abstraction */
4799 f_init_raw(testcasename(), info_ind);
4800
4801 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4802 g_mcs_initial_dl := 5;
4803 g_mcs_max_dl := 5;
4804 f_pcuvty_set_allowed_cs_mcs();
4805
4806 /* Establish BSSGP connection to the PCU */
4807 f_bssgp_establish();
4808 f_multi_ms_bssgp_register();
4809
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004810 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004811 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 +01004812 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4813 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4814 f_shutdown(__BFILE__, __LINE__);
4815 }
4816 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4817 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4818
4819 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004820 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 +01004821 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4822 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4823 f_shutdown(__BFILE__, __LINE__);
4824 }
4825 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4826 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4827
4828 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4829 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4830 f_sleep(0.1);
4831 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4832 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4833 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4834 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4835 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4836 /* ACK the DL block */
4837 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4838 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4839 f_dl_block_ack_fn(dl_block, dl_fn));
4840
4841 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4842 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4843 f_sleep(0.1);
4844 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4845 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4846 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4847 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4848 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4849 /* ACK the DL block */
4850 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4851 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4852 f_dl_block_ack_fn(dl_block, dl_fn));
4853
4854 data := f_rnd_octstring(1400);
4855 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4856 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4857
4858 for (var integer i := 0; i < 800; i := i + 1) {
4859 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4860
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07004861 if (match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL)) {
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004862 /* No more data to receive, done */
4863 break;
4864 }
4865
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004866 usf_ms := -1;
4867
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004868 if (ischosen(dl_block.ctrl)) {
4869 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4870 f_shutdown(__BFILE__, __LINE__);
4871 } else if (ischosen(dl_block.data_egprs)) {
4872 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4873 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4874 f_shutdown(__BFILE__, __LINE__);
4875 }
4876 tgt_ms := 1;
4877 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4878 if (dl_block.data_egprs.mcs > MCS_4) {
4879 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4880 f_shutdown(__BFILE__, __LINE__);
4881 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004882 usf_ms := 0;
4883 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004884 } else {
4885 if (dl_block.data_egprs.mcs <= MCS_4) {
4886 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4887 f_shutdown(__BFILE__, __LINE__);
4888 }
4889 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004890 usf_ms := 1;
4891 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004892 }
4893 }
4894 } else {
4895 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4896 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4897 f_shutdown(__BFILE__, __LINE__);
4898 }
4899 tgt_ms := 0;
4900 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 +01004901 usf_ms := 0;
4902 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004903 } 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 +01004904 usf_ms := 1;
4905 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004906 }
4907 }
4908
4909 /* Keep Ack/Nack description updated */
4910 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4911
4912 /* TDMA frame number on which we are supposed to send the ACK */
4913 if (f_dl_block_rrbp_valid(dl_block)) {
4914 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4915 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);
4916 if (tx_data_remain != 0) {
4917 /* Submit more data from time to time to keep the TBF ongoing */
4918 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4919 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4920 tx_data_remain := tx_data_remain - 1;
4921 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004922 } else if (tx_data_remain != 0) {
4923 /* keep sending UL blocks when requested by USF to avoid
4924 * UL TBF timeout and hence stop receival of USFs */
4925 if (usf_ms != -1) {
4926 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4927 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004928 }
4929 }
4930
4931 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 +01004932 /* He we check that DL blocks scheduled at GPRS can still request UL
4933 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4934 * condition also ensures the downgrade to <=MCS4 condition is tested
4935 * above */
4936 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4937 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004938 f_shutdown(__BFILE__, __LINE__);
4939 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004940 /* Here check for some level of fairness between them (at least ~40%): */
4941 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4942 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4943 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4944 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4945 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4946 f_shutdown(__BFILE__, __LINE__);
4947 }
4948 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4949 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4950 f_shutdown(__BFILE__, __LINE__);
4951 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004952
4953 f_shutdown(__BFILE__, __LINE__, final := true);
4954}
4955
4956
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004957private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4958 boolean exp_imsi, boolean exp_tmsi)
4959runs on RAW_PCU_Test_CT {
4960 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4961 var integer pending := lengthof(g_ms);
4962 var RlcmacDlBlock dl_block;
4963 var boolean f1, f2;
4964
4965 while (pending > 0) {
4966 var uint32_t poll_fn;
4967
4968 /* Obtain a Downlink block and make sure it is a paging request */
4969 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4970 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4971 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4972 break;
4973 }
4974
4975 /* This should not happen in general, but who knows... */
4976 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4977 if (not ispresent(req.repeated_pageinfo)) {
4978 setverdict(fail, "Repeated Page Info IE is absent?!?");
4979 break;
4980 }
4981
4982 /* A single message may contain several MIs depending on their type */
4983 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4984 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4985 ps_domain := false);
4986 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4987 ps_domain := false);
4988 if (not f1 and not f2)
4989 { continue; }
4990
4991 /* Detect duplicate MIs */
4992 if (mask[i] == '1'B) {
4993 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4994 continue;
4995 }
4996
4997 mask[i] := '1'B;
4998 }
4999
5000 pending := pending - lengthof(req.repeated_pageinfo);
5001 }
5002
5003 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
5004 if (mask[i] != '1'B) {
5005 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
5006 log("===== mask := ", mask);
5007 }
5008 }
5009
5010 /* All messages must have been received by now, expect a dummy block */
5011 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
5012}
5013
5014private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
5015runs on RAW_PCU_Test_CT {
5016 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5017 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5018
5019 /* Initialize NS/BSSGP side */
5020 f_init_bssgp();
5021
5022 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005023 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005024
5025 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
5026 f_init_gprs_ms(7 * 8);
5027
5028 /* Initialize the PCU interface abstraction */
5029 f_init_raw(testcasename(), info_ind);
5030
5031 /* Establish BSSGP connection to the PCU */
5032 f_bssgp_establish();
5033 f_multi_ms_bssgp_register();
5034
5035 /* Establish an Uplink TBF for each GprsMS instance */
5036 f_multi_ms_establish_tbf(do_activate := true);
5037}
5038
5039testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
5040 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5041
5042 /* Common part: send INFO.ind, establish TBFs... */
5043 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5044
5045 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
5046 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5047 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5048 }
5049
5050 /* FIXME: work around a race condition between PCUIF and BSSGP */
5051 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5052
5053 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5054 * The IUT is expected to page on all PDCH slots of all transceivers. */
5055 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5056 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5057 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
5058 }
5059
5060 f_shutdown(__BFILE__, __LINE__, final := true);
5061}
5062
5063testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
5064 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5065
5066 /* Common part: send INFO.ind, establish TBFs... */
5067 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5068
5069 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
5070 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5071 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5072 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5073 }
5074
5075 /* FIXME: work around a race condition between PCUIF and BSSGP */
5076 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5077
5078 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5079 * The IUT is expected to page on all PDCH slots of all transceivers. */
5080 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5081 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5082 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
5083 }
5084
5085 f_shutdown(__BFILE__, __LINE__, final := true);
5086}
5087
5088testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
5089 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
5090
5091 /* Common part: send INFO.ind, establish TBFs... */
5092 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
5093
5094 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
5095 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
5096 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
5097 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
5098 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
5099 } else {
5100 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
5101 }
5102 }
5103
5104 /* FIXME: work around a race condition between PCUIF and BSSGP */
5105 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
5106
5107 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
5108 * The IUT is expected to page on all PDCH slots of all transceivers. */
5109 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
5110 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
5111 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
5112 }
5113
5114 f_shutdown(__BFILE__, __LINE__, final := true);
5115}
5116
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005117private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005118runs on RAW_PCU_Test_CT return RlcmacDlBlock {
5119 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005120 var integer i := 0;
5121 while (true) {
5122 f_rx_rlcmac_dl_block(dl_block, sched_fn);
Vadim Yanitskiy7179d3e2022-10-04 03:27:29 +07005123 if (not match(dl_block, tr_RLCMAC_DL_DUMMY_CTRL())) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005124 break;
5125 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005126 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005127 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5128 f_shutdown(__BFILE__, __LINE__);
5129 }
5130 i := i + 1;
5131 }
5132 return dl_block;
5133}
5134
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005135private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
5136runs on RAW_PCU_Test_CT {
5137 var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1),
5138 info_ind.lac),
5139 info_ind.rac),
5140 info_ind.cell_id));
5141 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5142 423),
5143 2),
5144 5));
5145 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5146 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5147 var template (value) RAN_Information_RIM_Container res_cont :=
5148 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5149 ts_RIM_Sequence_Number(2),
5150 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5151 ts_RIM_Protocol_Version_Number(1),
5152 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
5153 omit);
5154 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5155 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5156 res_cont));
5157}
5158
5159altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
5160runs on RAW_PCU_Test_CT {
5161 /* RIM procedure: */
5162 var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1),
5163 info_ind.lac),
5164 info_ind.rac),
5165 info_ind.cell_id));
5166 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5167 423),
5168 2),
5169 5));
5170 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
5171 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
5172 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5173 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5174 tr_RAN_Information_Request_RIM_Container)) {
5175 if (do_answer) {
5176 f_outbound_nacc_rim_tx_resp(info_ind);
5177 }
5178 if (do_repeat) {
5179 repeat;
5180 }
5181 }
5182}
5183
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005184private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
5185 boolean answer := true, boolean use_old_ctrl_iface := false)
5186runs on RAW_PCU_Test_CT {
5187 if (use_old_ctrl_iface == true) {
5188 f_ipa_ctrl_wait_link_up();
5189 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5190 int2str(info_ind.lac) & "." &
5191 int2str(info_ind.cell_id) & "." &
5192 int2str(req_arfcn) & "." &
5193 int2str(req_bsic);
5194 if (answer) {
5195 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5196 } else {
5197 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
5198 }
5199 } else {
5200 var PCUIF_Message pcu_msg;
5201 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5202 if (answer) {
5203 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5204 }
5205 }
5206}
5207
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005208/* Start NACC from MS side */
5209private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005210 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005211 boolean skip_final_ctrl_ack := false,
5212 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005213runs on RAW_PCU_Test_CT {
5214 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5215 var RlcmacDlBlock dl_block;
5216 var uint32_t sched_fn;
5217 var GsmArfcn req_arfcn := 862;
5218 var uint6_t req_bsic := 43;
5219
5220 /* Start NACC from MS side */
5221 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5222 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5223
5224 if (exp_rac_ci_query == true) {
5225 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005226 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 +01005227 }
5228
5229 if (exp_si_query == true) {
5230 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005231 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005232 }
5233
5234 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005235 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005236
5237 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5238 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5239 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5240 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5241 f_shutdown(__BFILE__, __LINE__);
5242 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005243 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005244 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005245 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5246 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5247 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005248}
5249
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005250/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
5251testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005252 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005253 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005254 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005255 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005256
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005257 if (use_old_ctrl_iface) {
5258 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5259 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5260 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005261
5262 /* Initialize NS/BSSGP side */
5263 f_init_bssgp();
5264 /* Initialize GPRS MS side */
5265 f_init_gprs_ms();
5266 ms := g_ms[0]; /* We only use first MS in this test */
5267
5268 /* Initialize the PCU interface abstraction */
5269 f_init_raw(testcasename(), info_ind);
5270
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005271 /* Make sure we are not affected by full cache from previous tests */
5272 f_pcuvty_flush_neigh_caches();
5273
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005274 /* Establish BSSGP connection to the PCU */
5275 f_bssgp_establish();
5276 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5277
5278 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005279 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 +01005280 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5281 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5282
5283 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005284 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005285
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005286 f_shutdown(__BFILE__, __LINE__, final := true);
5287}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005288
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005289/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5290testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5291 var PollFnCtx pollctx;
5292 var GprsMS ms;
5293 var RlcmacDlBlock dl_block;
5294 var uint32_t sched_fn;
5295 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005296 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005297
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005298 if (use_old_ctrl_iface) {
5299 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5300 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5301 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005302
5303 /* Initialize NS/BSSGP side */
5304 f_init_bssgp();
5305 /* Initialize GPRS MS side */
5306 f_init_gprs_ms();
5307 ms := g_ms[0]; /* We only use first MS in this test */
5308
5309 /* Initialize the PCU interface abstraction */
5310 f_init_raw(testcasename(), info_ind);
5311
5312 /* Make sure we are not affected by full cache from previous tests */
5313 f_pcuvty_flush_neigh_caches();
5314
5315 /* Establish BSSGP connection to the PCU */
5316 f_bssgp_establish();
5317 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5318
5319 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005320 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 +01005321 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5322 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5323
5324 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005325 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 +01005326
5327 /* Wait until we receive something non-dummy */
5328 dl_block := f_skip_dummy(0, sched_fn);
5329 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5330 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5331 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5332 }
5333 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5334 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5335 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5336 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5337 }
5338
5339 f_shutdown(__BFILE__, __LINE__, final := true);
5340}
5341
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005342/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5343testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5344 var PollFnCtx pollctx;
5345 var GprsMS ms;
5346 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005347 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005348 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005349
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005350 if (use_old_ctrl_iface) {
5351 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5352 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5353 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005354
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005355 /* Initialize NS/BSSGP side */
5356 f_init_bssgp();
5357 /* Initialize GPRS MS side */
5358 f_init_gprs_ms();
5359 ms := g_ms[0]; /* We only use first MS in this test */
5360
5361 /* Initialize the PCU interface abstraction */
5362 f_init_raw(testcasename(), info_ind);
5363
5364 /* Make sure we are not affected by full cache from previous tests */
5365 f_pcuvty_flush_neigh_caches();
5366 /* Set timeout values for caches so that entries will be in cache during second try */
5367 f_pcuvty_set_neigh_caches(10, 10);
5368
5369 /* Establish BSSGP connection to the PCU */
5370 f_bssgp_establish();
5371 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5372
5373 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005374 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 +01005375 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5376 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5377
5378 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005379 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005380
5381 /* 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 +02005382 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 +01005383
5384 f_shutdown(__BFILE__, __LINE__, final := true);
5385}
5386
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005387/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5388 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5389 */
5390testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5391 var PollFnCtx pollctx;
5392 var GprsMS ms;
5393 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005394 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005395 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005396
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005397 if (use_old_ctrl_iface) {
5398 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5399 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5400 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005401
5402 /* Initialize NS/BSSGP side */
5403 f_init_bssgp();
5404 /* Initialize GPRS MS side */
5405 f_init_gprs_ms();
5406 ms := g_ms[0]; /* We only use first MS in this test */
5407
5408 /* Initialize the PCU interface abstraction */
5409 f_init_raw(testcasename(), info_ind);
5410
5411 /* Make sure we are not affected by full cache from previous tests */
5412 f_pcuvty_flush_neigh_caches();
5413 /* Set timeout values for caches so that entries will be erased before the second try */
5414 f_pcuvty_set_neigh_caches(1, 1);
5415
5416 /* Establish BSSGP connection to the PCU */
5417 f_bssgp_establish();
5418 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5419
5420 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005421 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 +01005422 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5423 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5424
5425 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005426 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005427
5428 /* CTRL client should have disconnected from us */
5429 f_ipa_ctrl_wait_link_down();
5430 /* wait for cache entries to time out */
5431 f_sleep(2.0);
5432 /* 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 +02005433 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005434
5435 f_shutdown(__BFILE__, __LINE__, final := true);
5436}
5437
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005438/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005439testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5440 var RlcmacDlBlock dl_block;
5441 var PollFnCtx pollctx;
5442 var uint32_t sched_fn;
5443 var GprsMS ms;
5444 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5445 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005446 var GsmArfcn req_arfcn := 862;
5447 var uint6_t req_bsic := 43;
5448
5449 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5450 * resolution CTRL port, to trigger Conn Refused by socket:
5451 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5452 */
5453
5454 /* Initialize NS/BSSGP side */
5455 f_init_bssgp();
5456 /* Initialize GPRS MS side */
5457 f_init_gprs_ms();
5458 ms := g_ms[0]; /* We only use first MS in this test */
5459
5460 /* Initialize the PCU interface abstraction */
5461 f_init_raw(testcasename(), info_ind);
5462
5463 /* Make sure we are not affected by full cache from previous tests */
5464 f_pcuvty_flush_neigh_caches();
5465
5466 /* Establish BSSGP connection to the PCU */
5467 f_bssgp_establish();
5468 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5469
5470 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005471 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 +01005472 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5473 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5474
5475 /* Start NACC from MS side */
5476 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5477 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5478
5479 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005480 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005481 /* Make sure it is a Pkt Cell Chg Continue */
5482 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5483 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5484 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005485 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5486 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5487 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5488 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5489 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005490
5491 f_shutdown(__BFILE__, __LINE__, final := true);
5492}
5493
5494/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005495testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5496 var RlcmacDlBlock dl_block;
5497 var PollFnCtx pollctx;
5498 var uint32_t sched_fn;
5499 var GprsMS ms;
5500 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5501 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005502 var GsmArfcn req_arfcn := 862;
5503 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005504 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005505
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005506 if (use_old_ctrl_iface) {
5507 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5508 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5509 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005510
5511 /* Initialize NS/BSSGP side */
5512 f_init_bssgp();
5513 /* Initialize GPRS MS side */
5514 f_init_gprs_ms();
5515 ms := g_ms[0]; /* We only use first MS in this test */
5516
5517 /* Initialize the PCU interface abstraction */
5518 f_init_raw(testcasename(), info_ind);
5519
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005520 /* Make sure we are not affected by full cache from previous tests */
5521 f_pcuvty_flush_neigh_caches();
5522
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005523 /* Establish BSSGP connection to the PCU */
5524 f_bssgp_establish();
5525 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5526
5527 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005528 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 +01005529 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5530 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5531
5532 /* Start NACC from MS side */
5533 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5534 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5535
5536 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005537 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005538 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 +01005539
5540 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005541 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005542 /* Make sure it is a Pkt Cell Chg Continue */
5543 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5544 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5545 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005546 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5547 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5548 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5549 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5550 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005551
5552 f_shutdown(__BFILE__, __LINE__, final := true);
5553}
5554
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005555/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5556testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5557 var RlcmacDlBlock dl_block;
5558 var PollFnCtx pollctx;
5559 var uint32_t sched_fn;
5560 var GprsMS ms;
5561 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5562 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005563 var GsmArfcn req_arfcn := 862;
5564 var uint6_t req_bsic := 43;
5565
5566 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5567 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5568
5569 /* Initialize NS/BSSGP side */
5570 f_init_bssgp();
5571 /* Initialize GPRS MS side */
5572 f_init_gprs_ms();
5573 ms := g_ms[0]; /* We only use first MS in this test */
5574
5575 /* Initialize the PCU interface abstraction */
5576 f_init_raw(testcasename(), info_ind);
5577
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005578 /* Make sure we are not affected by full cache from previous tests */
5579 f_pcuvty_flush_neigh_caches();
5580
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005581 /* Establish BSSGP connection to the PCU */
5582 f_bssgp_establish();
5583 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5584
5585 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005586 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 +01005587 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5588 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5589
5590 /* Start NACC from MS side */
5591 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5592 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5593
5594 /* osmo-pcu should now ask for resolution: */
5595 f_ipa_ctrl_wait_link_up();
5596 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5597 int2str(info_ind.lac) & "." &
5598 int2str(info_ind.cell_id) & "." &
5599 int2str(req_arfcn) & "." &
5600 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005601 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005602 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5603
5604 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005605 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005606 /* Make sure it is a Pkt Cell Chg Continue */
5607 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5608 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5609 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005610 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5611 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5612 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5613 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5614 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005615
5616 f_shutdown(__BFILE__, __LINE__, final := true);
5617}
5618
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005619/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5620testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5621 var RlcmacDlBlock dl_block;
5622 var PollFnCtx pollctx;
5623 var uint32_t sched_fn;
5624 var GprsMS ms;
5625 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5626 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005627 var GsmArfcn req_arfcn := 862;
5628 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005629 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005630 var BssgpCellId src := valueof(ts_BssgpCellId(ts_RAI(ts_LAI(f_enc_BcdMccMnc(info_ind.mcc, info_ind.mnc, info_ind.mnc_3_digits == 1), /* '262F42'H */
5631 info_ind.lac),
5632 info_ind.rac),
5633 info_ind.cell_id));
5634 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5635 423),
5636 2),
5637 5));
5638 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
5639 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
5640
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005641 if (use_old_ctrl_iface) {
5642 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5643 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5644 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005645
5646 /* Initialize NS/BSSGP side */
5647 f_init_bssgp();
5648 /* Initialize GPRS MS side */
5649 f_init_gprs_ms();
5650 ms := g_ms[0]; /* We only use first MS in this test */
5651
5652 /* Initialize the PCU interface abstraction */
5653 f_init_raw(testcasename(), info_ind);
5654
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005655 /* Make sure we are not affected by full cache from previous tests */
5656 f_pcuvty_flush_neigh_caches();
5657
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005658 /* Establish BSSGP connection to the PCU */
5659 f_bssgp_establish();
5660 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5661
5662 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005663 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 +01005664 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5665 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5666
5667 /* Start NACC from MS side */
5668 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5669 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5670
5671 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005672 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 +01005673
5674 /* RIM procedure: */
5675 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5676 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5677 tr_RAN_Information_Request_RIM_Container));
5678 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5679
5680 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005681 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005682 /* Make sure it is a Pkt Cell Chg Continue */
5683 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5684 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5685 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005686 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5687 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5688 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5689 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5690 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005691
5692 f_shutdown(__BFILE__, __LINE__, final := true);
5693}
5694
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005695/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5696testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5697 var PollFnCtx pollctx;
5698 var GprsMS ms;
5699 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5700 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5701 var RlcmacDlBlock dl_block;
5702 var uint32_t sched_fn;
5703 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005704 var charstring ctrl_var;
5705 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005706 var GsmArfcn req_arfcn := 862;
5707 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005708 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005709
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005710 if (use_old_ctrl_iface) {
5711 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5712 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5713 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005714
5715 /* Initialize NS/BSSGP side */
5716 f_init_bssgp();
5717 /* Initialize GPRS MS side */
5718 f_init_gprs_ms();
5719 ms := g_ms[0]; /* We only use first MS in this test */
5720
5721 /* Initialize the PCU interface abstraction */
5722 f_init_raw(testcasename(), info_ind);
5723
5724 /* Make sure we are not affected by full cache from previous tests */
5725 f_pcuvty_flush_neigh_caches();
5726
5727 /* Establish BSSGP connection to the PCU */
5728 f_bssgp_establish();
5729 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5730
5731 /* Send PACKET RESOURCE REQUEST */
5732 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5733 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5734 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5735
5736 /* Start NACC from MS side */
5737 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5738 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5739
5740 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005741 if (use_old_ctrl_iface) {
5742 f_ipa_ctrl_wait_link_up();
5743 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5744 int2str(info_ind.lac) & "." &
5745 int2str(info_ind.cell_id) & "." &
5746 int2str(req_arfcn) & "." &
5747 int2str(req_bsic);
5748 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5749 } else {
5750 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5751 }
5752
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005753 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5754 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5755 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005756
5757 if (use_old_ctrl_iface) {
5758 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5759 } else {
5760 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5761 }
5762
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005763 timer T := 2.0;
5764 T.start;
5765 alt {
5766 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005767 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005768 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5769 f_shutdown(__BFILE__, __LINE__);
5770 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005771 [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 {
5772 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5773 f_shutdown(__BFILE__, __LINE__);
5774 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005775 [] T.timeout {
5776 setverdict(pass);
5777 }
5778 }
5779
5780 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005781 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005782
5783 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5784 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5785 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5786 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5787 f_shutdown(__BFILE__, __LINE__);
5788 }
5789 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5790 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5791 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5792 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5793 }
5794
5795 f_shutdown(__BFILE__, __LINE__, final := true);
5796}
5797
5798/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5799testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5800 var PollFnCtx pollctx;
5801 var GprsMS ms;
5802 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5803 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5804 var RlcmacDlBlock dl_block;
5805 var uint32_t sched_fn;
5806 var CtrlMessage rx_ctrl;
5807 var GsmArfcn req_arfcn := 862;
5808 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005809 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005810
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005811 if (use_old_ctrl_iface) {
5812 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5813 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5814 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005815
5816 /* Initialize NS/BSSGP side */
5817 f_init_bssgp();
5818 /* Initialize GPRS MS side */
5819 f_init_gprs_ms();
5820 ms := g_ms[0]; /* We only use first MS in this test */
5821
5822 /* Initialize the PCU interface abstraction */
5823 f_init_raw(testcasename(), info_ind);
5824
5825 /* Make sure we are not affected by full cache from previous tests */
5826 f_pcuvty_flush_neigh_caches();
5827
5828 /* Establish BSSGP connection to the PCU */
5829 f_bssgp_establish();
5830 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5831
5832 /* Send PACKET RESOURCE REQUEST */
5833 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5834 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5835 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5836
5837 /* Start NACC from MS side */
5838 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5839 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5840
5841 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005842 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 +01005843 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5844 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5845 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5846 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5847 f_outbound_nacc_rim_tx_resp(info_ind);
5848 timer T := 1.0;
5849 T.start;
5850 alt {
5851 [] RIM.receive {
5852 setverdict(fail, "Received unexpected RIM message");
5853 f_shutdown(__BFILE__, __LINE__);
5854 }
5855 [] T.timeout {
5856 setverdict(pass);
5857 }
5858 }
5859
5860 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005861 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005862
5863 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5864 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5865 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5866 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5867 f_shutdown(__BFILE__, __LINE__);
5868 }
5869 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5870 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5871 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5872 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5873 }
5874
5875 f_shutdown(__BFILE__, __LINE__, final := true);
5876}
5877
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005878/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5879testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5880 var PollFnCtx pollctx;
5881 var GprsMS ms;
5882 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5883 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5884 var RlcmacDlBlock dl_block;
5885 var uint32_t sched_fn;
5886 var CtrlMessage rx_ctrl;
5887 var GsmArfcn req_arfcn := 862;
5888 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005889 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005890
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005891 if (use_old_ctrl_iface) {
5892 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5893 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5894 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005895
5896 /* Initialize NS/BSSGP side */
5897 f_init_bssgp();
5898 /* Initialize GPRS MS side */
5899 f_init_gprs_ms();
5900 ms := g_ms[0]; /* We only use first MS in this test */
5901
5902 /* Initialize the PCU interface abstraction */
5903 f_init_raw(testcasename(), info_ind);
5904
5905 /* Make sure we are not affected by full cache from previous tests */
5906 f_pcuvty_flush_neigh_caches();
5907
5908 /* Establish BSSGP connection to the PCU */
5909 f_bssgp_establish();
5910 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5911
5912 /* Send PACKET RESOURCE REQUEST */
5913 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5914 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5915 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5916
5917 /* Start NACC from MS side */
5918 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5919 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5920
5921 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005922 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 +01005923 /* RIM procedure: */
5924 as_outbound_nacc_rim_resolve(info_ind);
5925
5926 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5927 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5928 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5929
5930 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5931 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5932
5933 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5934 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5935 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5936 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5937 f_shutdown(__BFILE__, __LINE__);
5938 }
5939 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5940 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5941 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5942 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5943 }
5944}
5945
5946/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5947testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5948 var PollFnCtx pollctx;
5949 var GprsMS ms;
5950 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5951 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5952 var RlcmacDlBlock dl_block;
5953 var uint32_t sched_fn;
5954 var CtrlMessage rx_ctrl;
5955 var GsmArfcn req_arfcn := 862;
5956 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005957 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005958
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005959 if (use_old_ctrl_iface) {
5960 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5961 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5962 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005963
5964 /* Initialize NS/BSSGP side */
5965 f_init_bssgp();
5966 /* Initialize GPRS MS side */
5967 f_init_gprs_ms();
5968 ms := g_ms[0]; /* We only use first MS in this test */
5969
5970 /* Initialize the PCU interface abstraction */
5971 f_init_raw(testcasename(), info_ind);
5972
5973 /* Make sure we are not affected by full cache from previous tests */
5974 f_pcuvty_flush_neigh_caches();
5975
5976 /* Establish BSSGP connection to the PCU */
5977 f_bssgp_establish();
5978 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5979
5980 /* Send PACKET RESOURCE REQUEST */
5981 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5982 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5983 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5984
5985 /* Start NACC from MS side */
5986 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5987 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5988
5989 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005990 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 +01005991 /* RIM procedure: */
5992 as_outbound_nacc_rim_resolve(info_ind);
5993
5994 /* Announce SI back to MS, continue NACC procedure */
5995 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5996
5997 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5998 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5999
6000 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6001 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6002 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6003 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6004 f_shutdown(__BFILE__, __LINE__);
6005 }
6006 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6007 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6008 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6009 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6010 }
6011}
6012
6013/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
6014testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
6015 var PollFnCtx pollctx;
6016 var GprsMS ms;
6017 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6018 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6019 var RlcmacDlBlock dl_block;
6020 var uint32_t sched_fn;
6021 var CtrlMessage rx_ctrl;
6022 var GsmArfcn req_arfcn := 862;
6023 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006024 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006025
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006026 if (use_old_ctrl_iface) {
6027 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6028 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6029 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006030
6031 /* Initialize NS/BSSGP side */
6032 f_init_bssgp();
6033 /* Initialize GPRS MS side */
6034 f_init_gprs_ms();
6035 ms := g_ms[0]; /* We only use first MS in this test */
6036
6037 /* Initialize the PCU interface abstraction */
6038 f_init_raw(testcasename(), info_ind);
6039
6040 /* Make sure we are not affected by full cache from previous tests */
6041 f_pcuvty_flush_neigh_caches();
6042
6043 /* Establish BSSGP connection to the PCU */
6044 f_bssgp_establish();
6045 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6046
6047 /* Send PACKET RESOURCE REQUEST */
6048 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6049 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6050 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6051
6052 /* Start NACC from MS side */
6053 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6054 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6055
6056 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006057 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 +01006058 /* RIM procedure: */
6059 as_outbound_nacc_rim_resolve(info_ind);
6060
6061 /* Announce SI back to MS, continue NACC procedure */
6062 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6063
6064 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6065 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6066 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6067 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6068 f_shutdown(__BFILE__, __LINE__);
6069 }
6070 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
6071 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6072
6073 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6074 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6075 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6076 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6077 }
6078}
6079
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006080/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6081 * while waiting for CTRL resolution */
6082testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
6083 var PollFnCtx pollctx;
6084 var GprsMS ms;
6085 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6086 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6087 var RlcmacDlBlock dl_block;
6088 var uint32_t sched_fn;
6089 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006090 var charstring ctrl_var;
6091 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006092 var GsmArfcn req_arfcn := 862;
6093 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006094 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006095
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006096 if (use_old_ctrl_iface) {
6097 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6098 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6099 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006100
6101 /* Initialize NS/BSSGP side */
6102 f_init_bssgp();
6103 /* Initialize GPRS MS side */
6104 f_init_gprs_ms();
6105 ms := g_ms[0]; /* We only use first MS in this test */
6106
6107 /* Initialize the PCU interface abstraction */
6108 f_init_raw(testcasename(), info_ind);
6109
6110 /* Make sure we are not affected by full cache from previous tests */
6111 f_pcuvty_flush_neigh_caches();
6112
6113 /* Establish BSSGP connection to the PCU */
6114 f_bssgp_establish();
6115 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6116
6117 /* Send PACKET RESOURCE REQUEST */
6118 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6119 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6120 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6121
6122 /* Start NACC from MS side */
6123 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6124 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6125
6126 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006127 if (use_old_ctrl_iface) {
6128 f_ipa_ctrl_wait_link_up();
6129 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
6130 int2str(info_ind.lac) & "." &
6131 int2str(info_ind.cell_id) & "." &
6132 int2str(req_arfcn) & "." &
6133 int2str(req_bsic);
6134 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
6135 } else {
6136 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
6137 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006138 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
6139 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6140 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6141 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006142 if (use_old_ctrl_iface) {
6143 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
6144 } else {
6145 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
6146 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006147 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006148 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 +01006149
6150 /* And finally everything continues as usual with RIN procedure */
6151 as_outbound_nacc_rim_resolve(info_ind);
6152
6153 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006154 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006155
6156 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6157 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6158 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6159 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6160 f_shutdown(__BFILE__, __LINE__);
6161 }
6162 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6163 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6164 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6165 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6166 }
6167
6168 f_shutdown(__BFILE__, __LINE__, final := true);
6169}
6170
6171/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6172 * while waiting for SI resolution */
6173testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
6174 var PollFnCtx pollctx;
6175 var GprsMS ms;
6176 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6177 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6178 var RlcmacDlBlock dl_block;
6179 var uint32_t sched_fn;
6180 var CtrlMessage rx_ctrl;
6181 var GsmArfcn req_arfcn := 862;
6182 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006183 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006184
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006185 if (use_old_ctrl_iface) {
6186 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6187 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6188 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006189
6190 /* Initialize NS/BSSGP side */
6191 f_init_bssgp();
6192 /* Initialize GPRS MS side */
6193 f_init_gprs_ms();
6194 ms := g_ms[0]; /* We only use first MS in this test */
6195
6196 /* Initialize the PCU interface abstraction */
6197 f_init_raw(testcasename(), info_ind);
6198
6199 /* Make sure we are not affected by full cache from previous tests */
6200 f_pcuvty_flush_neigh_caches();
6201
6202 /* Establish BSSGP connection to the PCU */
6203 f_bssgp_establish();
6204 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6205
6206 /* Send PACKET RESOURCE REQUEST */
6207 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6208 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6209 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6210
6211 /* Start NACC from MS side */
6212 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6213 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6214
6215 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006216 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 +01006217 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
6218 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
6219 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6220 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6221 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
6222 f_outbound_nacc_rim_tx_resp(info_ind);
6223
6224 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006225 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 +01006226
6227 /* And finally everything continues as usual with RIN procedure */
6228 as_outbound_nacc_rim_resolve(info_ind);
6229
6230 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006231 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006232
6233 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6234 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6235 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6236 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6237 f_shutdown(__BFILE__, __LINE__);
6238 }
6239 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6240 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6241 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6242 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6243 }
6244
6245 f_shutdown(__BFILE__, __LINE__, final := true);
6246}
6247
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006248/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6249 * while sending Pkt Neigh Data Change */
6250testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6251 var PollFnCtx pollctx;
6252 var GprsMS ms;
6253 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6254 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6255 var RlcmacDlBlock dl_block;
6256 var uint32_t sched_fn;
6257 var CtrlMessage rx_ctrl;
6258 var GsmArfcn req_arfcn := 862;
6259 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006260 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006261
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006262 if (use_old_ctrl_iface) {
6263 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6264 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6265 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006266
6267 /* Initialize NS/BSSGP side */
6268 f_init_bssgp();
6269 /* Initialize GPRS MS side */
6270 f_init_gprs_ms();
6271 ms := g_ms[0]; /* We only use first MS in this test */
6272
6273 /* Initialize the PCU interface abstraction */
6274 f_init_raw(testcasename(), info_ind);
6275
6276 /* Make sure we are not affected by full cache from previous tests */
6277 f_pcuvty_flush_neigh_caches();
6278
6279 /* Establish BSSGP connection to the PCU */
6280 f_bssgp_establish();
6281 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6282
6283 /* Send PACKET RESOURCE REQUEST */
6284 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6285 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6286 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6287
6288 /* Start NACC from MS side */
6289 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6290 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6291
6292 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006293 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 +01006294 /* RIM procedure: */
6295 as_outbound_nacc_rim_resolve(info_ind);
6296
6297 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6298 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6299 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6300 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6301
6302 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006303 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 +01006304 /* RIM procedure: */
6305 as_outbound_nacc_rim_resolve(info_ind);
6306 /* Transmit SI back to MS */
6307 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6308
6309 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6310 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6311 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6312 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6313 f_shutdown(__BFILE__, __LINE__);
6314 }
6315 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6316 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6317 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6318 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6319 }
6320}
6321
6322/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6323testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6324 var PollFnCtx pollctx;
6325 var GprsMS ms;
6326 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6327 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6328 var RlcmacDlBlock dl_block;
6329 var uint32_t sched_fn;
6330 var CtrlMessage rx_ctrl;
6331 var GsmArfcn req_arfcn := 862;
6332 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006333 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006334
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006335 if (use_old_ctrl_iface) {
6336 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6337 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6338 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006339
6340 /* Initialize NS/BSSGP side */
6341 f_init_bssgp();
6342 /* Initialize GPRS MS side */
6343 f_init_gprs_ms();
6344 ms := g_ms[0]; /* We only use first MS in this test */
6345
6346 /* Initialize the PCU interface abstraction */
6347 f_init_raw(testcasename(), info_ind);
6348
6349 /* Make sure we are not affected by full cache from previous tests */
6350 f_pcuvty_flush_neigh_caches();
6351
6352 /* Establish BSSGP connection to the PCU */
6353 f_bssgp_establish();
6354 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6355
6356 /* Send PACKET RESOURCE REQUEST */
6357 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6358 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6359 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6360
6361 /* Start NACC from MS side */
6362 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6363 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6364
6365 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006366 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 +01006367 /* RIM procedure: */
6368 as_outbound_nacc_rim_resolve(info_ind);
6369
6370 /* Announce SI back to MS, continue NACC procedure */
6371 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6372
6373 /* trigger a Pkt Cell Change Notif with different tgt cell */
6374 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6375 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6376
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006377 /* It should trigger RAC_CI resolution to start again: */
6378 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6379
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006380 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6381 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6382
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006383 /* RIM procedure: */
6384 as_outbound_nacc_rim_resolve(info_ind);
6385 /* Transmit SI back to MS */
6386 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6387
6388 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6389 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6390 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6391 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6392 f_shutdown(__BFILE__, __LINE__);
6393 }
6394 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6395 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6396 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6397 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6398 }
6399}
6400
6401/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6402testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6403 var PollFnCtx pollctx;
6404 var GprsMS ms;
6405 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6406 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6407 var RlcmacDlBlock dl_block;
6408 var uint32_t sched_fn;
6409 var CtrlMessage rx_ctrl;
6410 var GsmArfcn req_arfcn := 862;
6411 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006412 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006413
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006414 if (use_old_ctrl_iface) {
6415 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6416 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6417 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006418
6419 /* Initialize NS/BSSGP side */
6420 f_init_bssgp();
6421 /* Initialize GPRS MS side */
6422 f_init_gprs_ms();
6423 ms := g_ms[0]; /* We only use first MS in this test */
6424
6425 /* Initialize the PCU interface abstraction */
6426 f_init_raw(testcasename(), info_ind);
6427
6428 /* Make sure we are not affected by full cache from previous tests */
6429 f_pcuvty_flush_neigh_caches();
6430
6431 /* Establish BSSGP connection to the PCU */
6432 f_bssgp_establish();
6433 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6434
6435 /* Send PACKET RESOURCE REQUEST */
6436 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6437 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6438 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6439
6440 /* Start NACC from MS side */
6441 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6442 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6443
6444 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006445 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 +01006446 /* RIM procedure: */
6447 as_outbound_nacc_rim_resolve(info_ind);
6448
6449 /* Announce SI back to MS, continue NACC procedure */
6450 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6451
6452 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6453 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6454 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6455 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6456 f_shutdown(__BFILE__, __LINE__);
6457 }
6458
6459 /* trigger a Pkt Cell Change Notif with different tgt cell */
6460 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6461 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6462
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006463 /* It should trigger RAC_CI resolution to start again: */
6464 /* When using new PCUIF interface for resolution, we must
6465 * PCUIF.receive() here since that's the first message in the PCUIF
6466 * queue that PCU will have sent. Calling other functions doing
6467 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6468 * due to unexpected message receive. */
6469 if (not use_old_ctrl_iface) {
6470 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6471 }
6472
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006473 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6474 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6475 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6476 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6477 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006478
6479 /* When using CTRL interface, we must schedule the ACK before (see
6480 * above) blocking here waiting for the resoltion, otherwise we'll be
6481 * too late scheduling by the time the resolution is done. */
6482 if (use_old_ctrl_iface) {
6483 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6484 }
6485
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006486 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6487 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6488
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006489 /* RIM procedure: */
6490 as_outbound_nacc_rim_resolve(info_ind);
6491 /* Transmit SI back to MS */
6492 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6493
6494 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6495 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6496 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6497 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6498 f_shutdown(__BFILE__, __LINE__);
6499 }
6500 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6501 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6502 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6503 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6504 }
6505}
6506
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006507/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6508testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6509 var PollFnCtx pollctx;
6510 var GprsMS ms;
6511 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6512 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6513 var RlcmacDlBlock dl_block;
6514 var uint32_t sched_fn, dl_fn;
6515 var CtrlMessage rx_ctrl;
6516 var GsmArfcn req_arfcn := 862;
6517 var uint6_t req_bsic := 43;
6518 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006519 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006520
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006521 if (use_old_ctrl_iface) {
6522 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6523 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6524 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006525
6526 /* Initialize NS/BSSGP side */
6527 f_init_bssgp();
6528 /* Initialize GPRS MS side */
6529 f_init_gprs_ms();
6530 ms := g_ms[0]; /* We only use first MS in this test */
6531
6532 /* Initialize the PCU interface abstraction */
6533 f_init_raw(testcasename(), info_ind);
6534
6535 /* Make sure we are not affected by full cache from previous tests */
6536 f_pcuvty_flush_neigh_caches();
6537
6538 /* Establish BSSGP connection to the PCU */
6539 f_bssgp_establish();
6540 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6541
6542 /* Send PACKET RESOURCE REQUEST */
6543 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6544 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6545 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6546
6547 /* Start NACC from MS side */
6548 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6549 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6550
6551 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006552 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 +01006553 /* RIM procedure: */
6554 as_outbound_nacc_rim_resolve(info_ind);
6555
6556 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6557 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6558 f_sleep(0.1);
6559 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6560 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6561
6562 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6563 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6564 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6565 * Data with unassigned DL TBF in line above): */
6566 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6567 /* Continue receiving Pkt Cell Neighbor Data */
6568 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6569
6570 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6571 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6572 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6573 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6574 f_shutdown(__BFILE__, __LINE__);
6575 }
6576 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6577 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6578 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6579 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6580 }
6581
6582 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6583 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6584 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6585 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6586 f_dl_block_ack_fn(dl_block, dl_fn));
6587}
6588
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006589
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006590function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6591runs on RAW_PCU_Test_CT
6592{
6593 var template (value) RAN_Information_Request_RIM_Container req_cont;
6594 var template (value) PDU_BSSGP bssgp_rim_pdu;
6595 var template PDU_BSSGP bssgp_rim_pdu_expect;
6596 var template RAN_Information_RIM_Container rim_cont_expect;
6597 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006598
6599 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006600 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 +01006601 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006602 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 +01006603 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006604 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);
6605 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006606 f_sleep(1.0);
6607
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006608 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006609
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006610 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6611 ts_RIM_Sequence_Number(1),
6612 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6613 ts_RIM_Protocol_Version_Number(1),
6614 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6615 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006616 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6617 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006618
6619 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6620 tr_RIM_Sequence_Number(1),
6621 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6622 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006623 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 +01006624 omit);
6625
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006626 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6627 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006628 rim_cont_expect);
6629 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006630 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006631 T.start;
6632 alt {
6633 [] RIM.receive(bssgp_rim_pdu_expect) { }
6634 [] RIM.receive {
6635 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6636 }
6637 [] T.timeout {
6638 setverdict(fail, "No BSSGP RIM PDU received");
6639 mtc.stop;
6640 }
6641 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006642}
6643/* Send a RIM RAN info request to the PCU and verify the response, we expect
6644 * getting the system information back which we have transfered to the PCU via
6645 * PCUIF on startup. */
6646testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6647 /* Initialize NS/BSSGP side */
6648 f_init_bssgp();
6649
6650 /* Initialize the PCU interface abstraction */
6651 f_init_raw(testcasename());
6652
6653 /* Establish BSSGP connection to the PCU */
6654 f_bssgp_establish();
6655
6656 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6657 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6658
6659 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6660 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6661
6662 f_shutdown(__BFILE__, __LINE__, final := true);
6663}
6664
6665/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6666 * Routing information, to verify PCU handles that kind of address just fine
6667 */
6668testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6669 /* Initialize NS/BSSGP side */
6670 f_init_bssgp();
6671
6672 /* Initialize the PCU interface abstraction */
6673 f_init_raw(testcasename());
6674
6675 /* Establish BSSGP connection to the PCU */
6676 f_bssgp_establish();
6677
6678 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6679 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6680
6681 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6682 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006683
6684 f_shutdown(__BFILE__, __LINE__, final := true);
6685}
6686
6687/* Same as above, but in this case we simulate the rare case in which the PCU
6688 * has no system information available. We expect getting a response back but
6689 * with no system information inside. */
6690testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006691 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006692 var PCUIF_Message pcu_msg;
6693 timer T := 2.0;
6694
6695 /* Initialize NS/BSSGP side */
6696 f_init_bssgp();
6697
6698 /* Initialize the PCU interface abstraction */
6699 f_init_raw(testcasename(), info_ind);
6700
6701 /* Establish BSSGP connection to the PCU */
6702 f_bssgp_establish();
6703
6704 /* Clear sysinfo from the PCU */
6705 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);
6706 BTS.send(si1_data_ind);
6707 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);
6708 BTS.send(si3_data_ind);
6709 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);
6710 BTS.send(si16_data_ind);
6711 f_sleep(1.0);
6712
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006713 var RIM_Routing_Address dst_addr;
6714 var RIM_Routing_Address src_addr;
6715 var template (value) RAN_Information_Request_RIM_Container req_cont;
6716 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006717 var template PDU_BSSGP bssgp_rim_pdu_expect;
6718 var template RAN_Information_RIM_Container rim_cont_expect;
6719
6720 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 +01006721 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6722 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006723
6724 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6725 ts_RIM_Sequence_Number(1),
6726 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6727 ts_RIM_Protocol_Version_Number(1),
6728 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6729 omit);
6730 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6731 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6732 req_cont);
6733
6734
6735 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6736 tr_RIM_Sequence_Number(1),
6737 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6738 tr_RIM_Protocol_Version_Number(1),
6739 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6740 omit);
6741
6742 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6743 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6744 rim_cont_expect);
6745 RIM.send(bssgp_rim_pdu);
6746 T.start;
6747 alt {
6748 [] RIM.receive(bssgp_rim_pdu_expect) { }
6749 [] RIM.receive {
6750 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6751 }
6752 [] T.timeout {
6753 setverdict(fail, "No BSSGP RIM PDU received");
6754 mtc.stop;
6755 }
6756 }
6757
6758 f_shutdown(__BFILE__, __LINE__, final := true);
6759}
6760
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006761/* 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 +02006762testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6763 var PCUIF_info_ind info_ind;
6764 var template (value) TsTrxBtsNum nr;
6765 var RlcmacDlBlock dl_block;
6766 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006767 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006768 timer T;
6769
6770 /* Initialize NS/BSSGP side */
6771 f_init_bssgp();
6772
6773 info_ind := valueof(ts_PCUIF_INFO_default);
6774 /* The 2 first TRX are enabled. */
6775 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6776 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6777 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6778
6779 /* Initialize the PCU interface abstraction */
6780 f_init_raw(testcasename(), info_ind);
6781
6782 /* Establish BSSGP connection to the PCU */
6783 f_bssgp_establish();
6784
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006785 for (ts := 0; ts < 2; ts := ts + 1) {
6786 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006787
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006788 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6789 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6790 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6791 T.start(0.5);
6792 alt {
6793 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6794 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6795 omit)) -> value data_msg {
6796 setverdict(pass);
6797 T.stop;
6798 }
6799 [] as_rx_fail_dummy(nr);
6800 [] BTS.receive {
6801 setverdict(fail, "Unexpected block from BTS");
6802 f_shutdown(__BFILE__, __LINE__);
6803 }
6804 [] T.timeout {
6805 setverdict(fail, "Expected IDLE block from BTS");
6806 f_shutdown(__BFILE__, __LINE__);
6807 }
6808 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006809 }
6810
6811 f_shutdown(__BFILE__, __LINE__, final := true);
6812}
6813
Oliver Smith3d174882021-09-03 11:38:51 +02006814/* Test stats for available and occupied PDCHs */
6815testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6816 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6817 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6818
6819 /* Initialize NS/BSSGP side */
6820 f_init_bssgp();
6821
Oliver Smithedcded22021-09-14 09:26:55 +02006822 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6823 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6824 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6825 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6826 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6827 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006828
Oliver Smith72d0c692021-09-08 10:03:52 +02006829 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006830 f_init_gprs_ms(4);
6831
6832 /* Initialize the PCU interface abstraction */
6833 f_init_raw(testcasename(), info_ind);
6834
6835 /* Reset stats */
6836 f_statsd_reset();
6837
6838 /* Establish BSSGP */
6839 f_bssgp_establish();
6840
6841 /* 8 PDCHs available, 0 occupied */
6842 var StatsDExpects expect := {
6843 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006844 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6845 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6846 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006847 };
6848 f_statsd_expect(expect);
6849
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006850 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006851 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006852 f_ms_establish_ul_tbf(g_ms[0]);
6853 f_ms_establish_ul_tbf(g_ms[1]);
6854 f_ms_establish_ul_tbf(g_ms[2]);
6855 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 +02006856
6857 /* 4 PDCHs occupied */
6858 expect := {
6859 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006860 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6861 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6862 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006863 };
6864 f_statsd_expect(expect);
6865
6866 f_shutdown(__BFILE__, __LINE__, final := true);
6867}
6868
Oliver Smithf04762d2021-09-14 17:20:38 +02006869/* Test stats for available and occupied PDCHs, for MS which is not known by
6870 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6871 * data arrives from SGSN) */
6872function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6873 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6874 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6875
6876 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6877 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6878 gprsmultislotclass := '00001'B,
6879 gprsextendeddynalloccap := '0'B
6880 };
6881 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6882 egprsmultislotclass := '00001'B,
6883 egprsextendeddynalloccap := '0'B
6884 };
6885 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6886 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6887 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6888 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6889
6890 /* Initialize NS/BSSGP side */
6891 f_init_bssgp();
6892
6893 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6894 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6895 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6896 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6897 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6898 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6899
6900 /* Allocate 1 GprsMS instance */
6901 f_init_gprs_ms(1);
6902
6903 /* Initialize the PCU interface abstraction */
6904 f_init_raw(testcasename(), info_ind);
6905
6906 /* Reset stats */
6907 f_statsd_reset();
6908
6909 /* Establish BSSGP */
6910 f_bssgp_establish();
6911
6912 /* 8 PDCHs available, 0 occupied */
6913 var StatsDExpects expect := {
6914 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6915 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6916 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6917 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6918 };
6919 f_statsd_expect(expect);
6920
6921 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6922 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6923
6924 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6925 var octetstring data := f_rnd_octstring(1400);
6926 if (egprs) {
6927 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6928 } else {
6929 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6930 }
6931 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6932
6933 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6934 f_sleep(X2002);
6935
6936 /* 1 PDCH occupied */
6937 if (egprs) {
6938 expect := {
6939 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6940 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6941 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6942 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6943 };
6944 } else {
6945 expect := {
6946 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6947 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6948 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6949 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6950 };
6951 }
6952 f_statsd_expect(expect);
6953
6954 /* Clean up */
6955 f_shutdown(__BFILE__, __LINE__, final := true);
6956}
6957testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6958 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6959}
6960testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6961 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6962}
6963
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006964/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6965testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
6966 var PCUIF_info_ind info_ind;
6967 var template IARRestOctets rest;
6968 var BIT11 ra11;
6969
6970 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006971
6972 /* Only the first TRX is enabled. */
6973 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
6974 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6975
6976 /* Initialize the PCU interface abstraction */
6977 f_init_raw(testcasename(), info_ind);
6978 f_statsd_reset();
6979
6980 var EGPRSPktChRequest req := {
6981 one_phase := {
6982 tag := '0'B,
6983 multislot_class := '10101'B,
6984 priority := '01'B,
6985 random_bits := '101'B
6986 }
6987 };
6988
6989 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
6990 for (var integer i := 0; i < 7; i := i + 1) {
6991 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
6992 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
6993 }
6994
6995 ra11 := enc_EGPRSPktChRequest2bits(req);
6996 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
6997
6998 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01006999 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007000
7001 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
7002 f_sleep(2.0);
7003 var StatsDExpects expect := {
7004 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
7005 };
7006 f_statsd_expect(expect);
7007
7008 f_shutdown(__BFILE__, __LINE__, final := true);
7009}
7010
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007011control {
7012 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01007013 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007014 execute( TC_ta_ptcch_idle() );
7015 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02007016 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007017 execute( TC_ta_idle_dl_tbf_ass() );
7018 execute( TC_ta_ptcch_ul_multi_tbf() );
7019 execute( TC_cs_lqual_ul_tbf() );
7020 execute( TC_cs_initial_ul() );
7021 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01007022 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01007023 execute( TC_cs_max_dl() );
7024 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01007025 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01007026 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01007027 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01007028 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02007029 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01007030 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02007031 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01007032 execute( TC_x2031_t3191() );
7033 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007034 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01007035 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01007036 execute( TC_t3172_wait_ind_size0() );
7037 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02007038 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02007039 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02007040 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007041 execute( TC_mo_ping_pong() );
7042 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02007043 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007044 execute( TC_mt_ping_pong() );
7045 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007046 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007047 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07007048 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02007049 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01007050 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02007051 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007052 execute( TC_paging_cs_from_bts() );
7053 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
7054 execute( TC_paging_cs_from_sgsn_sign() );
7055 execute( TC_paging_cs_from_sgsn_ptp() );
7056 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
7057 execute( TC_paging_ps_from_sgsn_sign() );
7058 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01007059 execute( TC_paging_pch_timeout() );
7060
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07007061 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
7062 execute( TC_paging_cs_multi_ms_imsi() );
7063 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02007064 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
7065 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01007066 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
7067 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007068
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007069 execute( TC_ul_tbf_finished_pkt_dl_ass_pch() );
Pau Espin Pedrol99e00b42022-10-28 13:28:52 +02007070 execute( TC_ul_tbf_1phase_while_dl_ass_pch() );
7071 execute( TC_ul_tbf_2phase_while_dl_ass_pch() );
Pau Espin Pedrol0b6b0d02022-10-25 21:21:02 +02007072
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007073 /* EGPRS specific test cases */
7074 execute( TC_egprs_pkt_chan_req_signalling() );
7075 execute( TC_egprs_pkt_chan_req_one_phase() );
7076 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07007077 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07007078 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07007079 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02007080
7081 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07007082
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007083 /* Immediate Assignment on AGCH/PCH */
7084 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
7085 execute( TC_pcuif_fh_imm_ass_ul() );
7086 execute( TC_pcuif_fh_imm_ass_dl() );
7087 /* Packet Uplink/Downlink Assignment on PACCH */
7088 execute( TC_pcuif_fh_pkt_ass_ul() );
7089 execute( TC_pcuif_fh_pkt_ass_dl() );
7090 execute( TC_multitrx_multims_alloc() );
7091 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
7092 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
7093 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02007094 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02007095 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01007096 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
7097 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01007098
Pau Espin Pedrole1303052020-11-16 11:13:51 +01007099 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07007100
7101 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01007102 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01007103 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01007104 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01007105 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01007106 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01007107 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01007108 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
7109 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01007110 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
7111 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
7112 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01007113 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
7114 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01007115 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
7116 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
7117 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01007118 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02007119 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
7120 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
7121 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
7122 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007123
7124 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02007125 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01007126 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02007127
7128 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02007129
7130 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02007131 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
7132 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01007133 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02007134}
7135
Harald Weltea419df22019-03-21 17:23:04 +01007136}