blob: 6c599171a79042fefb9ca49db2189d73d1175d1c [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;
25
26import from Osmocom_VTY_Functions all;
27import from TELNETasp_PortType all;
28
29import from MobileL3_GMM_SM_Types all;
30import from RLCMAC_CSN1_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020031import from RLCMAC_CSN1_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020032import from RLCMAC_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020033import from RLCMAC_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020034
35import from MobileL3_CommonIE_Types all;
36import from L3_Templates all;
37
38import from NS_Types all;
39import from BSSGP_Types all;
40import from Osmocom_Gb_Types all;
41
42import from BSSGP_Emulation all; /* BssgpConfig */
43import from NS_Emulation all; /* NSConfiguration */
44
45import from UD_Types all;
46import from PCUIF_Types all;
47import from PCUIF_CodecPort all;
48import from PCUIF_Components all;
49import from IPL4asp_Types all;
50import from Native_Functions all;
51import from SGSN_Components all;
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +020052import from GPRS_Components all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020053
Daniel Willmann535aea62020-09-21 13:27:08 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010059import from IPA_Emulation all;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +010060import from Osmocom_CTRL_Types all;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010061import from Osmocom_CTRL_Adapter all;
62import from Osmocom_CTRL_Functions all;
63
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020064modulepar {
65 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
66
67 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Daniel Willmann535aea62020-09-21 13:27:08 +020068
69 charstring mp_pcu_statsd_ip := "127.0.0.1";
70 integer mp_pcu_statsd_port := 8125;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010071
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +020072 charstring mp_ctrl_neigh_ip := ""; /* Use new PCUIF over IPA multiplex for Neigh Addr Resolution */
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010073 integer mp_ctrl_neigh_port := 4248;
Oliver Smith61b4e732021-07-22 08:14:29 +020074
75 boolean mp_osmo_pcu_newer_than_0_9_0 := true; /* Drop after OsmoPCU > 0.9.0 was released */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020076}
77
78
79/* 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 +010080friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
81:= {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070082 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010083 flags := flags,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +010084 trx := ts_PCUIF_InfoTrxs_def(GPRS_Components.mp_base_arfcn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020085 bsic := 7,
86 mcc := 262,
87 mnc := 42,
88 mnc_3_digits := 0,
89 lac := 13135,
90 rac := 0,
91 nsei := mp_nsconfig.nsei,
92 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
93 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
94 cell_id := 20960,
95 repeat_time := 5 * 50,
96 repeat_count := 3,
Harald Welte5339b2e2020-10-04 22:52:56 +020097 bvci := mp_gb_cfg.bvc[0].bvci,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020098 t3142 := 20,
99 t3169 := 5,
100 t3191 := 5,
101 t3193_10ms := 160,
102 t3195 := 5,
Pau Espin Pedrol76de1662021-03-01 17:40:58 +0100103 n3101 := 10,
104 n3103 := 4,
105 n3105 := 8,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200106 cv_countdown := 15,
107 dl_tbf_ext := 250 * 10, /* ms */
108 ul_tbf_ext := 250 * 10, /* ms */
109 initial_cs := 2,
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100110 initial_mcs := 1,
Harald Welte90f19742020-11-06 19:34:40 +0100111 nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
112 local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
113 remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +0100114 remote_addr := f_PCUIF_RemoteAddr(
Harald Welte90f19742020-11-06 19:34:40 +0100115 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 +0200116}
117
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100118/* Passed in RAN-INFO message from emulated neighbor using RIM */
119const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
120const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
121const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
122const octetstring si_default := si1_default & si3_default & si13_default;
123
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +0100124const MultislotCap_GPRS mscap_gprs_def := {
125 gprsmultislotclass := '00011'B,
126 gprsextendeddynalloccap := '0'B
127};
128const MultislotCap_EGPRS mscap_egprs_def := {
129 egprsmultislotclass := '00011'B,
130 egprsextendeddynalloccap := '0'B
131};
132template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
133template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
134
135const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
136 gprsmultislotclass := '00011'B,
137 gprsextendeddynalloccap := '0'B
138};
139const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
140 egprsmultislotclass := '00011'B,
141 egprsextendeddynalloccap := '0'B
142};
143template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
144template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
145
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200146type record lqual_range {
147 /* component reference to the IPA_Client component used for RSL */
148 uint8_t low,
149 uint8_t high
150}
151
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100152type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700153 /* PCU interface abstraction component */
154 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700155
Daniel Willmann535aea62020-09-21 13:27:08 +0200156 /* StatsD */
157 var StatsD_Checker_CT vc_STATSD;
158
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200159 /* Connection to the PCUIF component */
160 port RAW_PCU_MSG_PT PCUIF;
161 /* VTY connection to the PCU */
162 port TELNETasp_PT PCUVTY;
163
164 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
165 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
166 {low := 5, high := 8},
167 {low := 7, high := 13},
168 {low := 12,high := 35}};
169 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
170 {low := 5, high := 8},
171 {low := 7, high := 13},
172 {low := 12,high := 15},
173 {low := 14, high := 17},
174 {low := 16, high := 18},
175 {low := 17,high := 20},
176 {low := 19, high := 24},
177 {low := 23,high := 35}};
178 var uint8_t g_cs_initial_dl := 1;
179 var uint8_t g_cs_initial_ul := 1;
180 var uint8_t g_mcs_initial_dl := 1;
181 var uint8_t g_mcs_initial_ul := 1;
182 var uint8_t g_cs_max_dl := 4;
183 var uint8_t g_cs_max_ul := 4;
184 var uint8_t g_mcs_max_dl := 9;
185 var uint8_t g_mcs_max_ul := 9;
186
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200187 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200188
189 /* Guard timeout */
190 timer g_T_guard := 60.0;
191};
192
193private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
194 [] g_T_guard.timeout {
195 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700196 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200197 }
198}
199
200private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
201 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
202 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
203
204 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
205 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
206}
207
208private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
209 var charstring cmd;
210
211 cmd := "cs link-quality-ranges" &
212 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
213 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
214 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
215 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
216 f_vty_config2(PCUVTY, {"pcu"}, cmd);
217
218 cmd := "mcs link-quality-ranges" &
219 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
220 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
221 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
222 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
223 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
224 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
225 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
226 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
227 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
228 f_vty_config2(PCUVTY, {"pcu"}, cmd);
229}
230
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100231private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
232 f_pcuvty_set_neigh_caches(0, 0);
233}
234
235private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
236runs on RAW_PCU_Test_CT {
237 if (neigh_cache_secs == -1) {
238 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
239 } else {
240 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
241 }
242 if (si_cache_secs == -1) {
243 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
244 } else {
245 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
246 }
247}
248
Pau Espin Pedrole8a94442021-11-15 17:05:46 +0100249private function f_pcuvty_set_timer(integer t, integer val)
250runs on RAW_PCU_Test_CT {
251 if (t >= 0) {
252 f_vty_config2(PCUVTY, {"pcu"}, "timer T" & int2str(t) & " " & int2str(val));
253 } else {
254 f_vty_config2(PCUVTY, {"pcu"}, "timer X" & int2str(t * -1) & " " & int2str(val));
255 }
256}
257
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100258private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200259 map(self:PCUVTY, system:PCUVTY);
260 f_vty_set_prompts(PCUVTY);
261 f_vty_transceive(PCUVTY, "enable");
262
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100263 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
264 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200265 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
266 } else {
267 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
268 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200269
270 if (g_force_two_phase_access) {
271 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
272 } else {
273 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
274 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200275}
276
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200277function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200278runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200279 /* Start the guard timer */
280 g_T_guard.start;
281 activate(as_Tguard_RAW());
282
283 /* Init PCU interface component */
Harald Welte5339b2e2020-10-04 22:52:56 +0200284 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200285 connect(vc_PCUIF:MTC, self:PCUIF);
286 map(vc_PCUIF:PCU, system:PCU);
287
288 /* Create one BTS component (we may want more some day) */
Harald Welte5339b2e2020-10-04 22:52:56 +0200289 vc_BTS := RAW_PCU_BTS_CT.create("BTS");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200290 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
291 connect(vc_BTS:TC, self:BTS);
292
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100293 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200294
Daniel Willmann535aea62020-09-21 13:27:08 +0200295 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
296 /* This is normally done in the ConnHdlr component, but here
297 * the Test_CT doubles as ConnHdlr */
298 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
299
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200300 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100301 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200302
303 /* Wait until the BTS is ready (SI13 negotiated) */
304 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
305}
306
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700307/* Register TLLI of each allocated GprsMS instance */
308private function f_multi_ms_bssgp_register()
309runs on RAW_PCU_Test_CT {
310 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
311 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
312 }
313}
314
315/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
316private function f_multi_ms_establish_tbf(boolean do_activate := false)
317runs on RAW_PCU_Test_CT {
318 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
319 /* Establish an Uplink TBF */
320 f_ms_establish_ul_tbf(g_ms[i]);
321
322 /* Send a random block, so this TBF becomes "active" */
323 if (do_activate) {
324 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100325 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700326 var octetstring dummy := f_rnd_octstring(12);
327 var RlcmacDlBlock dl_block;
328 var uint32_t poll_fn;
329
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200330 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 +0700331 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
332 }
333 }
334}
335
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100336private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
337 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
338runs on RAW_PCU_Test_CT return PollFnCtx {
339 var PollFnCtx pollctx;
340
341 /* Single block (two phase) packet access */
342 var uint16_t ra := bit2int(chan_req_sb);
343 if (g_force_two_phase_access) {
344 /* If 2phase access is enforced by the network, then let's
345 * request a One phase packet access, we'll receive a single block
346 * anyway
347 */
348 ra := bit2int(chan_req_def);
349 }
350
351 /* Establish an Uplink TBF */
352 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
353 f_ms_establish_ul_tbf(ms);
354
355 /* Make sure we've got an Uplink TBF assignment */
356 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
357 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
358 f_shutdown(__BFILE__, __LINE__);
359 }
360
361 /* Send PACKET RESOURCE REQUEST
362 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
363 */
364 if (istemplatekind(pkt_res_req, "omit")) {
365 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
366 }
367
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200368 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 +0100369 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100370 * overwrite the TS allocation on MS with info from new UL TBF:
371 */
372 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
373 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
374 return pollctx;
375}
376
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200377testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200378 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100379 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200380 timer T;
381
382 /* Initialize NS/BSSGP side */
383 f_init_bssgp();
384
385 /* Initialize the PCU interface abstraction */
386 f_init_raw(testcasename());
387
388 /* Establish BSSGP connection to the PCU */
389 f_bssgp_establish();
390
391 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
392
393 T.start(2.0);
394 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100395 [] 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 +0200396 setverdict(pass);
397 }
398 [] T.timeout {
399 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
400 }
401 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700402
403 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200404}
405
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100406/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
407testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
408 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200409 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100410 var RlcmacDlBlock dl_block;
411 var octetstring data := f_rnd_octstring(10);
412 var uint32_t sched_fn;
413 var uint32_t dl_fn;
414 var GprsMS ms;
415 timer T;
416
417 /* Initialize NS/BSSGP side */
418 f_init_bssgp();
419 /* Initialize GPRS MS side */
420 f_init_gprs_ms();
421 ms := g_ms[0]; /* We only use first MS in this test */
422
423 /* Initialize the PCU interface abstraction */
424 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
425
426 /* Establish BSSGP connection to the PCU */
427 f_bssgp_establish();
428 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
429
430 /* Establish an Uplink TBF */
431 f_ms_establish_ul_tbf(ms);
432
433 /* Send one UL block (with TLLI since we are in One-Phase Access
434 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200435 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 +0100436 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
437 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
438 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
439
440 /* UL block should be received in SGSN */
441 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
442
443 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
444 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
445 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
446
447 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
448 f_sleep(X2002);
449 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
450
451 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
452 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
453
454 T.start(2.0);
455 alt {
456 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
457 setverdict(pass);
458 }
459 [] T.timeout {
460 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
461 f_shutdown(__BFILE__, __LINE__);
462 }
463 }
464
465 /* Make sure we don't receive data for that TBF since it was released
466 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200467 f_pcuif_rx_data_req_pdtch(data_msg);
468 if (mp_osmo_pcu_newer_than_0_9_0 and data_msg.dl_block == omit) {
469 /* IDLE block, expected on new PCU versions */
470 } else if (not mp_osmo_pcu_newer_than_0_9_0 and match(data_msg.dl_block, tr_RLCMAC_DUMMY_CTRL())) {
471 /* Dummy RLCMAC block, expected on older PCU versions */
472 if (data_msg.dl_block.ctrl.mac_hdr.usf != USF_UNUSED) {
473 setverdict(fail, "Unexpected USF ", data_msg.dl_block.ctrl.mac_hdr.usf);
474 f_shutdown(__BFILE__, __LINE__);
475 }
476 } else {
477 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100478 f_shutdown(__BFILE__, __LINE__);
479 }
480
481 /* New data arrives, PCU should page the MS since no TBF active exists: */
482 /* Send some more data, it will never reach the MS */
483 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
484 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
485
486 f_shutdown(__BFILE__, __LINE__, final := true);
487}
488
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200489/* Test of correct Timing Advance at the time of TBF establishment
490 * (derived from timing offset of the Access Burst). */
491testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200492 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200493
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200494 /* Initialize GPRS MS side */
495 f_init_gprs_ms();
496 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200497 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100498 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200499
500 /* We cannot send too many TBF requests in a short time because
501 * at some point the PCU will fail to allocate a new TBF. */
502 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
503 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200504 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700505 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200506
507 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200508 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700509 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200510 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700511 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700512 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200513 }
514 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700515
516 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200517}
518
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200519/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
520 * sent in response to the first Uplink block after resource allocation. */
521testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
522 var GprsMS ms := valueof(t_GprsMS_def);
523 var PacketUlAckNack ul_ack_nack;
524 var PacketTimingAdvance pkt_ta;
525 var RlcmacDlBlock dl_block;
526 var uint32_t sched_fn;
527
528 /* Initialize NS/BSSGP side */
529 f_init_bssgp();
530
531 /* Initialize the PCU interface abstraction */
532 f_init_raw(testcasename());
533
534 /* Establish BSSGP connection to the PCU */
535 f_bssgp_establish();
536 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
537
538 /* Establish an Uplink TBF */
539 f_ms_establish_ul_tbf(ms);
540
541 /* In a busy network, there can be a significant delay between resource
542 * allocation (Packet Uplink Assignment above) and the actual time when
543 * the MS is allowed to transmit the first Uplink data block. */
544
545 /* Simulate a delay > 0 */
546 ms.ta := 2;
547
548 /* We're in One-Phase Access contention resoultion, include TLLI */
549 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
550 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
551
552 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
553 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
554 pkt_ta := ul_ack_nack.gprs.pkt_ta;
555 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
556 pkt_ta := ul_ack_nack.egprs.pkt_ta;
557 } else {
558 setverdict(fail, "PacketTimingAdvance IE is not present");
559 f_shutdown(__BFILE__, __LINE__);
560 }
561
562 if (not ispresent(pkt_ta.val)) {
563 setverdict(fail, "Timing Advance value is not present");
564 f_shutdown(__BFILE__, __LINE__);
565 } else if (pkt_ta.val != ms.ta) {
566 setverdict(fail, "Timing Advance mismatch: expected ",
567 ms.ta, ", but received ", pkt_ta.val);
568 f_shutdown(__BFILE__, __LINE__);
569 }
570}
571
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200572/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
573 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
574 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
575 * no active TBF exists at the moment of establishment (idle mode). */
576testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100577 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200578
579 /* Initialize NS/BSSGP side */
580 f_init_bssgp();
581
582 /* Initialize the PCU interface abstraction */
583 f_init_raw(testcasename());
584
585 /* Establish BSSGP connection to the PCU */
586 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100587 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200588
589 /* SGSN sends some DL data, PCU will initiate Packet Downlink
590 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100591 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
592 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200593
594 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
595 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
596 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100597 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700598 setverdict(fail, "Timing Advance value doesn't match");
599 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700600
601 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200602}
603
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200604/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200605 * while neither Uplink nor Downlink TBF is established. */
606testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100607 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200608 timer T;
609
610 /* Initialize the PCU interface abstraction */
611 f_init_raw(testcasename());
612
613 /* Sent an RTS.req for PTCCH/D */
614 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
615 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
616 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100617
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200618 T.start(5.0);
619 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200620 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
621 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
622 omit)) {
623 if (not mp_osmo_pcu_newer_than_0_9_0) {
624 setverdict(fail, "Expected PTCCH/D block instead of IDLE block");
625 f_shutdown(__BFILE__, __LINE__);
626 }
627 }
628 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
629 if (mp_osmo_pcu_newer_than_0_9_0) {
630 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
631 f_shutdown(__BFILE__, __LINE__);
632 }
633 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200634 [] BTS.receive(PCUIF_Message:?) { repeat; }
635 [] T.timeout {
636 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700637 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200638 }
639 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100640 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700641
642 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200643}
644
645/* Test of correct Timing Advance during an active Uplink TBF.
646 *
647 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
648 * are not continuous and there can be long time gaps between them. This happens
649 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
650 * significantly change between such rare Uplink transmissions, so GPRS introduces
651 * additional mechanisms to control Timing Advance, and thus reduce interference
652 * between neighboring TDMA time-slots.
653 *
654 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
655 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
656 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
657 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
658 * among with the initial Timing Advance value. And here PTCCH comes to play.
659 *
660 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
661 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
662 * continuously. To ensure continuous measurements of the signal propagation
663 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
664 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
665 *
666 * The purpose of this test case is to verify the assignment of Timing Advance
667 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
668 * first establishes several Uplink TBFs, but does not transmit any Uplink
669 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
670 * indications to the PCU, checking the correctness of two received PTCCH/D
671 * messages (period of PTCCH/D is two multi-frames).
672 */
673
674/* List of ToA values for Access Bursts to be sent on PTCCH/U,
675 * each ToA (Timing of Arrival) value is in units of 1/4 of
676 * a symbol (i.e. 1 symbol is 4 QTA units). */
677type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
678const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
679 0, 0, 0, 0,
680 0, 0, 0, 0,
681 0, 0, 0, 0,
682 0, 0, 0, 0
683};
684
685private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
686 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
687runs on RAW_PCU_Test_CT {
688 var RAW_PCU_Event event;
689 var integer ss;
690
691 /* Send Access Bursts on PTCCH/U for every TA Index */
692 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
693 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700694 if (ss < 0) { /* Shall not happen */
695 f_shutdown(__BFILE__, __LINE__);
696 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200697
698 log("Sending an Access Burst on PTCCH/U",
699 ", sub-slot=", ss, " (TAI)",
700 ", fn=", event.data.tdma_fn,
701 ", ToA=", toa_map[ss], " (QTA)");
702 /* TODO: do we care about RA and burst format? */
703 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
704 ra := oct2int('3A'O),
705 is_11bit := 0,
706 burst_type := BURST_TYPE_0,
707 fn := event.data.tdma_fn,
708 arfcn := 871,
709 qta := toa_map[ss],
710 sapi := PCU_IF_SAPI_PTCCH));
711 repeat;
712 }
713}
714
715private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
716 template PTCCHDownlinkMsg t_ta_msg)
717runs on RAW_PCU_Test_CT {
718 var PTCCHDownlinkMsg ta_msg;
719 var PCUIF_Message pcu_msg;
720 timer T;
721
722 /* First, send an RTS.req for the upcoming PTCCH/D block */
723 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
724 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
725 arfcn := 871, block_nr := 0));
726 T.start(2.0);
727 alt {
728 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
729 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
730 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
731 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
732 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
733 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
734 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
735 log("Rx PTCCH/D message: ", ta_msg);
736
737 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700738 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200739 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
740 }
741 }
742 [] BTS.receive { repeat; }
743 [] T.timeout {
744 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200745 }
746 }
747}
748
749testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
750 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200751 var GprsMS ms;
752
753 /* Initialize GPRS MS side */
754 f_init_gprs_ms();
755 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200756
757 /* Initialize the PCU interface abstraction */
758 f_init_raw(testcasename());
759
760 /* Enable forwarding of PTCCH/U TDMA events to us */
761 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
762
763 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
764 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200765 /* Establish an Uplink TBF */
766 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200767
768 /* We expect incremental TFI/USF assignment (dynamic allocation) */
769 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200770 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200771 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700772 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200773 }
774
775 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200776 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200777 setverdict(fail, "Failed to match Timing Advance Index for #", i);
778 /* Keep going, the current OsmoPCU does not assign TA Index */
779 }
780 }
781
782 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
783 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
784 for (var integer i := 0; i < 7; i := i + 1) {
785 /* ToA in units of 1/4 of a symbol */
786 toa_map[i] := (i + 1) * 7 * 4;
787 }
788
789 /* Now we have all 7 TBFs established in one-phase access mode,
790 * however we will not be sending any data on them. Instead, we
791 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
792 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
793 *
794 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
795 * time-slots, so at the moment of scheduling a PTCCH/D block
796 * the PCU has odd number of PTCCH/U Access Bursts received. */
797 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
798 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
799 /* Other values are not known (yet) */
800 tai3_ta := ?));
801 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
802 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
803 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
804 /* Other values are out of our interest */
805 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700806
807 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200808}
809
810/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
811 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
812 *
813 * NOTE: the ranges are intentionally overlapping because OsmoPCU
814 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
815private template integer CS1_lqual_dB_range := (-infinity .. 6);
816private template integer CS2_lqual_dB_range := (5 .. 8);
817private template integer CS3_lqual_dB_range := (7 .. 13);
818private template integer CS4_lqual_dB_range := (12 .. infinity);
819
820testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200821 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200822 var GprsMS ms;
823 var uint32_t unused_fn, sched_fn;
824 var uint4_t cv;
825
826 /* Initialize GPRS MS side */
827 f_init_gprs_ms();
828 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200829
830 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100831 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200832
833 f_pcuvty_set_allowed_cs_mcs();
834 f_pcuvty_set_link_quality_ranges();
835
836 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200837 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200838
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200839
840 /* The actual / old link quality values. We need to keep track of the old
841 * (basically previous) link quality value, because OsmoPCU actually
842 * changes the coding scheme if not only the actual, but also the old
843 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200844 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200846
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200847 /* Send one UL block (with TLLI since we are in One-Phase Access
848 contention resoultion) and make sure it is ACKED fine. */
849 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
850 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200851 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true, fn := ms.ul_tbf.start_time_fn)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200852 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
853 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
854 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200855
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200856 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
857 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200858 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200859 lqual_old := ms.lqual_cb;
860 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200861
862 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200863 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
864 if (i > g_bs_cv_max) {
865 cv := 15;
866 } else {
867 cv := i;
868 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200869
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200870 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
871
872 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
873 f_rx_rlcmac_dl_block(dl_block, unused_fn);
874 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
875 continue;
876 }
877 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
878 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
879 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
880 f_shutdown(__BFILE__, __LINE__);
881 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200882
883 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
884 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
885
886 /* Match the received Channel Coding Command. Since we are increasing
887 * the link quality value on each iteration and not decreasing, there
888 * is no need to check the both old and current link quality values. */
889 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200890 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200891 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
892 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
893 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
894 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
895 }
896
897 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
898 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200899 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200900 }
901 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700902
903 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200904}
905
906/* Test the max UL CS set by VTY works fine */
907testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200908 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200909 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200910 var uint32_t unused_fn, sched_fn;
911 var GprsMS ms;
912
913 /* Initialize GPRS MS side */
914 f_init_gprs_ms();
915 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200916
917 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100918 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200919
920 /* Set initial UL CS to 3 */
921 g_cs_initial_ul := 3;
922 f_pcuvty_set_allowed_cs_mcs();
923 f_pcuvty_set_link_quality_ranges();
924
925 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200926 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200927
928 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200929 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200930
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200931 /* Send one UL block (with TLLI since we are in One-Phase Access
932 contention resoultion) and make sure it is ACKED fine. */
933 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
934 /* 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 +0200935 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 +0200936 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
937 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
938 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200939
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200940 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
941 while (true) {
942 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
943 f_rx_rlcmac_dl_block(dl_block, unused_fn);
944 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
945 continue;
946 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200947
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200948 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
949 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
950 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
951 f_shutdown(__BFILE__, __LINE__);
952 break;
953 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200954
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200955 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200956 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200957 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200958 if (last_ch_coding != CH_CODING_CS3) {
959 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200960 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200961 }
962
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200963 /* Remaining UL blocks are used to make sure regardless of initial
964 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200965 /* 0 dB, make sure we downgrade CS */
966 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200967 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200968 f_ms_tx_ul_data_block_multi(ms, 5);
969 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
970 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
971 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200972
973 if (last_ch_coding != CH_CODING_CS1) {
974 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200975 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200976 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700977
978 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200979}
980
981/* Test the max UL CS set by VTY works fine */
982testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200983 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200984 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200985 var uint32_t unused_fn, sched_fn;
986 var GprsMS ms;
987
988 /* Initialize GPRS MS side */
989 f_init_gprs_ms();
990 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200991
992 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100993 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200994
995 /* Set maximum allowed UL CS to 3 */
996 g_cs_max_ul := 3;
997 f_pcuvty_set_allowed_cs_mcs();
998 f_pcuvty_set_link_quality_ranges();
999
1000 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001001 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001002
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001003 /* Send one UL block (with TLLI since we are in One-Phase Access
1004 contention resoultion) and make sure it is ACKED fine. */
1005 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1006 /* 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 +02001007 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 +02001008 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1009 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1010 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001011
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001012 ms.lqual_cb := 40*10; /* 40 dB */
1013 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001014
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001015 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1016 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001017
1018 if (last_ch_coding != CH_CODING_CS3) {
1019 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001020 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001021 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001022
1023 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001024}
1025
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001026/* Test the initial DL CS set by VTY works fine */
1027testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1028 var octetstring data := f_rnd_octstring(10);
1029 var CodingScheme exp_dl_cs_mcs;
1030 var RlcmacDlBlock dl_block;
1031 var uint32_t poll_fn;
1032 var GprsMS ms;
1033
1034 /* Initialize NS/BSSGP side */
1035 f_init_bssgp();
1036 /* Initialize GPRS MS side */
1037 f_init_gprs_ms();
1038 ms := g_ms[0]; /* We only use first MS in this test */
1039
1040 /* Initialize the PCU interface abstraction */
1041 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1042
1043 /* Set initial allowed DL CS to 3 */
1044 g_cs_initial_dl := 3;
1045 exp_dl_cs_mcs := CS_3;
1046 /* Set maximum allowed UL CS to 4 */
1047 g_cs_max_dl := 4;
1048 f_pcuvty_set_allowed_cs_mcs();
1049 f_pcuvty_set_link_quality_ranges();
1050
1051 /* Establish BSSGP connection to the PCU */
1052 f_bssgp_establish();
1053 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1054
1055 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1056 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1057 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1058
1059 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1060 f_sleep(X2002);
1061 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1062
1063 /* ACK the DL block */
1064 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1065 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1066 f_dl_block_ack_fn(dl_block, poll_fn));
1067
1068 f_shutdown(__BFILE__, __LINE__, final := true);
1069}
1070
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001071/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001072function 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 +01001073 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001074 var RlcmacDlBlock prev_dl_block, dl_block;
1075 var uint32_t ack_fn;
1076 var uint32_t fn;
1077 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001078 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001079 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001080 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1081 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001082 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001083
1084 if (using_egprs) {
1085 exp_tmp_csmcs := mcs_egprs_any;
1086 bsn_mod := 2048;
1087 } else {
1088 exp_tmp_csmcs := cs_gprs_any;
1089 bsn_mod := 128;
1090 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001091
1092 /* Establish BSSGP connection to the PCU */
1093 f_bssgp_establish();
1094
1095 ms := g_ms[0]; /* We only use first MS in this test */
1096 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1097
1098 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001099 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001100 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1101
1102 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1103 f_sleep(X2002);
1104
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001105 for (var integer i := 0; i < 800; i := i + 1) {
1106 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001107 f_rx_rlcmac_dl_block(dl_block, fn);
1108
1109 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
1110 /* No more data to receive, done */
1111 break;
1112 }
1113
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001114 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001115
1116 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001117 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001118
1119 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001120 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001121 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001122 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 +01001123 if (tx_data_remain != 0) {
1124 /* Submit more data from time to time to keep the TBF ongoing */
1125 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1126 tx_data_remain := tx_data_remain - 1;
1127 }
1128 }
1129 prev_dl_block := dl_block;
1130 }
1131
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001132 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1133 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001134
1135
1136 f_shutdown(__BFILE__, __LINE__, final := true);
1137}
1138
1139/* Verify DL CS above "cs max" set by VTY is never used */
1140testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1141 /* Initialize NS/BSSGP side */
1142 f_init_bssgp();
1143 /* Initialize GPRS MS side */
1144 f_init_gprs_ms();
1145
1146 /* Initialize the PCU interface abstraction */
1147 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1148
1149 /* Set maximum allowed DL CS to 3 */
1150 g_cs_initial_dl := 1;
1151 g_cs_max_dl := 3;
1152 f_pcuvty_set_allowed_cs_mcs();
1153 f_pcuvty_set_link_quality_ranges();
1154
1155 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1156}
1157
1158/* Check DL CS4 is used in good link conditions if allowed by config */
1159testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1160 /* Initialize NS/BSSGP side */
1161 f_init_bssgp();
1162 /* Initialize GPRS MS side */
1163 f_init_gprs_ms();
1164
1165 /* Initialize the PCU interface abstraction */
1166 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1167
1168 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1169 g_cs_initial_dl := 1;
1170 g_cs_max_dl := 4;
1171 f_pcuvty_set_allowed_cs_mcs();
1172 f_pcuvty_set_link_quality_ranges();
1173
1174 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1175}
1176
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001177/* Test the initial UL MCS set by VTY works fine */
1178testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1179 var RlcmacDlBlock dl_block;
1180 var PollFnCtx pollctx;
1181 var EgprsChCodingCommand last_ch_coding;
1182 var uint32_t unused_fn, sched_fn;
1183 var GprsMS ms;
1184 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001185
1186 /* Initialize GPRS MS side */
1187 f_init_gprs_ms();
1188 ms := g_ms[0]; /* We only use first MS in this test */
1189
1190 /* Initialize the PCU interface abstraction */
1191 f_init_raw(testcasename());
1192
1193 /* Set initial UL MCS to 3 */
1194 g_mcs_initial_ul := 3;
1195 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1196 f_pcuvty_set_allowed_cs_mcs();
1197 f_pcuvty_set_link_quality_ranges();
1198
1199 /* Take lqual (dB->cB) so that we stay in that MCS */
1200 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1201
1202 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001203 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 +01001204
1205 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1206 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1207 f_shutdown(__BFILE__, __LINE__);
1208 }
1209
1210 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1211 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1212
1213 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1214 while (true) {
1215 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1216 f_rx_rlcmac_dl_block(dl_block, unused_fn);
1217 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1218 continue;
1219 }
1220
1221 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1222 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1223 f_shutdown(__BFILE__, __LINE__);
1224 break;
1225 }
1226
1227 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1228 break;
1229 }
1230 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1231 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1232 f_shutdown(__BFILE__, __LINE__);
1233 }
1234
1235 /* Remaining UL blocks are used to make sure regardless of initial
1236 * lqual, we can go lower at any time
1237 * 0 dB, make sure we downgrade MCS */
1238 ms.lqual_cb := 0;
1239 /* 5 UL blocks, check we are in same initial MCS: */
1240 f_ms_tx_ul_data_block_multi(ms, 5);
1241 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1242 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1243 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1244
1245 if (last_ch_coding != CH_CODING_MCS1) {
1246 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1247 f_shutdown(__BFILE__, __LINE__);
1248 }
1249
1250 f_shutdown(__BFILE__, __LINE__, final := true);
1251}
1252
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001253/* Test the maximum UL MCS set by VTY works fine */
1254testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1255 var RlcmacDlBlock dl_block;
1256 var EgprsChCodingCommand last_ch_coding;
1257 var PollFnCtx pollctx;
1258 var uint32_t unused_fn, sched_fn;
1259 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001260
1261 /* Initialize GPRS MS side */
1262 f_init_gprs_ms();
1263 ms := g_ms[0]; /* We only use first MS in this test */
1264
1265 /* Initialize the PCU interface abstraction */
1266 f_init_raw(testcasename());
1267
1268 /* Set maximum allowed UL MCS to 5 */
1269 g_mcs_max_ul := 5;
1270 f_pcuvty_set_allowed_cs_mcs();
1271 f_pcuvty_set_link_quality_ranges();
1272
1273 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001274 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 +01001275 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1276 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1277
1278 ms.lqual_cb := 40*10; /* 40 dB */
1279 f_ms_tx_ul_data_block_multi(ms, 16);
1280
1281 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1282 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1283
1284 if (last_ch_coding != CH_CODING_MCS5) {
1285 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1286 f_shutdown(__BFILE__, __LINE__);
1287 }
1288
1289 f_shutdown(__BFILE__, __LINE__, final := true);
1290}
1291
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001292/* Test the initial DL CS set by VTY works fine */
1293testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1294 var octetstring data := f_rnd_octstring(10);
1295 var CodingScheme exp_dl_cs_mcs;
1296 var RlcmacDlBlock dl_block;
1297 var uint32_t poll_fn;
1298 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001299
1300 /* Initialize NS/BSSGP side */
1301 f_init_bssgp();
1302 /* Initialize GPRS MS side */
1303 f_init_gprs_ms();
1304 ms := g_ms[0]; /* We only use first MS in this test */
1305
1306 /* Initialize the PCU interface abstraction */
1307 f_init_raw(testcasename());
1308
1309 /* Set initial allowed DL MCS to 3 */
1310 g_mcs_initial_dl := 3;
1311 exp_dl_cs_mcs := MCS_3;
1312 /* Set maximum allowed DL MCS to 4 */
1313 g_mcs_max_dl := 4;
1314 f_pcuvty_set_allowed_cs_mcs();
1315 f_pcuvty_set_link_quality_ranges();
1316
1317 /* Establish BSSGP connection to the PCU */
1318 f_bssgp_establish();
1319 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1320
1321 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001322 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001323 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1324
1325 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1326 f_sleep(X2002);
1327 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1328
1329 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001330 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1331 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 +01001332 f_dl_block_ack_fn(dl_block, poll_fn));
1333
1334 f_shutdown(__BFILE__, __LINE__, final := true);
1335}
1336
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001337/* Verify DL MCS above "mcs max" set by VTY is never used */
1338testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1339 /* Initialize NS/BSSGP side */
1340 f_init_bssgp();
1341 /* Initialize GPRS MS side */
1342 f_init_gprs_ms();
1343
1344 /* Initialize the PCU interface abstraction */
1345 f_init_raw(testcasename());
1346
1347 /* Set maximum allowed DL CS to 3 */
1348 g_mcs_initial_dl := 1;
1349 g_mcs_max_dl := 3;
1350 f_pcuvty_set_allowed_cs_mcs();
1351 f_pcuvty_set_link_quality_ranges();
1352
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001353 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 +01001354}
1355
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001356/* Verify PCU drops TBF after some time of inactivity. */
1357testcase TC_t3141() runs on RAW_PCU_Test_CT {
1358 var PCUIF_info_ind info_ind;
1359 var template (value) TsTrxBtsNum nr;
1360 var BTS_PDTCH_Block data_msg;
1361 var GprsMS ms;
1362 var uint3_t rx_usf;
1363 timer T_3141 := 1.0;
1364 var boolean ul_tbf_usf_req := false;
1365
1366 /* Initialize NS/BSSGP side */
1367 f_init_bssgp();
1368 /* Initialize GPRS MS side */
1369 f_init_gprs_ms();
1370 ms := g_ms[0]; /* We only use first MS in this test */
1371
1372 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1373 /* Only use 1 PDCH to simplify test: */
1374 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1375 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1376 /* Initialize the PCU interface abstraction */
1377 f_init_raw(testcasename(), info_ind);
1378
1379 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1380
1381 /* Establish BSSGP connection to the PCU */
1382 f_bssgp_establish();
1383 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1384
1385 /* Establish a one-phase access Uplink TBF */
1386 f_ms_establish_ul_tbf(ms);
1387
1388 T_3141.start;
1389
1390 /* Now we wait for PCU to transmit our USF */
1391 nr := ts_TsTrxBtsNum;
1392 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1393 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1394 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1395 block_nr := nr.blk_nr));
1396
1397 alt {
1398 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1399 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1400 ?)) -> value data_msg {
1401 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1402 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1403 f_shutdown(__BFILE__, __LINE__);
1404 }
1405
1406 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1407 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1408 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1409 ul_tbf_usf_req := true;
1410 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))
1411 } else if (rx_usf == USF_UNUSED) {
1412 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1413 if (ul_tbf_usf_req) {
1414 /* TBF was dropped by T3141, success */
1415 setverdict(pass);
1416 break;
1417 } else {
1418 log("PCU never requested USF, unexpected");
1419 f_shutdown(__BFILE__, __LINE__);
1420 }
1421 } /* else: Keep waiting for TBF to be active by network */
1422 } else {
1423 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1424 f_shutdown(__BFILE__, __LINE__);
1425 }
1426
1427 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1428 if (match(data_msg.dl_block,
1429 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1430 tr_UlAckNackGprs(tlli := ?,
1431 acknack_desc := ?,
1432 rel99 := *))))
1433 {
1434 log("Received UL ACK/NACK with TLLI set");
1435 f_shutdown(__BFILE__, __LINE__);
1436 }
1437
1438 nr := ts_TsTrxBtsNum;
1439 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1440 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1441 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1442 block_nr := nr.blk_nr));
1443 repeat;
1444 }
1445 [] T_3141.timeout {
1446 log("T_3141 expired but TBF is still active, unexpected");
1447 f_shutdown(__BFILE__, __LINE__);
1448 }
1449 [] BTS.receive {
1450 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1451 * because we never sent the TLLI to the PCU */
1452 setverdict(fail, "Unexpected BTS message");
1453 f_shutdown(__BFILE__, __LINE__);
1454 }
1455 }
1456
1457 f_shutdown(__BFILE__, __LINE__, final := true);
1458}
1459
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001460/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1461 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1462 * T3169. See OS#5033 */
1463testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1464 var PCUIF_info_ind info_ind;
1465 var template (value) TsTrxBtsNum nr;
1466 var BTS_PDTCH_Block data_msg;
1467 var GprsMS ms;
1468 var uint3_t rx_usf;
1469 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1470 var integer n3101 := 0;
1471 timer T_3169 := 1.0;
1472
1473 /* Initialize NS/BSSGP side */
1474 f_init_bssgp();
1475 /* Initialize GPRS MS side */
1476 f_init_gprs_ms();
1477 ms := g_ms[0]; /* We only use first MS in this test */
1478
1479 /* Initialize the PCU interface abstraction */
1480 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1481 info_ind.n3101 := N3101_MAX;
1482 info_ind.t3169 := 1;
1483 f_init_raw(testcasename(), info_ind);
1484
1485 /* Establish BSSGP connection to the PCU */
1486 f_bssgp_establish();
1487 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1488
1489 /* Establish UL TBF */
1490 f_ms_establish_ul_tbf(ms);
1491
1492 /* Now we wait for PCU to transmit our USF */
1493 nr := ts_TsTrxBtsNum;
1494 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1495 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1496 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1497 block_nr := nr.blk_nr));
1498
1499 alt {
1500 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1501 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1502 ?)) -> value data_msg {
1503 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1504 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1505 f_shutdown(__BFILE__, __LINE__);
1506 }
1507
1508 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1509 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1510 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1511 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001512 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1513 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001514 f_shutdown(__BFILE__, __LINE__);
1515 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001516 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001517 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1518 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1519 if (not T_3169.running) {
1520 log("T3169 started");
1521 T_3169.start;
1522 }
1523 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1524 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1525 f_shutdown(__BFILE__, __LINE__);
1526 } else {
1527 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1528 }
1529 nr := ts_TsTrxBtsNum;
1530 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1531 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1532 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1533 block_nr := nr.blk_nr));
1534 repeat;
1535 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001536 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1537 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
1538 [mp_osmo_pcu_newer_than_0_9_0 and n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001539 [] T_3169.timeout {
1540 log("T_3169 expired");
1541 /* Done in alt */
1542 }
1543 [] BTS.receive {
1544 setverdict(fail, "Unexpected BTS message");
1545 f_shutdown(__BFILE__, __LINE__);
1546 }
1547 }
1548
1549 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1550 /* USFs as per previous TBF since they were freed at expiration time: */
1551 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1552 var uint5_t old_tfi := ms.ul_tbf.tfi;
1553 f_ms_establish_ul_tbf(ms);
1554 if (old_tfi != ms.ul_tbf.tfi) {
1555 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1556 f_shutdown(__BFILE__, __LINE__);
1557 }
1558 for (var integer i := 0; i < 8; i := i +1) {
1559 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1560 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1561 f_shutdown(__BFILE__, __LINE__);
1562 }
1563 }
1564
1565 f_shutdown(__BFILE__, __LINE__, final := true);
1566}
1567
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001568
1569/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1570 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1571 the final UL ACK sent at us. */
1572testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1573 var PCUIF_info_ind info_ind;
1574 var BTS_PDTCH_Block data_msg;
1575 var RlcmacDlBlock dl_block;
1576 var uint32_t sched_fn;
1577 var template (value) TsTrxBtsNum nr;
1578 var template RlcmacDlBlock exp_ul_ack;
1579 var template UlAckNackGprs exp_ul_ack_sub;
1580 var GprsMS ms;
1581 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1582 var integer N3103 := 0;
1583 timer T_3169 := 1.0;
1584
1585 /* Initialize GPRS MS side */
1586 f_init_gprs_ms();
1587 ms := g_ms[0]; /* We only use first MS in this test */
1588
1589 /* Initialize the PCU interface abstraction */
1590 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1591 info_ind.n3103 := N3103_MAX;
1592 info_ind.t3169 := 1;
1593 f_init_raw(testcasename(), info_ind);
1594
1595 /* Establish an Uplink TBF */
1596 f_ms_establish_ul_tbf(ms);
1597
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001598 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001599 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1600 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1601
1602 nr := ts_TsTrxBtsNum;
1603 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1604 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1605 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1606 block_nr := nr.blk_nr));
1607 alt {
1608 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1609 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1610 exp_ul_ack)) -> value data_msg {
1611 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1612 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1613 f_shutdown(__BFILE__, __LINE__);
1614 }
1615
1616 nr := ts_TsTrxBtsNum;
1617 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1618 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1619 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1620 block_nr := nr.blk_nr));
1621 N3103 := N3103 + 1;
1622 if (N3103 == N3103_MAX) {
1623 /* At this point in time (N3103_MAX reached), PCU is
1624 * moving the TBF to RELEASE state so no data/ctrl for
1625 * it is tx'ed, hence the dummy blocks: */
1626 T_3169.start;
1627 }
1628 repeat;
1629 }
1630 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1631 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1632 exp_ul_ack)) -> value data_msg {
1633 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1634 f_shutdown(__BFILE__, __LINE__);
1635 }
1636 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001637 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001638 [T_3169.running] T_3169.timeout {
1639 log("T_3169 timeout");
1640 /* Done in alt, wait for pending RTS initiated previously in
1641 * above case before continuing (expect /* Dummy block): */
1642 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1643 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1644 tr_RLCMAC_DUMMY_CTRL));
1645 }
1646 [] BTS.receive {
1647 setverdict(fail, "Unexpected BTS message");
1648 f_shutdown(__BFILE__, __LINE__);
1649 }
1650 }
1651
1652 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1653 * USFs as per previous TBF since they were freed at expiration time: */
1654 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1655 var uint5_t old_tfi := ms.ul_tbf.tfi;
1656 f_ms_establish_ul_tbf(ms);
1657 if (old_tfi != ms.ul_tbf.tfi) {
1658 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1659 f_shutdown(__BFILE__, __LINE__);
1660 }
1661 for (var integer i := 0; i < 8; i := i +1) {
1662 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1663 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1664 f_shutdown(__BFILE__, __LINE__);
1665 }
1666 }
1667
1668 f_shutdown(__BFILE__, __LINE__, final := true);
1669}
1670
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001671/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1672 * point the TBF is no longer available. In order to get to start of T3191, we
1673 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1674 * until TBF release procedure starts after draining DL queue. */
1675testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1676 var PCUIF_info_ind info_ind;
1677 var RlcmacDlBlock dl_block;
1678 var octetstring data1 := f_rnd_octstring(200);
1679 var octetstring data2 := f_rnd_octstring(10);
1680 var uint32_t dl_fn;
1681 var template (value) TsTrxBtsNum nr;
1682 var BTS_PDTCH_Block data_msg;
1683 var GprsMS ms;
1684
1685 /* Initialize NS/BSSGP side */
1686 f_init_bssgp();
1687 /* Initialize GPRS MS side */
1688 f_init_gprs_ms();
1689 ms := g_ms[0]; /* We only use first MS in this test */
1690
1691 /* Initialize the PCU interface abstraction */
1692 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1693 /* Set timer to 1 sec (default 5) to speedup test: */
1694 info_ind.t3191 := 1;
1695 f_init_raw(testcasename(), info_ind);
1696
1697 /* Establish BSSGP connection to the PCU */
1698 f_bssgp_establish();
1699 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1700
1701 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1702 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1703 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1704
1705 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1706 f_sleep(X2002);
1707
1708 while (true) {
1709 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1710
1711 /* Keep Ack/Nack description updated (except for last BSN) */
1712 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1713
1714 if (f_dl_block_rrbp_valid(dl_block)) {
1715 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1716 f_dl_block_ack_fn(dl_block, dl_fn));
1717 break;
1718 }
1719 }
1720
1721 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1722 nr := ts_TsTrxBtsNum;
1723 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1724 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1725 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1726 block_nr := nr.blk_nr));
1727 alt {
1728 [] as_ms_rx_ignore_dummy(ms, nr);
1729 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1730 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1731 ?)) -> value data_msg {
1732 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1733 log("Received FINAL_ACK");
1734 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1735 break;
1736 }
1737 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1738 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1739 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1740 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1741 }
1742 nr := ts_TsTrxBtsNum;
1743 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1744 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1745 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1746 block_nr := nr.blk_nr));
1747 repeat;
1748 }
1749 [] BTS.receive {
1750 setverdict(fail, "Unexpected BTS message");
1751 f_shutdown(__BFILE__, __LINE__);
1752 }
1753 }
1754
1755 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1756 to time out. We simply sleep instead of requesting blocks because
1757 otherwise retransmissions would keep restarting the timer. */
1758 f_sleep(int2float(info_ind.t3191));
1759
1760 /* The TBF should be freed now, so new data should trigger an Assignment: */
1761 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1762 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1763
1764 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1765 f_sleep(X2002);
1766 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1767 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1768 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1769 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1770 f_dl_block_ack_fn(dl_block, dl_fn));
1771
1772 f_shutdown(__BFILE__, __LINE__, final := true);
1773}
1774
1775/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1776testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1777 var PCUIF_info_ind info_ind;
1778 var RlcmacDlBlock dl_block;
1779 var octetstring data1 := f_rnd_octstring(1400);
1780 var octetstring data2 := f_rnd_octstring(10);
1781 var uint32_t dl_fn;
1782 var GprsMS ms;
1783
1784 /* Initialize NS/BSSGP side */
1785 f_init_bssgp();
1786 /* Initialize GPRS MS side */
1787 f_init_gprs_ms();
1788 ms := g_ms[0]; /* We only use first MS in this test */
1789
1790 /* Initialize the PCU interface abstraction */
1791 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1792 /* Set timer to 1 sec (default 5) to speedup test: */
1793 info_ind.t3191 := 1;
1794 f_init_raw(testcasename(), info_ind);
1795
1796 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1797
1798 /* Establish BSSGP connection to the PCU */
1799 f_bssgp_establish();
1800 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1801
1802 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1803 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1804 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1805
1806 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1807 f_sleep(X2002);
1808
1809 /* Send enough DL data to at least be able to DL ACK once (excl the
1810 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1811 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1812 while (true) {
1813 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1814
1815 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1816 log("Received FINAL_ACK");
1817 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1818 break;
1819 }
1820
1821 /* Keep Ack/Nack description updated (except for last BSN) */
1822 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1823
1824 if (f_dl_block_rrbp_valid(dl_block)) {
1825 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1826 f_dl_block_ack_fn(dl_block, dl_fn));
1827 }
1828 }
1829
1830 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1831 to time out. We simply sleep instead of requesting blocks because
1832 otherwise retransmissions would keep restarting the timer. */
1833 f_sleep(int2float(info_ind.t3191));
1834
1835 /* The TBF should be freed now, so new data should trigger an Assignment: */
1836 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1837 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1838
1839 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1840 f_sleep(X2002);
1841 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1842 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1843 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1844 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1845 f_dl_block_ack_fn(dl_block, dl_fn));
1846
1847 f_shutdown(__BFILE__, __LINE__, final := true);
1848}
1849
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001850/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1851 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1852 * T3193) after DL TBF release */
1853testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001854 var RlcmacDlBlock dl_block;
1855 var octetstring data := f_rnd_octstring(10);
1856 var boolean ok;
1857 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001858 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001859 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001860 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1861
1862 /* Initialize NS/BSSGP side */
1863 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001864 /* Initialize GPRS MS side */
1865 f_init_gprs_ms();
1866 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001867
1868 /* Initialize the PCU interface abstraction */
1869 f_init_raw(testcasename());
1870
1871 /* Establish BSSGP connection to the PCU */
1872 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001873 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001874
1875 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001876 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1877 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001878
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001879 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1880 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001881 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001882
1883 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001884 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1885 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1886 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001887
1888 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001889 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001890 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001891 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001892 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001893
1894 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001895
1896 /* 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 +07001897 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001898 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1899 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1900 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001901
1902 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001903}
1904
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001905/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1906 freed and no longer available. Trigger it by sending DL blocks and never DL
1907 ACKing the data (which are requested through RRBP) */
1908testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1909 var PCUIF_info_ind info_ind;
1910 var RlcmacDlBlock dl_block;
1911 var octetstring data1 := f_rnd_octstring(1000);
1912 var octetstring data2 := f_rnd_octstring(10);
1913 var uint32_t dl_fn;
1914 var template (value) TsTrxBtsNum nr;
1915 var BTS_PDTCH_Block data_msg;
1916 var GprsMS ms;
1917 const integer N3105_MAX := 2;
1918 var integer N3105 := 0;
1919 timer T_3195 := 1.0;
1920 var integer num_poll_recv := 0;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001921 var template RlcmacDlBlock dl_block_exp;
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001922
1923 /* Initialize NS/BSSGP side */
1924 f_init_bssgp();
1925 /* Initialize GPRS MS side */
1926 f_init_gprs_ms();
1927 ms := g_ms[0]; /* We only use first MS in this test */
1928
1929 /* Initialize the PCU interface abstraction */
1930 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1931 /* Speedup test: */
1932 info_ind.n3105 := N3105_MAX;
1933 info_ind.t3195 := 1;
1934 f_init_raw(testcasename(), info_ind);
1935
1936 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1937 * MS and retransmitted after the TBF is released and later on created
1938 * (because the MS is reused) */
1939 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1940
1941 /* Establish BSSGP connection to the PCU */
1942 f_bssgp_establish();
1943 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1944
1945 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1946 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1947 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1948
1949 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1950 f_sleep(X2002);
1951
1952 /* Now we go on receiving DL data and not answering RRBP: */
1953 nr := ts_TsTrxBtsNum;
1954 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1955 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1956 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1957 block_nr := nr.blk_nr));
1958 alt {
1959 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1960 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1961 tr_RLCMAC_DATA)) -> value data_msg {
1962 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1963 if (num_poll_recv == 0) {
1964 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1965 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1966 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1967 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1968 } else {
1969 log("Ignoring RRBP ", num_poll_recv);
1970 N3105 := N3105 + 1;
1971 }
1972 num_poll_recv := num_poll_recv + 1;
1973 }
1974
1975 nr := ts_TsTrxBtsNum;
1976 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1977 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1978 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1979 block_nr := nr.blk_nr));
1980 repeat;
1981 }
1982 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001983 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001984 */
1985 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1986 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1987 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
1988 if (not T_3195.running) {
1989 T_3195.start;
1990 /* We even send some new data, nothing should be sent to MS */
1991 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1992 }
1993 nr := ts_TsTrxBtsNum;
1994 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1995 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1996 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1997 block_nr := nr.blk_nr));
1998 repeat;
1999 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01002000 /* We may already receive idle blocks before our own TTCN3 timer
2001 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
2002 [mp_osmo_pcu_newer_than_0_9_0 and N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002003 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002004 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002005 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002006 * above case before continuing (expect empty blocks on new
2007 * versions, Dummy block on older versions): */
2008 if (mp_osmo_pcu_newer_than_0_9_0) {
2009 dl_block_exp := omit;
2010 } else {
2011 dl_block_exp := tr_RLCMAC_DUMMY_CTRL;
2012 }
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002013 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2014 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002015 dl_block_exp));
2016 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002017 [] BTS.receive {
2018 setverdict(fail, "Unexpected BTS message");
2019 f_shutdown(__BFILE__, __LINE__);
2020 }
2021 }
2022
2023 /* after T_3195 timeout, TBF is released */
2024 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
2025 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2026
2027 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2028 f_sleep(X2002);
2029 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2030
2031 /* ACK the DL block */
2032 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2033 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2034 f_dl_block_ack_fn(dl_block, dl_fn));
2035
2036 f_shutdown(__BFILE__, __LINE__, final := true);
2037}
2038
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002039/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2040function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2041 var PCUIF_info_ind info_ind;
2042 var template IARRestOctets rest;
2043 var BIT11 ra11;
2044 var GprsMS ms;
2045 var octetstring data := f_rnd_octstring(10);
2046 var RlcmacDlBlock dl_block;
2047 var template RlcmacDlBlock rej_tmpl;
2048 var uint32_t dl_fn;
2049 var uint32_t sched_fn;
2050 var uint8_t wait_ind_val;
2051
2052 /* Initialize NS/BSSGP side */
2053 f_init_bssgp();
2054 /* Initialize GPRS MS side */
2055 f_init_gprs_ms();
2056 ms := g_ms[0]; /* We only use first MS in this test */
2057
2058 info_ind := valueof(ts_PCUIF_INFO_default);
2059
2060 /* Only the first TRX is enabled. */
2061 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2062 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2063
2064 /* Initialize the PCU interface abstraction */
2065 f_init_raw(testcasename(), info_ind);
2066
2067 f_pcuvty_set_timer(3172, t3172_ms);
2068
2069 /* Establish BSSGP connection to the PCU */
2070 f_bssgp_establish();
2071 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2072
2073 var EGPRSPktChRequest req := {
2074 one_phase := {
2075 tag := '0'B,
2076 multislot_class := '10101'B,
2077 priority := '01'B,
2078 random_bits := '101'B
2079 }
2080 };
2081
2082 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2083 for (var integer i := 0; i < 7; i := i + 1) {
2084 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2085 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2086 }
2087
2088 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2089 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2090 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2091
2092 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2093 f_sleep(X2002);
2094 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2095
2096 /* ACK the DL block */
2097 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2098 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2099 f_dl_block_ack_fn(dl_block, dl_fn));
2100
2101 /* Since all USF are taken, we should receive a Reject: */
2102
2103 if (wait_ind_size == '0'B) {
2104 wait_ind_val := t3172_ms / 1000;
2105 } else {
2106 wait_ind_val := t3172_ms / 20;
2107 }
2108 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2109 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2110 wait_ind_val,
2111 wait_ind_size)));
2112 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2113 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2114 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2115 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2116 block_nr := nr.blk_nr));
2117 alt {
2118 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2119 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2120 rej_tmpl));
2121 [] BTS.receive {
2122 setverdict(fail, "Unexpected BTS message");
2123 f_shutdown(__BFILE__, __LINE__);
2124 }
2125 }
2126 f_shutdown(__BFILE__, __LINE__, final := true);
2127}
2128testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2129 /* size=0 means value is provided in seconds. Due to value being 8
2130 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2131 * = 5100. Hence, values above it should use size=0 to be able to
2132 * provide values in range. Let's use 6 seconds, 6000ms
2133 */
2134 f_TC_t3172(6000, '0'B);
2135}
2136testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2137 f_TC_t3172(3000, '1'B);
2138}
2139
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002140/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2141testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002142 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002143 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002144 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002145 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002146
2147 /* Initialize NS/BSSGP side */
2148 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002149 /* Initialize GPRS MS side */
2150 f_init_gprs_ms();
2151 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002152
2153 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002154 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002155
2156 /* Establish BSSGP connection to the PCU */
2157 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002158 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002159
2160 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002161 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002162
2163 /* Send one UL block (with TLLI since we are in One-Phase Access
2164 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002165 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002166 /* 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 +02002167 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 +02002168 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2169 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002170 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002171
2172 /* Send enough blocks to test whole procedure: Until Nth block
2173 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2174 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002175 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002176 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2177 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002178 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002179
2180 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002181 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 +07002182
2183 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002184}
2185
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002186/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2187testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2188 var RlcmacDlBlock dl_block;
2189 var uint32_t dl_fn, sched_fn;
2190 var octetstring payload;
2191 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002192 var template (value) LlcBlockHdr blk_hdr;
2193 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002194 var integer blk_len;
2195 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002196 var GprsMS ms;
2197
2198 /* Initialize NS/BSSGP side */
2199 f_init_bssgp();
2200 /* Initialize GPRS MS side */
2201 f_init_gprs_ms();
2202 ms := g_ms[0]; /* We only use first MS in this test */
2203
2204 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002205 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002206
2207 /* Establish BSSGP connection to the PCU */
2208 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002209 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002210
2211 /* Establish an Uplink TBF */
2212 f_ms_establish_ul_tbf(ms);
2213
2214 /* Send one UL block (with TLLI since we are in One-Phase Access
2215 contention resoultion) and make sure it is ACKED fine. */
2216 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002217 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2218 more := false, e := true);
2219 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002220 /* 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 +01002221 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2222 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002223 cv := 15,
2224 bsn := ms.ul_tbf.bsn,
2225 blocks := blocks,
2226 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002227 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002228 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002229
2230 /* ACK and check it was received fine */
2231 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2232 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2233 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2234 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002235 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 +02002236
2237 /* Test sending LLC PDUS of incrementing size */
2238 var integer max_size := 49;
2239 for (var integer i := 1; i <= max_size; i := i + 1) {
2240 var integer cv;
2241 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2242 log("Sending DATA.ind with LLC payload size ", i);
2243 if (i < max_size - g_bs_cv_max) {
2244 cv := 15;
2245 } else {
2246 cv := max_size - i;
2247 }
2248
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002249 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2250 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002251 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002252 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2253 more := false, e := true);
2254 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002255 /* 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 +01002256 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2257 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002258 cv := cv,
2259 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002260 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002261 f_ultbf_inc_bsn(ms.ul_tbf);
2262 f_ms_tx_ul_block(ms, ul_data);
2263
2264 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002265 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 +02002266
2267 /* we will receive UL ACK/NACK from time to time, handle it. */
2268 f_rx_rlcmac_dl_block(dl_block, dl_fn);
2269 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
2270 continue;
2271 }
2272 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2273 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2274 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2275 f_shutdown(__BFILE__, __LINE__);
2276 }
2277
2278 log("Rx Packet Uplink ACK / NACK");
2279 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2280 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2281 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2282 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002283
2284 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002285}
2286
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002287function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2288 var octetstring payload;
2289 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002290 var template (value) LlcBlockHdr blk_hdr;
2291 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002292 var integer block_len, max_valid_data_len;
2293 timer T;
2294
2295 block_len := f_rlcmac_cs_mcs2block_len(cs);
2296 /* We need to send with TLLI since we are in One-Phase Access Contenion
2297 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
2298 * indicator, -1 for spare bits octet at the end */
2299 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2300 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 +07002301 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2302 more := false, e := true);
2303 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002304 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2305 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002306 cv := cv,
2307 bsn := ms.ul_tbf.bsn,
2308 blocks := blocks,
2309 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002310 f_ultbf_inc_bsn(ms.ul_tbf);
2311 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2312
2313 T.start(0.5);
2314 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002315 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002316 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2317 f_shutdown(__BFILE__, __LINE__);
2318 }
2319 [] T.timeout {
2320 setverdict(pass);
2321 }
2322 }
2323}
2324/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2325 blocks intentionally contain last byte of data placed in last byte of RLC
2326 containing padding/spare bits, which is incorrect. Spare bits exist and are
2327 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2328 discounting padding in octet" */
2329testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2330 var GprsMS ms;
2331 var integer block_len, max_valid_data_len;
2332
2333 /* Initialize NS/BSSGP side */
2334 f_init_bssgp();
2335 /* Initialize GPRS MS side */
2336 f_init_gprs_ms();
2337 ms := g_ms[0]; /* We only use first MS in this test */
2338
2339 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002340 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002341
2342 /* Establish BSSGP connection to the PCU */
2343 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002344 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002345
2346 /* Establish an Uplink TBF */
2347 f_ms_establish_ul_tbf(ms);
2348
2349 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2350 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2351 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2352
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002353 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002354}
2355
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002356/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2357 * answered, so TBFs for uplink and later for downlink are created.
2358 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002359private 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 +02002360 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002361 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002362 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002363 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002364 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002365
2366 /* Initialize NS/BSSGP side */
2367 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002368 /* Initialize GPRS MS side */
2369 f_init_gprs_ms();
2370 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002371
2372 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002373 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002374
2375 /* Establish BSSGP connection to the PCU */
2376 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002377 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002378
2379 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002380 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002381
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002382 /* Send one UL block (with TLLI since we are in One-Phase Access
2383 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002384 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 +02002385 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2386 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002387 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002388
2389 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002390 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002391
2392 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002393 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2394 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002395
2396 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2397 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002398 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002399
2400 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002401 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2402 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2403 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002404
2405 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002406}
2407
2408/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2409 * answered, so TBFs for uplink and later for downlink are created.
2410 */
2411testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002412 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002413 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002414}
2415
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002416/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2417 * answered, so TBFs for uplink and later for downlink are created.
2418 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002419private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2420 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002421 template (present) CodingScheme exp_ul_cs_mcs := ?,
2422 template (present) CodingScheme exp_dl_cs_mcs := ?)
2423runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002424 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002425 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002426 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002427 var uint32_t sched_fn;
2428 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002429 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002430 var GprsMS ms;
2431
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002432 /* Initialize NS/BSSGP side */
2433 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002434 /* Initialize GPRS MS side */
2435 f_init_gprs_ms();
2436 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002437
2438 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002439 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002440
2441 /* Establish BSSGP connection to the PCU */
2442 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002443 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002444
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002445 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2446 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 +02002447
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002448 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2449 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 +02002450 f_shutdown(__BFILE__, __LINE__);
2451 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002452
2453 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2454 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002455 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002456
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002457 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002458 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 +02002459
2460 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002461 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002462
2463 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002464 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002465 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2466 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002467 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002468 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002469 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002470
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002471 /* PCU acks the UL data after having received CV=0) */
2472 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2473
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002474 /* 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 +02002475 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 +02002476
2477 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002478 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2479 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 +02002480 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002481
2482 f_shutdown(__BFILE__, __LINE__, final := true);
2483}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002484
2485testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002486 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2487 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002488
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002489 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 +01002490
2491 if (mp_osmo_pcu_newer_than_0_9_0) {
2492 var StatsDExpects expect := {
2493 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2494 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2495 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2496 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2497 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2498 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2499 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2500 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2501 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2502 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2503 };
2504 f_statsd_expect(expect);
2505 }
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002506}
2507
2508testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002509 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2510 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002511
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002512 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 Pedrol023330d2021-11-08 14:10:21 +01002513 if (mp_osmo_pcu_newer_than_0_9_0) {
2514 var StatsDExpects expect := {
2515 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2516 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2517 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2518 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2519 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2520 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2521 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2522 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2523 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2524 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2525 };
2526 f_statsd_expect(expect);
2527 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002528}
2529
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002530testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2531 /* Configure PCU to force two phase access */
2532 g_force_two_phase_access := true;
2533
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002534 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002535 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002536
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002537 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 +01002538
2539 if (mp_osmo_pcu_newer_than_0_9_0) {
2540 var StatsDExpects expect := {
2541 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2542 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2543 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2544 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2545 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2546 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2547 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2548 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2549 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2550 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2551 };
2552 f_statsd_expect(expect);
2553 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002554}
2555
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002556/* Test scenario where SGSN wants to send some data against MS and it is
2557 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2558 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002559private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2560 template (present) CodingScheme exp_cs_mcs := ?)
2561runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002562 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002563 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002564 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002565 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002566 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002567
2568 /* Initialize NS/BSSGP side */
2569 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002570 /* Initialize GPRS MS side */
2571 f_init_gprs_ms();
2572 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002573
2574 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002575 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002576
2577 /* Establish BSSGP connection to the PCU */
2578 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002579 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002580
2581 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002582 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2583 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002584
2585 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2586 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002587 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002588
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002589 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002590 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2591 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 +02002592 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002593
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002594 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002595 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002596
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002597 /* Send one UL block (with TLLI since we are in One-Phase Access
2598 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002599 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002600 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2601 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002602 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002603
2604 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002605 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002606
2607 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002608}
2609
2610testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002611 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002612 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2613}
2614
2615/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2616/* information about the MS */
2617testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002618 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002619 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002620}
2621
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002622/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2623 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2624 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2625 * be transferred).
2626 */
2627testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002628 var RlcmacDlBlock dl_block;
2629 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002630 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002631 var octetstring total_payload;
2632 var octetstring payload;
2633 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002634 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002635 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002636 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002637
2638 /* Initialize NS/BSSGP side */
2639 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002640 /* Initialize GPRS MS side */
2641 f_init_gprs_ms();
2642 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002643
2644 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002645 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002646
2647 /* Establish BSSGP connection to the PCU */
2648 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002649 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002650
2651 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002652 f_ms_establish_ul_tbf(ms);
2653 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002654
2655 /* Send one UL block (with TLLI since we are in One-Phase Access
2656 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002657 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 +02002658 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 +02002659
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002660 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2661 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002662 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002663 total_payload := payload;
2664
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002665 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2666
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002667 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002668 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002669 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002670 total_payload := total_payload & 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
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002676 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002677 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 +02002678 total_payload := total_payload & lost_payload;
2679
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002680 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002681 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002682 total_payload := total_payload & payload;
2683
2684 /* 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 +02002685 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002686
2687 /* On CV=0, we'll receive a UL ACK asking about missing block */
2688 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2689 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002690 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2691 tfi := tfi,
2692 cv := 15,
2693 bsn := 3,
2694 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002695 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002696
2697 /* Now final ack is recieved */
2698 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2699 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002700 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002701
2702 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002703 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 +07002704
2705 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002706}
2707
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002708/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2709 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2710 * timeout occurs (specified by sent RRBP on DL block). */
2711testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002712 var RlcmacDlBlock dl_block;
2713 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002714 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002715 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002716
2717 /* Initialize NS/BSSGP side */
2718 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002719 /* Initialize GPRS MS side */
2720 f_init_gprs_ms();
2721 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002722
2723 /* Initialize the PCU interface abstraction */
2724 f_init_raw(testcasename());
2725
2726 /* Establish BSSGP connection to the PCU */
2727 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002728 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002729
2730 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002731 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2732 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002733
2734 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2735 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002736 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002737
2738 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2739 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2740 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002741 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002742
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002743 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2744 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002745 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002746
2747 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002748 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2749 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2750 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002751
2752 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002753}
2754
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002755/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2756testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2757 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2758 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002759 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002760 var RlcmacDlBlock dl_block;
2761 var uint32_t ack_fn;
2762 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002763 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002764 timer T := 5.0;
2765
2766 /* Initialize NS/BSSGP side */
2767 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002768 /* Initialize GPRS MS side */
2769 f_init_gprs_ms();
2770 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002771
2772 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002773 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002774
Daniel Willmann535aea62020-09-21 13:27:08 +02002775 f_statsd_reset();
2776
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002777 /* Establish BSSGP connection to the PCU */
2778 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002779 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002780
2781 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002782 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2783 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002784
2785 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2786 f_sleep(X2002);
2787
2788 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2789 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002790 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002791
2792 /* TDMA frame number on which we are supposed to send the ACK */
2793 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2794
2795 /* SGSN sends more blocks during the indicated RRBP */
2796 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2797 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002798 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002799
2800 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2801
2802 /* Make sure this block has the same TFI as was assigned
2803 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002804 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002805 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2806 dl_block.data.mac_hdr.hdr_ext.tfi);
2807 f_shutdown(__BFILE__, __LINE__);
2808 }
2809
2810 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002811 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002812
2813 /* Break if this is the end of RRBP */
2814 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002815 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002816 break;
2817 }
2818 }
2819
2820 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002821 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 +07002822
2823 /* Make sure that the next block (after the Ack) is dummy */
2824 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2825
Daniel Willmann535aea62020-09-21 13:27:08 +02002826 var StatsDExpects expect := {
2827 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2828 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2829 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2830 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2831 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002832 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002833 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2834 };
2835 f_statsd_expect(expect);
2836
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002837 f_shutdown(__BFILE__, __LINE__, final := true);
2838}
2839
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002840/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2841 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2842 * Check "3GPP TS 44.060" Annex B. */
2843testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2844 var RlcmacDlBlock dl_block;
2845 var octetstring dataA := f_rnd_octstring(20);
2846 var octetstring dataB := f_rnd_octstring(13);
2847 var octetstring dataC := f_rnd_octstring(3);
2848 var octetstring dataD := f_rnd_octstring(12);
2849 var uint32_t sched_fn;
2850 var GprsMS ms;
2851 var template (value) RlcmacUlBlock ul_data;
2852
2853 /* Initialize NS/BSSGP side */
2854 f_init_bssgp();
2855 /* Initialize GPRS MS side */
2856 f_init_gprs_ms();
2857 ms := g_ms[0]; /* We only use first MS in this test */
2858
2859 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002860 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002861
2862 /* Establish BSSGP connection to the PCU */
2863 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002864 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002865
2866 /* Establish an Uplink TBF */
2867 f_ms_establish_ul_tbf(ms);
2868
2869 /* Summary of what's transmitted:
2870 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2871 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2872 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2873 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2874 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2875 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2876 */
2877
2878 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002879 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2880 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002881 cv := 3,
2882 bsn := ms.ul_tbf.bsn,
2883 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2884 tlli := ms.tlli);
2885 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2886 * RLCMAC block being sent. */
2887 ul_data.data.mac_hdr.e := true;
2888 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002889 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002890
2891 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002892 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2893 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002894 cv := 2,
2895 bsn := ms.ul_tbf.bsn,
2896 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2897 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2898 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2899 },
2900 tlli := ms.tlli);
2901 f_ultbf_inc_bsn(ms.ul_tbf);
2902 f_ms_tx_ul_block(ms, ul_data);
2903
2904 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002905 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 +02002906
2907 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002908 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2909 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002910 cv := 1,
2911 bsn := ms.ul_tbf.bsn,
2912 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2913 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2914 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2915 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2916 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2917 },
2918 tlli := ms.tlli);
2919 f_ultbf_inc_bsn(ms.ul_tbf);
2920 f_ms_tx_ul_block(ms, ul_data);
2921
2922 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002923 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2924 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 +02002925
2926 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002927 ul_data := t_RLCMAC_UL_DATA_TLLI(
2928 cs := CS_1,
2929 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002930 cv := 0,
2931 bsn := ms.ul_tbf.bsn,
2932 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2933 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2934 },
2935 tlli := ms.tlli);
2936 f_ultbf_inc_bsn(ms.ul_tbf);
2937 f_ms_tx_ul_block(ms, ul_data);
2938
2939 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002940 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 +02002941
2942 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2943 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2944 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2945
2946 f_shutdown(__BFILE__, __LINE__, final := true);
2947}
2948
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002949/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2950 * ACK/NACK is not answered */
2951testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2952 var RlcmacDlBlock dl_block;
2953 var octetstring data1 := f_rnd_octstring(200);
2954 var octetstring data2 := f_rnd_octstring(10);
2955 var uint32_t dl_fn;
2956 var GprsMS ms;
2957 var template (value) TsTrxBtsNum nr;
2958 var BTS_PDTCH_Block data_msg;
2959
2960 /* Initialize NS/BSSGP side */
2961 f_init_bssgp();
2962 /* Initialize GPRS MS side */
2963 f_init_gprs_ms();
2964 ms := g_ms[0]; /* We only use first MS in this test */
2965
2966 /* Initialize the PCU interface abstraction */
2967 f_init_raw(testcasename())
2968
2969 /* Establish BSSGP connection to the PCU */
2970 f_bssgp_establish();
2971 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2972
2973 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2974 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2975 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2976
2977 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2978 f_sleep(X2002);
2979
2980 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2981 while (true) {
2982 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2983
2984 /* Keep Ack/Nack description updated (except for last BSN) */
2985 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2986
2987 if (f_dl_block_rrbp_valid(dl_block)) {
2988 /* Don't transmit DL ACK here on purpose ignore it */
2989 break;
2990 }
2991 }
2992
2993 /* PCU starts whole process again */
2994 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2995
2996 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2997 f_sleep(X2002);
2998
2999 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
3000 /* DL data), after that we receive only DUMMY blocks so we are done */
3001 var boolean data_received := false;
3002 nr := ts_TsTrxBtsNum;
3003 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3004 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3005 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3006 block_nr := nr.blk_nr));
3007 alt {
3008 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3009 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3010 tr_RLCMAC_DUMMY_CTRL)) { /* done */ }
3011 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3012 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3013 tr_RLCMAC_DATA)) -> value data_msg {
3014 data_received := true;
3015 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3016 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3017 log("Received FINAL_ACK");
3018 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3019 }
3020 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3021 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3022 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3023 }
3024 nr := ts_TsTrxBtsNum;
3025 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3026 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3027 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3028 block_nr := nr.blk_nr));
3029 repeat;
3030 }
3031 [] BTS.receive {
3032 setverdict(fail, "Unexpected BTS message");
3033 f_shutdown(__BFILE__, __LINE__);
3034 }
3035 }
3036
3037 f_shutdown(__BFILE__, __LINE__, final := true);
3038}
3039
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003040/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3041testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003042 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003043 var octetstring data := f_rnd_octstring(10);
3044 var PacketDlAssign dl_tbf_ass;
3045 var RlcmacDlBlock dl_block;
3046 var uint32_t poll_fn;
3047 var uint32_t sched_fn;
3048 var GprsMS ms;
3049 timer T := 5.0;
3050
3051 /* Initialize NS/BSSGP side */
3052 f_init_bssgp();
3053 /* Initialize GPRS MS side */
3054 f_init_gprs_ms();
3055 ms := g_ms[0]; /* We only use first MS in this test */
3056
3057 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003058 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3059 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003060
3061 /* Initialize the PCU interface abstraction */
3062 f_init_raw(testcasename(), info_ind);
3063
3064 /* Establish BSSGP connection to the PCU */
3065 f_bssgp_establish();
3066 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3067
3068 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3069 through PDCH (no multiblock assignment possible through PCH) */
3070 f_ms_establish_ul_tbf(ms);
3071
3072 /* Send one UL block (with TLLI since we are in One-Phase Access
3073 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003074 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
3075 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003076 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3077 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3078
3079 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3080 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3081 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3082 gprsextendeddynalloccap := '0'B
3083 };
3084 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3085 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3086 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3087 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3088 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3089 f_shutdown(__BFILE__, __LINE__);
3090 }
3091 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3092
3093 f_shutdown(__BFILE__, __LINE__, final := true);
3094}
3095
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003096testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003097 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003098 var RlcmacDlBlock dl_block;
3099 var octetstring data := f_rnd_octstring(10);
3100 var PollFnCtx pollctx;
3101 var uint32_t sched_fn;
3102 var GprsMS ms;
3103
3104 var MultislotCap_GPRS mscap_gprs := {
3105 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3106 gprsextendeddynalloccap := '0'B
3107 };
3108 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3109
3110
3111 /* Initialize NS/BSSGP side */
3112 f_init_bssgp();
3113 /* Initialize GPRS MS side */
3114 f_init_gprs_ms();
3115 ms := g_ms[0]; /* We only use first MS in this test */
3116
3117 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003118 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3119 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003120
3121 /* Initialize the PCU interface abstraction */
3122 f_init_raw(testcasename(), info_ind);
3123
3124 /* Establish BSSGP connection to the PCU */
3125 f_bssgp_establish();
3126 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3127
3128 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3129 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3130
3131 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3132 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3133
3134 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3135 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3136 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3137 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3138 f_shutdown(__BFILE__, __LINE__);
3139 }
3140 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3141
3142 f_shutdown(__BFILE__, __LINE__, final := true);
3143}
3144
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003145testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3146 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3147 var RlcmacDlBlock dl_block;
3148 var octetstring data := f_rnd_octstring(10);
3149 var PollFnCtx pollctx;
3150 var uint32_t sched_fn;
3151 var GprsMS ms;
3152
3153 var MultislotCap_GPRS mscap_gprs := {
3154 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3155 gprsextendeddynalloccap := '0'B
3156 };
3157 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3158
3159
3160 /* Initialize NS/BSSGP side */
3161 f_init_bssgp();
3162 /* Initialize GPRS MS side */
3163 f_init_gprs_ms();
3164 ms := g_ms[0]; /* We only use first MS in this test */
3165
3166 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003167 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3168 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003169
3170 /* Initialize the PCU interface abstraction */
3171 f_init_raw(testcasename(), info_ind);
3172
3173 /* Establish BSSGP connection to the PCU */
3174 f_bssgp_establish();
3175 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3176
3177 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3178 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3179
3180 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3181 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3182 f_shutdown(__BFILE__, __LINE__);
3183 }
3184
3185 f_shutdown(__BFILE__, __LINE__, final := true);
3186}
3187
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003188/* Test scenario where MS wants to request a new TBF once the current one is
3189 * ending, by means of sending a Packet Resource Request on ul slot provided by
3190 * last Pkt Ul ACK's RRBP.
3191 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3192testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003193 var RlcmacDlBlock dl_block;
3194 var octetstring data := f_rnd_octstring(10);
3195 var uint32_t sched_fn;
3196 var uint32_t dl_fn;
3197 var template RlcmacDlBlock acknack_tmpl;
3198 var GprsMS ms;
3199
3200 /* Initialize NS/BSSGP side */
3201 f_init_bssgp();
3202 /* Initialize GPRS MS side */
3203 f_init_gprs_ms();
3204 ms := g_ms[0]; /* We only use first MS in this test */
3205
3206 /* Initialize the PCU interface abstraction */
3207 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003208 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003209
3210 /* Establish BSSGP connection to the PCU */
3211 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003212 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003213
3214 /* Establish an Uplink TBF */
3215 f_ms_establish_ul_tbf(ms);
3216
3217 /* Send one UL block (with TLLI since we are in One-Phase Access
3218 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003219 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 +02003220
3221 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003222 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003223
3224 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3225 tr_UlAckNackGprs(ms.tlli,
3226 tr_AckNackDescription(final_ack := '1'B),
3227 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3228 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3229
3230 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3231
3232 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003233 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 +07003234 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003235 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3236 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3237
3238 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3239 and make sure it is ACKED fine */
3240 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3241
3242 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003243 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003244
3245 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3246 /* ACK the ACK */
3247 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3248
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003249 if (mp_osmo_pcu_newer_than_0_9_0) {
3250 var StatsDExpects expect := {
3251 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3252 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3253 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3254 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3255 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3256 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3257 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3258 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3259 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3260 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3261 };
3262 f_statsd_expect(expect);
3263 }
3264
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003265 f_shutdown(__BFILE__, __LINE__, final := true);
3266}
3267
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003268/* Test scenario where MS wants to request a new TBF once the current one is
3269 * ending, by means of sending a Packet Resource Request on ul slot provided by
3270 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3271 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3272testcase TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() runs on RAW_PCU_Test_CT {
3273 var PCUIF_info_ind info_ind;
3274 var RlcmacDlBlock dl_block;
3275 var octetstring data := f_rnd_octstring(10);
3276 var uint32_t sched_fn;
3277 var uint32_t dl_fn;
3278 var template (value) TsTrxBtsNum nr;
3279 var BTS_PDTCH_Block data_msg;
3280 var template RlcmacDlBlock acknack_tmpl;
3281 var GprsMS ms;
3282 const integer N3105_MAX := 2;
3283 var integer N3105 := 0;
3284 timer T_3195 := 1.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
3285
3286 /* Initialize NS/BSSGP side */
3287 f_init_bssgp();
3288 /* Initialize GPRS MS side */
3289 f_init_gprs_ms();
3290 ms := g_ms[0]; /* We only use first MS in this test */
3291
3292 /* Initialize the PCU interface abstraction */
3293 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3294 /* Speedup test: */
3295 info_ind.n3105 := N3105_MAX;
3296 info_ind.t3195 := 1;
3297 f_init_raw(testcasename(), info_ind);
3298
3299 /* Establish BSSGP connection to the PCU */
3300 f_bssgp_establish();
3301 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3302
3303 /* Establish an Uplink TBF */
3304 f_ms_establish_ul_tbf(ms);
3305
3306 /* Send one UL block (with TLLI since we are in One-Phase Access
3307 contention resoultion) and make sure it is ACKED fine */
3308 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3309
3310 /* UL block should be received in SGSN */
3311 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3312
3313 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3314 tr_UlAckNackGprs(ms.tlli,
3315 tr_AckNackDescription(final_ack := '1'B),
3316 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3317 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3318
3319 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3320
3321 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
3322 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3323
3324 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3325 /* Now we go on receiving DL data and not answering RRBP: */
3326 nr := ts_TsTrxBtsNum;
3327 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3328 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3329 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3330 block_nr := nr.blk_nr));
3331 alt {
3332 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3333 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3334 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
3335 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3336 log("Ignoring RRBP N3105 ", N3105);
3337 N3105 := N3105 + 1;
3338 }
3339 nr := ts_TsTrxBtsNum;
3340 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3341 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3342 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3343 block_nr := nr.blk_nr));
3344 repeat;
3345 }
3346 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
3347 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
3348 */
3349 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3350 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3351 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3352 if (not T_3195.running) {
3353 T_3195.start;
3354 }
3355 nr := ts_TsTrxBtsNum;
3356 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3357 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3358 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3359 block_nr := nr.blk_nr));
3360 repeat;
3361 }
3362 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3363 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3364 omit)) -> value data_msg {
3365 /* We may already receive idle blocks before our own TTCN3 timer
3366 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
3367 nr := ts_TsTrxBtsNum;
3368 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3369 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3370 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3371 block_nr := nr.blk_nr));
3372 repeat;
3373 }
3374 /* We receive Dummy blocks in between Pkt Ul Ass while PCU waits for us to ack it */
3375 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3376 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3377 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3378 log("Ignoring Dummy block FN ", data_msg.raw.fn);
3379 nr := ts_TsTrxBtsNum;
3380 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3381 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3382 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3383 block_nr := nr.blk_nr));
3384 repeat;
3385 }
3386 [T_3195.running] T_3195.timeout {
3387 log("T_3195 timeout");
3388 /* Done in alt, wait for pending RTS initiated previously in
3389 * above case before continuing (expect nothing to be sent since there's no active TBF): */
3390 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3391 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3392 omit));
3393 }
3394 [] BTS.receive {
3395 setverdict(fail, "Unexpected BTS message");
3396 f_shutdown(__BFILE__, __LINE__);
3397 }
3398 }
3399
3400 f_shutdown(__BFILE__, __LINE__, final := true);
3401}
3402
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003403/* Test CS paging over the BTS<->PCU socket.
3404 * 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.
3405 * Paging should be send on the PACCH.
3406 *
3407 * 1. Send a Paging Request over PCU socket.
3408 * 2. Send a Ready-To-Send message over PCU socket
3409 * 3. Expect a Paging Frame
3410 */
3411testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003412 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003413 var MobileIdentityLV mi;
3414 var octetstring mi_enc_lv;
3415 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003416 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003417
3418 /* Initialize NS/BSSGP side */
3419 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003420 /* Initialize GPRS MS side */
3421 f_init_gprs_ms();
3422 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003423
3424 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003425 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003426
3427 /* Establish BSSGP connection to the PCU */
3428 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003429 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003430
3431 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003432 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003433
3434 /* build mobile Identity */
3435 mi := valueof(ts_MI_IMSI_LV(imsi));
3436 mi_enc_lv := enc_MobileIdentityLV(mi);
3437 /* Send paging request */
3438 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3439 sapi :=PCU_IF_SAPI_PDTCH));
3440
3441 /* Receive it on BTS side towards MS */
3442 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3443
3444 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003445 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3446 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3447 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3448 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003449
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003450 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003451}
3452
3453/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3454 */
3455private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3456runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003457 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003458 var hexstring imsi := f_gen_imsi(42);
3459 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003460 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003461
3462 /* Initialize NS/BSSGP side */
3463 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003464 /* Initialize GPRS MS side */
3465 f_init_gprs_ms();
3466 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003467
3468 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003469 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003470
3471 /* Establish BSSGP connection to the PCU */
3472 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003473 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003474
3475 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003476 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003477
3478 /* Send paging request with or without TMSI */
3479 if (use_ptmsi) {
3480 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3481 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3482 } else {
3483 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3484 }
3485
3486 /* Receive it on BTS side towards MS */
3487 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3488
3489 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003490 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003491 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003492 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3493 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3494 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003495 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003496 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3497 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3498 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003499 }
3500
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003501 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003502}
3503
3504testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3505 f_tc_paging_cs_from_sgsn(0, true);
3506}
3507
3508testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3509 f_tc_paging_cs_from_sgsn(0);
3510}
3511
3512testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003513 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003514}
3515
3516/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3517 */
3518private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3519runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003520 var integer imsi_suff_tx := 423;
3521 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003522 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003523
3524 /* Initialize NS/BSSGP side */
3525 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003526 /* Initialize GPRS MS side */
3527 f_init_gprs_ms();
3528 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003529
Oliver Smith61b4e732021-07-22 08:14:29 +02003530 f_statsd_reset();
3531
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003532 /* Establish BSSGP connection to the PCU */
3533 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003534 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003535
3536 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3537 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3538 if (use_ptmsi) {
3539 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3540 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3541 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3542 } else {
3543 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3544 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3545 }
3546
Oliver Smith61b4e732021-07-22 08:14:29 +02003547 if (mp_osmo_pcu_newer_than_0_9_0) {
3548 var StatsDExpects expect := {
Oliver Smith36d95d82021-08-06 22:01:53 +02003549 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3550 /* After the PCU receives the paging request from SGSN,
3551 * and it doesn't have any errors, PCU sends it to the
3552 * BTS to do paging over PCH. */
3553 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
Oliver Smith61b4e732021-07-22 08:14:29 +02003554 };
3555 f_statsd_expect(expect);
3556 }
Oliver Smithfbd39312021-07-27 15:23:39 +02003557}
3558
3559testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3560 /* Initialize the PCU interface abstraction */
3561 f_init_raw(testcasename());
3562
3563 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003564
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003565 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003566}
3567
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003568testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003569 /* Initialize the PCU interface abstraction */
3570 f_init_raw(testcasename());
3571
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003572 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003573
3574 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003575}
3576
3577testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003578 /* Initialize the PCU interface abstraction */
3579 f_init_raw(testcasename());
3580
Harald Welte5339b2e2020-10-04 22:52:56 +02003581 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003582
3583 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003584}
3585
Oliver Smithe1a77c42021-07-28 13:36:09 +02003586testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3587 /* Initialize the PCU interface abstraction */
3588 f_init_raw(testcasename());
3589
3590 /* Set T3113 to 1s to shorten the test duration */
3591 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3592
3593 /* Reset stats and send paging PS request */
3594 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3595
3596 /* Verify that counter increases when T3113 times out (MS did not start
3597 * TBF to respond to paging). */
3598 f_sleep(1.2);
3599 var StatsDExpects expect := {
3600 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3601 };
3602 f_statsd_expect(expect);
3603
3604 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3605 f_shutdown(__BFILE__, __LINE__, final := true);
3606}
3607
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003608/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3609testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3610 var RlcmacDlBlock dl_block;
3611 var octetstring data := f_rnd_octstring(10);
3612 var uint32_t sched_fn;
3613 var uint32_t dl_fn;
3614 var GprsMS ms;
3615
3616 /* Initialize NS/BSSGP side */
3617 f_init_bssgp();
3618 /* Initialize GPRS MS side */
3619 f_init_gprs_ms();
3620 ms := g_ms[0]; /* We only use first MS in this test */
3621
3622 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003623 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003624
Daniel Willmann535aea62020-09-21 13:27:08 +02003625 f_statsd_reset();
3626
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003627 /* Establish BSSGP connection to the PCU */
3628 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003629 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003630
3631 /* Establish an Uplink TBF */
3632 f_ms_establish_ul_tbf(ms);
3633
3634 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003635 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 +02003636 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3637 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3638 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3639
3640 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003641 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003642
3643 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3644 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3645 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3646
3647 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3648 f_sleep(X2002);
3649 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3650
3651 /* ACK the DL block */
3652 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3653 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3654 f_dl_block_ack_fn(dl_block, dl_fn));
3655
Daniel Willmann535aea62020-09-21 13:27:08 +02003656 var StatsDExpects expect := {
3657 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3658 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3659 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3660 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003661 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003662 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003663 };
3664 f_statsd_expect(expect);
3665
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003666 f_shutdown(__BFILE__, __LINE__, final := true);
3667}
3668
3669/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3670testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3671 var RlcmacDlBlock dl_block;
3672 var octetstring data := f_rnd_octstring(10);
3673 var uint32_t sched_fn;
3674 var uint32_t dl_fn;
3675 var GprsMS ms;
3676
3677 /* Initialize NS/BSSGP side */
3678 f_init_bssgp();
3679 /* Initialize GPRS MS side */
3680 f_init_gprs_ms();
3681 ms := g_ms[0]; /* We only use first MS in this test */
3682
3683 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003684 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003685
3686 /* Establish BSSGP connection to the PCU */
3687 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003688 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003689
3690 /* Establish an Uplink TBF */
3691 f_ms_establish_ul_tbf(ms);
3692
3693 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003694 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 +02003695 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3696 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3697 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3698
3699 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003700 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003701
3702 /* Now SGSN sends some DL data with an invalid IMSI */
3703 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3704
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003705 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003706
3707 /* TODO: make sure no data is sent over PCU -> MS */
3708
3709 f_shutdown(__BFILE__, __LINE__, final := true);
3710}
3711
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003712private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3713 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3714 var octetstring data := f_rnd_octstring(6);
3715 var RlcmacDlBlock dl_block;
3716 var GprsMS ms;
3717 var uint32_t fn;
3718
3719 /* Initialize NS/BSSGP side */
3720 f_init_bssgp();
3721 /* Initialize GPRS MS side */
3722 f_init_gprs_ms();
3723 ms := g_ms[0]; /* We only use first MS in this test */
3724
3725 /* Initialize the PCU interface abstraction */
3726 f_init_raw(testcasename());
3727
3728 /* Establish BSSGP connection to the PCU */
3729 f_bssgp_establish();
3730 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3731
3732 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3733 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3734 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3735
3736 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3737 f_sleep(X2002);
3738
3739 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3740 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3741
3742 if (ischosen(dl_block.data_egprs)) {
3743 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3744 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3745 f_shutdown(__BFILE__, __LINE__);
3746 }
3747 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3748 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3749 f_shutdown(__BFILE__, __LINE__);
3750 }
3751 if (not match(dl_block.data_egprs.blocks[1].payload,
3752 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3753 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3754 f_shutdown(__BFILE__, __LINE__);
3755 }
3756 } else if (lengthof(dl_block.data.blocks) > 1) {
3757 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3758 f_shutdown(__BFILE__, __LINE__);
3759 }
3760
3761 f_shutdown(__BFILE__, __LINE__, final := true);
3762}
3763
3764/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3765 * containing llc data. See OS#4849 */
3766testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3767 f_tc_dl_data_no_llc_ui_dummy(omit);
3768}
3769
3770/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3771 * containing llc data. See OS#4849 */
3772testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003773 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003774}
3775
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003776private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003777 template GsmRrMessage t_imm_ass := ?,
3778 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003779runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003780 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003781 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003782
3783 ra11 := enc_EGPRSPktChRequest2uint(req);
3784 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
3785
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07003786 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003787 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003788 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003789 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003790 }
3791
3792 setverdict(pass);
3793}
3794
3795testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
3796 var template GsmRrMessage imm_ass;
3797 var template IaRestOctets rest;
3798 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003799 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003800
3801 /* Initialize the PCU interface abstraction */
3802 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003803 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003804
3805 var EGPRSPktChRequest req := {
3806 /* NOTE: other fields are set in the loop */
3807 signalling := { tag := '110011'B }
3808 };
3809
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003810 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003811 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3812 req.signalling.random_bits := ext_ra;
3813
3814 /* For signalling, do we expect Multiblock UL TBF Assignment? */
3815 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3816 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3817 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3818
3819 f_TC_egprs_pkt_chan_req(req, imm_ass);
3820 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003821
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003822 if (mp_osmo_pcu_newer_than_0_9_0) {
3823 var StatsDExpects expect := {
3824 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3825 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3826 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3827 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3828 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3829 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3830 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3831 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3832 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3833 };
3834 f_statsd_expect(expect);
3835 }
3836
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003837 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003838}
3839
3840testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
3841 var template GsmRrMessage imm_ass;
3842 var template IaRestOctets rest;
3843 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003844 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003845
3846 /* Initialize the PCU interface abstraction */
3847 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003848 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003849
3850 var EGPRSPktChRequest req := {
3851 /* NOTE: other fields are set in the loop */
3852 one_phase := { tag := '0'B }
3853 };
3854
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003855 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003856 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3857 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
3858 var BIT2 priority := substr(ext_ra, 0, 2);
3859 var BIT3 rand := substr(ext_ra, 2, 3);
3860
3861 req.one_phase.multislot_class := mslot_class;
3862 req.one_phase.priority := priority;
3863 req.one_phase.random_bits := rand;
3864
3865 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
3866 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
3867 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3868 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3869
3870 f_TC_egprs_pkt_chan_req(req, imm_ass);
3871 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003872
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003873 if (mp_osmo_pcu_newer_than_0_9_0) {
3874 var StatsDExpects expect := {
3875 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3876 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3877 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
3878 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3879 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3880 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
3881 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3882 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3883 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3884 };
3885 f_statsd_expect(expect);
3886 }
3887
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003888 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003889}
3890
3891testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
3892 var template GsmRrMessage imm_ass;
3893 var template IaRestOctets rest;
3894 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003895 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003896
3897 /* Initialize the PCU interface abstraction */
3898 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003899 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003900
3901 var EGPRSPktChRequest req := {
3902 /* NOTE: other fields are set in the loop */
3903 two_phase := { tag := '110000'B }
3904 };
3905
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003906 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003907 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3908 var BIT2 priority := substr(ext_ra, 0, 2);
3909 var BIT3 rand := substr(ext_ra, 2, 3);
3910
3911 req.two_phase.priority := priority;
3912 req.two_phase.random_bits := rand;
3913
3914 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
3915 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3916 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3917 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3918
3919 f_TC_egprs_pkt_chan_req(req, imm_ass);
3920 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003921
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003922 if (mp_osmo_pcu_newer_than_0_9_0) {
3923 var StatsDExpects expect := {
3924 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3925 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3926 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3927 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3928 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3929 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3930 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3931 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3932 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3933 };
3934 f_statsd_expect(expect);
3935 }
3936
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003937 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003938}
3939
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003940private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
3941 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003942 PCUIF_BurstType bt := BURST_TYPE_1,
3943 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003944runs on RAW_PCU_Test_CT {
3945 var template ReqRefWaitInd tr_ref;
3946 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003947
3948 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
3949 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
3950 ra := bit2int(ra11), is_11bit := 1,
3951 burst_type := bt, fn := fn,
3952 arfcn := 871));
3953
3954 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07003955 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003956
3957 /* Just to have a short-name reference to the actual message */
3958 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
3959
3960 /* Make sure that Request Reference list contains at least one entry
3961 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003962 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003963 if (not match(iar.payload, { *, tr_ref, * })) {
3964 setverdict(fail, "Request Reference list does not match");
3965 f_shutdown(__BFILE__, __LINE__);
3966 }
3967
3968 /* Match Feature Indicator (must indicate PS domain) */
3969 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
3970 setverdict(fail, "Feature Indicator does not match");
3971 f_shutdown(__BFILE__, __LINE__);
3972 }
3973
3974 /* Match IAR Rest Octets */
3975 if (not match(iar.rest_octets, rest)) {
3976 setverdict(fail, "IAR Rest Octets does not match: ",
3977 iar.rest_octets, " vs expected ", rest);
3978 f_shutdown(__BFILE__, __LINE__);
3979 }
3980
3981 setverdict(pass);
3982}
3983
3984/* Verify the contents of RR Immediate Assignment Reject message and its
3985 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
3986testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
3987 var template IARRestOctets rest;
3988 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003989 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003990
3991 /* Initialize the PCU interface abstraction */
3992 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003993 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003994
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003995 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003996 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
3997 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
3998
3999 /* Intentionally incorrect message (see table 11.2.5a.2) */
4000 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4001 }
4002
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004003 if (mp_osmo_pcu_newer_than_0_9_0) {
4004 var StatsDExpects expect := {
4005 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4006 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4007 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4008 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4009 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4010 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4011 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4012 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4013 };
4014 f_statsd_expect(expect);
4015 }
4016
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004017 f_shutdown(__BFILE__, __LINE__, final := true);
4018}
4019
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004020/* At the moment, the IUT does not support any emergency services. Make sure
4021 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4022testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4023 var template IARRestOctets rest;
4024 var BIT5 ext_ra;
4025 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004026 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004027
4028 /* Initialize the PCU interface abstraction */
4029 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004030 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004031
4032 var EGPRSPktChRequest req := {
4033 /* NOTE: other fields are set in the loop */
4034 emergency := { tag := '110111'B }
4035 };
4036
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004037 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004038 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4039 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4040
4041 req.emergency.random_bits := ext_ra;
4042 ra11 := enc_EGPRSPktChRequest2bits(req);
4043
4044 /* Intentionally incorrect message (see table 11.2.5a.2) */
4045 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4046 }
4047
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004048 if (mp_osmo_pcu_newer_than_0_9_0) {
4049 var StatsDExpects expect := {
4050 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4051 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4052 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4053 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4054 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4055 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4056 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4057 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4058 };
4059 f_statsd_expect(expect);
4060 }
4061
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004062 f_shutdown(__BFILE__, __LINE__, final := true);
4063}
4064
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004065/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4066testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004067 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004068 var template IARRestOctets rest;
4069 var BIT11 ra11;
4070
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004071 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004072 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004073
4074 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004075 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4076 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004077
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004078 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004079 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004080 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004081
4082 var EGPRSPktChRequest req := {
4083 one_phase := {
4084 tag := '0'B,
4085 multislot_class := '10101'B,
4086 priority := '01'B,
4087 random_bits := '101'B
4088 }
4089 };
4090
4091 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4092 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4093 for (var integer i := 0; i < 7; i := i + 1) {
4094 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4095 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4096 }
4097
4098 ra11 := enc_EGPRSPktChRequest2bits(req);
4099 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4100
4101 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004102 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004103
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004104 if (mp_osmo_pcu_newer_than_0_9_0) {
4105 var StatsDExpects expect := {
4106 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4107 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4108 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4109 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4110 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4111 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4112 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4113 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4114 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4115 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4116 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4117 };
4118 f_statsd_expect(expect);
4119 }
4120
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004121 f_shutdown(__BFILE__, __LINE__, final := true);
4122}
4123
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004124/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004125private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004126return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004127 /* Pick a random MA length in range 2 .. max_ma_len */
4128 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4129
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004130 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4131 hsn := f_rnd_int(63),
4132 maio := f_rnd_int(63),
4133 ma := f_rnd_bitstring(ma_len));
4134}
4135
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004136private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4137 in GsmRrMessage rr_msg)
4138{
4139 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004140 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004141
4142 var template PacketChannelDescription tr_pkt_chan_desc := {
4143 channel_Type_spare := ?,
4144 tn := ?,
4145 tsc := ts.tsc,
4146 presence := '1'B,
4147 zero := omit,
4148 one := {
4149 maio := ts.maio,
4150 hsn := ts.hsn
4151 }
4152 };
4153
4154 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4155 setverdict(fail, "Packet Channel Description does not match: ",
4156 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4157 }
4158
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004159 /* Mobile Allocation is expected to be octet-aligned */
4160 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4161 var template MobileAllocationLV tr_ma := {
4162 len := ma_oct_len, /* in bytes */
4163 ma := substr(ts.ma, 0, ma_oct_len * 8)
4164 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004165
4166 if (not match(ia.mobile_allocation, tr_ma)) {
4167 setverdict(fail, "Mobile Allocation does not match: ",
4168 ia.mobile_allocation, " vs ", tr_ma);
4169 }
4170
4171 setverdict(pass);
4172}
4173
4174/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4175testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004176 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004177 var GprsMS ms := valueof(t_GprsMS_def);
4178
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004179 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004180 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004181
4182 /* Initialize the PCU interface abstraction */
4183 f_init_raw(testcasename(), info_ind);
4184
4185 /* EGPRS Packet Channel Request (cause=Signalling) */
4186 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4187
4188 /* Establish an Uplink EGPRS TBF */
4189 f_ms_establish_ul_tbf(ms);
4190
4191 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4192 f_shutdown(__BFILE__, __LINE__, final := true);
4193}
4194
4195/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4196testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004197 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004198 var GprsMS ms := valueof(t_GprsMS_def);
4199
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004200 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004201 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004202
4203 /* Initialize the PCU interface abstraction */
4204 f_init_raw(testcasename(), info_ind);
4205
4206 /* Establish an Uplink TBF */
4207 f_ms_establish_ul_tbf(ms);
4208
4209 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4210 f_shutdown(__BFILE__, __LINE__, final := true);
4211}
4212
4213/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4214testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004215 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004216 var GprsMS ms := valueof(t_GprsMS_def);
4217
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004218 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004219 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004220
4221 /* Initialize NS/BSSGP side */
4222 f_init_bssgp();
4223
4224 /* Initialize the PCU interface abstraction */
4225 f_init_raw(testcasename(), info_ind);
4226
4227 /* Establish BSSGP connection to the PCU */
4228 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004229 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004230
4231 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4232 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4233 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4234
4235 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4236 f_shutdown(__BFILE__, __LINE__, final := true);
4237}
4238
4239private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4240 in FrequencyParameters fp)
4241{
4242 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004243 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004244
4245 /* Table 12.8.1: Frequency Parameters information elements */
4246 var template FrequencyParameters tr_fp := {
4247 tsc := ts.tsc,
4248 presence := '10'B, /* Direct encoding 1 */
4249 arfcn := omit,
4250 indirect := omit,
4251 direct1 := {
4252 maio := ts.maio,
4253 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4254 mobile_allocation := {
4255 hsn := ts.hsn,
4256 rfl_number_list_present := '0'B,
4257 rfl_number_list := omit,
4258 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004259 ma_length := ts.ma_bit_len,
4260 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004261 }
4262 },
4263 direct2 := omit
4264 };
4265
4266 if (not match(fp, tr_fp)) {
4267 setverdict(fail, "Frequency Parameters IE does not match: ",
4268 fp, " vs ", tr_fp);
4269 }
4270
4271 setverdict(pass);
4272}
4273
4274/* Make sure that Packet Uplink Assignment contains hopping parameters */
4275testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004276 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004277 var GprsMS ms := valueof(t_GprsMS_def);
4278 var uint32_t poll_fn;
4279
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004280 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004281 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004282
4283 /* Initialize the PCU interface abstraction */
4284 f_init_raw(testcasename(), info_ind);
4285
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004286 /* Single block (two phase) packet access */
4287 var uint16_t ra := bit2int(chan_req_sb);
4288 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4289
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004290 /* Establish an Uplink TBF */
4291 f_ms_establish_ul_tbf(ms);
4292
4293 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004294 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4295 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004296
4297 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004298 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4299 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004300
4301 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4302 var template (omit) FrequencyParameters fp;
4303 if (ua.is_egprs == '1'B) {
4304 fp := ua.egprs.freq_par;
4305 } else {
4306 fp := ua.gprs.freq_par;
4307 }
4308
4309 /* This is an optional IE, so it's worth to check its presence */
4310 if (istemplatekind(fp, "omit")) {
4311 setverdict(fail, "Frequency Parameters IE is not present");
4312 f_shutdown(__BFILE__, __LINE__);
4313 }
4314
4315 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4316 f_shutdown(__BFILE__, __LINE__, final := true);
4317}
4318
4319/* Make sure that Packet Downlink Assignment contains hopping parameters */
4320testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004321 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004322 var octetstring data := f_rnd_octstring(10);
4323 var GprsMS ms := valueof(t_GprsMS_def);
4324 var RlcmacDlBlock dl_block;
4325 var uint32_t poll_fn;
4326
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004327 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004328 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004329
4330 /* Initialize NS/BSSGP side */
4331 f_init_bssgp();
4332
4333 /* Initialize the PCU interface abstraction */
4334 f_init_raw(testcasename(), info_ind);
4335
4336 /* Establish BSSGP connection to the PCU */
4337 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004338 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004339
4340 /* Establish an Uplink TBF */
4341 f_ms_establish_ul_tbf(ms);
4342
4343 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004344 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 +07004345
4346 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4347 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4348 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4349
4350 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4351 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4352
4353 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004354 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4355 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004356
4357 /* This is an optional IE, so it's worth to check its presence */
4358 if (not ispresent(da.freq_par)) {
4359 setverdict(fail, "Frequency Parameters IE is not present");
4360 f_shutdown(__BFILE__, __LINE__);
4361 }
4362
4363 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4364 f_shutdown(__BFILE__, __LINE__, final := true);
4365}
4366
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004367/* Check if the IUT handles subsequent INFO.ind messages */
4368testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004369 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004370 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004371
4372 /* Initialize the PCU interface abstraction */
4373 f_init_raw(testcasename(), info_ind);
4374
4375 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4376 for (var integer i := 0; i < 16; i := i + 1) {
4377 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004378 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004379 }
4380
4381 f_shutdown(__BFILE__, __LINE__, final := true);
4382}
4383
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004384/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4385testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4386 var PCUIF_info_ind info_ind;
4387 var integer i;
4388 const integer num_ms := 8;
4389
4390 /* Initialize NS/BSSGP side */
4391 f_init_bssgp();
4392 /* Initialize GPRS MS side */
4393 f_init_gprs_ms(num_ms);
4394
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004395 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004396 /* Only the 3 first TRX are enabled. The enabled ones all have same
4397 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004398 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4399 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4400 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4401 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004402
4403 /* Initialize the PCU interface abstraction */
4404 f_init_raw(testcasename(), info_ind);
4405
4406 /* Establish BSSGP connection to the PCU */
4407 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004408 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004409
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004410 /* Establish an Uplink TBF for each GprsMS instance */
4411 f_multi_ms_establish_tbf(do_activate := false);
4412
4413 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004414 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004415 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004416 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004417 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004418 f_shutdown(__BFILE__, __LINE__);
4419 }
4420 }
4421
4422 f_shutdown(__BFILE__, __LINE__, final := true);
4423}
4424
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004425/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4426 * downgraded to CS1-4 so that GPRS can read the USF).
4427 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4428 */
4429testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4430 var PCUIF_info_ind info_ind;
4431 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4432 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004433 var uint32_t sched_fn, dl_fn, ack_fn;
4434 var octetstring data := f_rnd_octstring(10);
4435 var RlcmacDlBlock dl_block;
4436 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004437 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004438 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4439 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4440
4441 /* Initialize NS/BSSGP side */
4442 f_init_bssgp();
4443 /* Initialize GPRS MS side */
4444 f_init_gprs_ms(num_ms);
4445
4446 info_ind := valueof(ts_PCUIF_INFO_default);
4447 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004448 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4449 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004450
4451 /* Initialize the PCU interface abstraction */
4452 f_init_raw(testcasename(), info_ind);
4453
4454 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4455 g_mcs_initial_dl := 5;
4456 g_mcs_max_dl := 5;
4457 f_pcuvty_set_allowed_cs_mcs();
4458
4459 /* Establish BSSGP connection to the PCU */
4460 f_bssgp_establish();
4461 f_multi_ms_bssgp_register();
4462
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004463 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004464 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 +01004465 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4466 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4467 f_shutdown(__BFILE__, __LINE__);
4468 }
4469 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4470 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4471
4472 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004473 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 +01004474 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4475 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4476 f_shutdown(__BFILE__, __LINE__);
4477 }
4478 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4479 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4480
4481 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4482 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4483 f_sleep(0.1);
4484 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4485 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4486 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4487 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4488 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4489 /* ACK the DL block */
4490 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4491 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4492 f_dl_block_ack_fn(dl_block, dl_fn));
4493
4494 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4495 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4496 f_sleep(0.1);
4497 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4498 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4499 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4500 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4501 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4502 /* ACK the DL block */
4503 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4504 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4505 f_dl_block_ack_fn(dl_block, dl_fn));
4506
4507 data := f_rnd_octstring(1400);
4508 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4509 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4510
4511 for (var integer i := 0; i < 800; i := i + 1) {
4512 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4513
4514 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
4515 /* No more data to receive, done */
4516 break;
4517 }
4518
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004519 usf_ms := -1;
4520
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004521 if (ischosen(dl_block.ctrl)) {
4522 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4523 f_shutdown(__BFILE__, __LINE__);
4524 } else if (ischosen(dl_block.data_egprs)) {
4525 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4526 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4527 f_shutdown(__BFILE__, __LINE__);
4528 }
4529 tgt_ms := 1;
4530 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4531 if (dl_block.data_egprs.mcs > MCS_4) {
4532 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4533 f_shutdown(__BFILE__, __LINE__);
4534 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004535 usf_ms := 0;
4536 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004537 } else {
4538 if (dl_block.data_egprs.mcs <= MCS_4) {
4539 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4540 f_shutdown(__BFILE__, __LINE__);
4541 }
4542 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004543 usf_ms := 1;
4544 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004545 }
4546 }
4547 } else {
4548 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4549 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4550 f_shutdown(__BFILE__, __LINE__);
4551 }
4552 tgt_ms := 0;
4553 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 +01004554 usf_ms := 0;
4555 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004556 } 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 +01004557 usf_ms := 1;
4558 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004559 }
4560 }
4561
4562 /* Keep Ack/Nack description updated */
4563 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4564
4565 /* TDMA frame number on which we are supposed to send the ACK */
4566 if (f_dl_block_rrbp_valid(dl_block)) {
4567 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4568 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);
4569 if (tx_data_remain != 0) {
4570 /* Submit more data from time to time to keep the TBF ongoing */
4571 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4572 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4573 tx_data_remain := tx_data_remain - 1;
4574 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004575 } else if (tx_data_remain != 0) {
4576 /* keep sending UL blocks when requested by USF to avoid
4577 * UL TBF timeout and hence stop receival of USFs */
4578 if (usf_ms != -1) {
4579 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4580 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004581 }
4582 }
4583
4584 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 +01004585 /* He we check that DL blocks scheduled at GPRS can still request UL
4586 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4587 * condition also ensures the downgrade to <=MCS4 condition is tested
4588 * above */
4589 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4590 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004591 f_shutdown(__BFILE__, __LINE__);
4592 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004593 /* Here check for some level of fairness between them (at least ~40%): */
4594 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4595 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4596 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4597 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4598 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4599 f_shutdown(__BFILE__, __LINE__);
4600 }
4601 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4602 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4603 f_shutdown(__BFILE__, __LINE__);
4604 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004605
4606 f_shutdown(__BFILE__, __LINE__, final := true);
4607}
4608
4609
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004610private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4611 boolean exp_imsi, boolean exp_tmsi)
4612runs on RAW_PCU_Test_CT {
4613 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4614 var integer pending := lengthof(g_ms);
4615 var RlcmacDlBlock dl_block;
4616 var boolean f1, f2;
4617
4618 while (pending > 0) {
4619 var uint32_t poll_fn;
4620
4621 /* Obtain a Downlink block and make sure it is a paging request */
4622 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4623 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4624 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4625 break;
4626 }
4627
4628 /* This should not happen in general, but who knows... */
4629 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4630 if (not ispresent(req.repeated_pageinfo)) {
4631 setverdict(fail, "Repeated Page Info IE is absent?!?");
4632 break;
4633 }
4634
4635 /* A single message may contain several MIs depending on their type */
4636 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4637 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4638 ps_domain := false);
4639 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4640 ps_domain := false);
4641 if (not f1 and not f2)
4642 { continue; }
4643
4644 /* Detect duplicate MIs */
4645 if (mask[i] == '1'B) {
4646 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4647 continue;
4648 }
4649
4650 mask[i] := '1'B;
4651 }
4652
4653 pending := pending - lengthof(req.repeated_pageinfo);
4654 }
4655
4656 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4657 if (mask[i] != '1'B) {
4658 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
4659 log("===== mask := ", mask);
4660 }
4661 }
4662
4663 /* All messages must have been received by now, expect a dummy block */
4664 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
4665}
4666
4667private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
4668runs on RAW_PCU_Test_CT {
4669 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4670 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4671
4672 /* Initialize NS/BSSGP side */
4673 f_init_bssgp();
4674
4675 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004676 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004677
4678 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
4679 f_init_gprs_ms(7 * 8);
4680
4681 /* Initialize the PCU interface abstraction */
4682 f_init_raw(testcasename(), info_ind);
4683
4684 /* Establish BSSGP connection to the PCU */
4685 f_bssgp_establish();
4686 f_multi_ms_bssgp_register();
4687
4688 /* Establish an Uplink TBF for each GprsMS instance */
4689 f_multi_ms_establish_tbf(do_activate := true);
4690}
4691
4692testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
4693 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4694
4695 /* Common part: send INFO.ind, establish TBFs... */
4696 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4697
4698 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
4699 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4700 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4701 }
4702
4703 /* FIXME: work around a race condition between PCUIF and BSSGP */
4704 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4705
4706 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4707 * The IUT is expected to page on all PDCH slots of all transceivers. */
4708 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4709 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4710 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
4711 }
4712
4713 f_shutdown(__BFILE__, __LINE__, final := true);
4714}
4715
4716testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
4717 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4718
4719 /* Common part: send INFO.ind, establish TBFs... */
4720 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4721
4722 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
4723 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4724 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4725 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4726 }
4727
4728 /* FIXME: work around a race condition between PCUIF and BSSGP */
4729 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4730
4731 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4732 * The IUT is expected to page on all PDCH slots of all transceivers. */
4733 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4734 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4735 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
4736 }
4737
4738 f_shutdown(__BFILE__, __LINE__, final := true);
4739}
4740
4741testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
4742 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4743
4744 /* Common part: send INFO.ind, establish TBFs... */
4745 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4746
4747 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
4748 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4749 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4750 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
4751 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4752 } else {
4753 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4754 }
4755 }
4756
4757 /* FIXME: work around a race condition between PCUIF and BSSGP */
4758 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4759
4760 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4761 * The IUT is expected to page on all PDCH slots of all transceivers. */
4762 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4763 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4764 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
4765 }
4766
4767 f_shutdown(__BFILE__, __LINE__, final := true);
4768}
4769
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004770private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004771runs on RAW_PCU_Test_CT return RlcmacDlBlock {
4772 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004773 var integer i := 0;
4774 while (true) {
4775 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4776 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
4777 break;
4778 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004779 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004780 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4781 f_shutdown(__BFILE__, __LINE__);
4782 }
4783 i := i + 1;
4784 }
4785 return dl_block;
4786}
4787
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004788private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
4789runs on RAW_PCU_Test_CT {
4790 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),
4791 info_ind.lac),
4792 info_ind.rac),
4793 info_ind.cell_id));
4794 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4795 423),
4796 2),
4797 5));
4798 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4799 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4800 var template (value) RAN_Information_RIM_Container res_cont :=
4801 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
4802 ts_RIM_Sequence_Number(2),
4803 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
4804 ts_RIM_Protocol_Version_Number(1),
4805 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
4806 omit);
4807 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4808 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4809 res_cont));
4810}
4811
4812altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
4813runs on RAW_PCU_Test_CT {
4814 /* RIM procedure: */
4815 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),
4816 info_ind.lac),
4817 info_ind.rac),
4818 info_ind.cell_id));
4819 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4820 423),
4821 2),
4822 5));
4823 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4824 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4825 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4826 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4827 tr_RAN_Information_Request_RIM_Container)) {
4828 if (do_answer) {
4829 f_outbound_nacc_rim_tx_resp(info_ind);
4830 }
4831 if (do_repeat) {
4832 repeat;
4833 }
4834 }
4835}
4836
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004837private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
4838 boolean answer := true, boolean use_old_ctrl_iface := false)
4839runs on RAW_PCU_Test_CT {
4840 if (use_old_ctrl_iface == true) {
4841 f_ipa_ctrl_wait_link_up();
4842 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4843 int2str(info_ind.lac) & "." &
4844 int2str(info_ind.cell_id) & "." &
4845 int2str(req_arfcn) & "." &
4846 int2str(req_bsic);
4847 if (answer) {
4848 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4849 } else {
4850 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
4851 }
4852 } else {
4853 var PCUIF_Message pcu_msg;
4854 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
4855 if (answer) {
4856 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
4857 }
4858 }
4859}
4860
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004861/* Start NACC from MS side */
4862private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004863 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004864 boolean skip_final_ctrl_ack := false,
4865 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004866runs on RAW_PCU_Test_CT {
4867 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4868 var RlcmacDlBlock dl_block;
4869 var uint32_t sched_fn;
4870 var GsmArfcn req_arfcn := 862;
4871 var uint6_t req_bsic := 43;
4872
4873 /* Start NACC from MS side */
4874 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4875 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4876
4877 if (exp_rac_ci_query == true) {
4878 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004879 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 +01004880 }
4881
4882 if (exp_si_query == true) {
4883 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004884 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004885 }
4886
4887 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004888 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004889
4890 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
4891 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4892 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4893 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4894 f_shutdown(__BFILE__, __LINE__);
4895 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004896 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004897 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004898 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4899 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4900 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004901}
4902
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004903/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
4904testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004905 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004906 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004907 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004908 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004909
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004910 if (use_old_ctrl_iface) {
4911 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4912 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4913 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004914
4915 /* Initialize NS/BSSGP side */
4916 f_init_bssgp();
4917 /* Initialize GPRS MS side */
4918 f_init_gprs_ms();
4919 ms := g_ms[0]; /* We only use first MS in this test */
4920
4921 /* Initialize the PCU interface abstraction */
4922 f_init_raw(testcasename(), info_ind);
4923
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004924 /* Make sure we are not affected by full cache from previous tests */
4925 f_pcuvty_flush_neigh_caches();
4926
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004927 /* Establish BSSGP connection to the PCU */
4928 f_bssgp_establish();
4929 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4930
4931 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004932 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 +01004933 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4934 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4935
4936 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004937 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004938
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004939 f_shutdown(__BFILE__, __LINE__, final := true);
4940}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004941
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004942/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
4943testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
4944 var PollFnCtx pollctx;
4945 var GprsMS ms;
4946 var RlcmacDlBlock dl_block;
4947 var uint32_t sched_fn;
4948 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004949 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004950
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004951 if (use_old_ctrl_iface) {
4952 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4953 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4954 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004955
4956 /* Initialize NS/BSSGP side */
4957 f_init_bssgp();
4958 /* Initialize GPRS MS side */
4959 f_init_gprs_ms();
4960 ms := g_ms[0]; /* We only use first MS in this test */
4961
4962 /* Initialize the PCU interface abstraction */
4963 f_init_raw(testcasename(), info_ind);
4964
4965 /* Make sure we are not affected by full cache from previous tests */
4966 f_pcuvty_flush_neigh_caches();
4967
4968 /* Establish BSSGP connection to the PCU */
4969 f_bssgp_establish();
4970 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4971
4972 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004973 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 +01004974 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4975 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4976
4977 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004978 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 +01004979
4980 /* Wait until we receive something non-dummy */
4981 dl_block := f_skip_dummy(0, sched_fn);
4982 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
4983 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4984 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4985 }
4986 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4987 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4988 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4989 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4990 }
4991
4992 f_shutdown(__BFILE__, __LINE__, final := true);
4993}
4994
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004995/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
4996testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
4997 var PollFnCtx pollctx;
4998 var GprsMS ms;
4999 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005000 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005001 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005002
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005003 if (use_old_ctrl_iface) {
5004 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5005 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5006 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005007
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005008 /* Initialize NS/BSSGP side */
5009 f_init_bssgp();
5010 /* Initialize GPRS MS side */
5011 f_init_gprs_ms();
5012 ms := g_ms[0]; /* We only use first MS in this test */
5013
5014 /* Initialize the PCU interface abstraction */
5015 f_init_raw(testcasename(), info_ind);
5016
5017 /* Make sure we are not affected by full cache from previous tests */
5018 f_pcuvty_flush_neigh_caches();
5019 /* Set timeout values for caches so that entries will be in cache during second try */
5020 f_pcuvty_set_neigh_caches(10, 10);
5021
5022 /* Establish BSSGP connection to the PCU */
5023 f_bssgp_establish();
5024 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5025
5026 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005027 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 +01005028 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5029 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5030
5031 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005032 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005033
5034 /* 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 +02005035 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 +01005036
5037 f_shutdown(__BFILE__, __LINE__, final := true);
5038}
5039
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005040/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5041 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5042 */
5043testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5044 var PollFnCtx pollctx;
5045 var GprsMS ms;
5046 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005047 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005048 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005049
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005050 if (use_old_ctrl_iface) {
5051 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5052 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5053 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005054
5055 /* Initialize NS/BSSGP side */
5056 f_init_bssgp();
5057 /* Initialize GPRS MS side */
5058 f_init_gprs_ms();
5059 ms := g_ms[0]; /* We only use first MS in this test */
5060
5061 /* Initialize the PCU interface abstraction */
5062 f_init_raw(testcasename(), info_ind);
5063
5064 /* Make sure we are not affected by full cache from previous tests */
5065 f_pcuvty_flush_neigh_caches();
5066 /* Set timeout values for caches so that entries will be erased before the second try */
5067 f_pcuvty_set_neigh_caches(1, 1);
5068
5069 /* Establish BSSGP connection to the PCU */
5070 f_bssgp_establish();
5071 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5072
5073 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005074 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 +01005075 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5076 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5077
5078 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005079 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005080
5081 /* CTRL client should have disconnected from us */
5082 f_ipa_ctrl_wait_link_down();
5083 /* wait for cache entries to time out */
5084 f_sleep(2.0);
5085 /* 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 +02005086 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005087
5088 f_shutdown(__BFILE__, __LINE__, final := true);
5089}
5090
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005091/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005092testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5093 var RlcmacDlBlock dl_block;
5094 var PollFnCtx pollctx;
5095 var uint32_t sched_fn;
5096 var GprsMS ms;
5097 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5098 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005099 var GsmArfcn req_arfcn := 862;
5100 var uint6_t req_bsic := 43;
5101
5102 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5103 * resolution CTRL port, to trigger Conn Refused by socket:
5104 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5105 */
5106
5107 /* Initialize NS/BSSGP side */
5108 f_init_bssgp();
5109 /* Initialize GPRS MS side */
5110 f_init_gprs_ms();
5111 ms := g_ms[0]; /* We only use first MS in this test */
5112
5113 /* Initialize the PCU interface abstraction */
5114 f_init_raw(testcasename(), info_ind);
5115
5116 /* Make sure we are not affected by full cache from previous tests */
5117 f_pcuvty_flush_neigh_caches();
5118
5119 /* Establish BSSGP connection to the PCU */
5120 f_bssgp_establish();
5121 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5122
5123 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005124 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 +01005125 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5126 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5127
5128 /* Start NACC from MS side */
5129 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5130 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5131
5132 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005133 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005134 /* Make sure it is a Pkt Cell Chg Continue */
5135 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5136 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5137 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005138 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5139 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5140 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5141 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5142 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005143
5144 f_shutdown(__BFILE__, __LINE__, final := true);
5145}
5146
5147/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005148testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5149 var RlcmacDlBlock dl_block;
5150 var PollFnCtx pollctx;
5151 var uint32_t sched_fn;
5152 var GprsMS ms;
5153 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5154 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005155 var GsmArfcn req_arfcn := 862;
5156 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005157 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005158
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005159 if (use_old_ctrl_iface) {
5160 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5161 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5162 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005163
5164 /* Initialize NS/BSSGP side */
5165 f_init_bssgp();
5166 /* Initialize GPRS MS side */
5167 f_init_gprs_ms();
5168 ms := g_ms[0]; /* We only use first MS in this test */
5169
5170 /* Initialize the PCU interface abstraction */
5171 f_init_raw(testcasename(), info_ind);
5172
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005173 /* Make sure we are not affected by full cache from previous tests */
5174 f_pcuvty_flush_neigh_caches();
5175
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005176 /* Establish BSSGP connection to the PCU */
5177 f_bssgp_establish();
5178 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5179
5180 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005181 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 +01005182 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5183 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5184
5185 /* Start NACC from MS side */
5186 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5187 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5188
5189 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005190 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005191 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 +01005192
5193 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005194 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005195 /* Make sure it is a Pkt Cell Chg Continue */
5196 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5197 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5198 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005199 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5200 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5201 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5202 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5203 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005204
5205 f_shutdown(__BFILE__, __LINE__, final := true);
5206}
5207
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005208/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5209testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5210 var RlcmacDlBlock dl_block;
5211 var PollFnCtx pollctx;
5212 var uint32_t sched_fn;
5213 var GprsMS ms;
5214 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5215 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005216 var GsmArfcn req_arfcn := 862;
5217 var uint6_t req_bsic := 43;
5218
5219 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5220 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5221
5222 /* Initialize NS/BSSGP side */
5223 f_init_bssgp();
5224 /* Initialize GPRS MS side */
5225 f_init_gprs_ms();
5226 ms := g_ms[0]; /* We only use first MS in this test */
5227
5228 /* Initialize the PCU interface abstraction */
5229 f_init_raw(testcasename(), info_ind);
5230
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005231 /* Make sure we are not affected by full cache from previous tests */
5232 f_pcuvty_flush_neigh_caches();
5233
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005234 /* Establish BSSGP connection to the PCU */
5235 f_bssgp_establish();
5236 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5237
5238 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005239 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 +01005240 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5241 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5242
5243 /* Start NACC from MS side */
5244 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5245 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5246
5247 /* osmo-pcu should now ask for resolution: */
5248 f_ipa_ctrl_wait_link_up();
5249 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5250 int2str(info_ind.lac) & "." &
5251 int2str(info_ind.cell_id) & "." &
5252 int2str(req_arfcn) & "." &
5253 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005254 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005255 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5256
5257 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005258 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005259 /* Make sure it is a Pkt Cell Chg Continue */
5260 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5261 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5262 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005263 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5264 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5265 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5266 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5267 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005268
5269 f_shutdown(__BFILE__, __LINE__, final := true);
5270}
5271
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005272/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5273testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5274 var RlcmacDlBlock dl_block;
5275 var PollFnCtx pollctx;
5276 var uint32_t sched_fn;
5277 var GprsMS ms;
5278 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5279 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005280 var GsmArfcn req_arfcn := 862;
5281 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005282 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005283 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 */
5284 info_ind.lac),
5285 info_ind.rac),
5286 info_ind.cell_id));
5287 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5288 423),
5289 2),
5290 5));
5291 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
5292 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
5293
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005294 if (use_old_ctrl_iface) {
5295 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5296 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5297 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005298
5299 /* Initialize NS/BSSGP side */
5300 f_init_bssgp();
5301 /* Initialize GPRS MS side */
5302 f_init_gprs_ms();
5303 ms := g_ms[0]; /* We only use first MS in this test */
5304
5305 /* Initialize the PCU interface abstraction */
5306 f_init_raw(testcasename(), info_ind);
5307
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005308 /* Make sure we are not affected by full cache from previous tests */
5309 f_pcuvty_flush_neigh_caches();
5310
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005311 /* Establish BSSGP connection to the PCU */
5312 f_bssgp_establish();
5313 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5314
5315 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005316 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 +01005317 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5318 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5319
5320 /* Start NACC from MS side */
5321 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5322 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5323
5324 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005325 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 +01005326
5327 /* RIM procedure: */
5328 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5329 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5330 tr_RAN_Information_Request_RIM_Container));
5331 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5332
5333 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005334 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005335 /* Make sure it is a Pkt Cell Chg Continue */
5336 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5337 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5338 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005339 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5340 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5341 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5342 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5343 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005344
5345 f_shutdown(__BFILE__, __LINE__, final := true);
5346}
5347
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005348/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5349testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5350 var PollFnCtx pollctx;
5351 var GprsMS ms;
5352 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5353 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5354 var RlcmacDlBlock dl_block;
5355 var uint32_t sched_fn;
5356 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005357 var charstring ctrl_var;
5358 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005359 var GsmArfcn req_arfcn := 862;
5360 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005361 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005362
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005363 if (use_old_ctrl_iface) {
5364 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5365 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5366 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005367
5368 /* Initialize NS/BSSGP side */
5369 f_init_bssgp();
5370 /* Initialize GPRS MS side */
5371 f_init_gprs_ms();
5372 ms := g_ms[0]; /* We only use first MS in this test */
5373
5374 /* Initialize the PCU interface abstraction */
5375 f_init_raw(testcasename(), info_ind);
5376
5377 /* Make sure we are not affected by full cache from previous tests */
5378 f_pcuvty_flush_neigh_caches();
5379
5380 /* Establish BSSGP connection to the PCU */
5381 f_bssgp_establish();
5382 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5383
5384 /* Send PACKET RESOURCE REQUEST */
5385 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5386 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5387 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5388
5389 /* Start NACC from MS side */
5390 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5391 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5392
5393 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005394 if (use_old_ctrl_iface) {
5395 f_ipa_ctrl_wait_link_up();
5396 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5397 int2str(info_ind.lac) & "." &
5398 int2str(info_ind.cell_id) & "." &
5399 int2str(req_arfcn) & "." &
5400 int2str(req_bsic);
5401 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5402 } else {
5403 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5404 }
5405
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005406 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5407 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5408 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005409
5410 if (use_old_ctrl_iface) {
5411 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5412 } else {
5413 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5414 }
5415
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005416 timer T := 2.0;
5417 T.start;
5418 alt {
5419 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005420 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005421 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5422 f_shutdown(__BFILE__, __LINE__);
5423 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005424 [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 {
5425 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5426 f_shutdown(__BFILE__, __LINE__);
5427 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005428 [] T.timeout {
5429 setverdict(pass);
5430 }
5431 }
5432
5433 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005434 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005435
5436 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5437 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5438 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5439 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5440 f_shutdown(__BFILE__, __LINE__);
5441 }
5442 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5443 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5444 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5445 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5446 }
5447
5448 f_shutdown(__BFILE__, __LINE__, final := true);
5449}
5450
5451/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5452testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5453 var PollFnCtx pollctx;
5454 var GprsMS ms;
5455 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5456 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5457 var RlcmacDlBlock dl_block;
5458 var uint32_t sched_fn;
5459 var CtrlMessage rx_ctrl;
5460 var GsmArfcn req_arfcn := 862;
5461 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005462 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005463
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005464 if (use_old_ctrl_iface) {
5465 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5466 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5467 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005468
5469 /* Initialize NS/BSSGP side */
5470 f_init_bssgp();
5471 /* Initialize GPRS MS side */
5472 f_init_gprs_ms();
5473 ms := g_ms[0]; /* We only use first MS in this test */
5474
5475 /* Initialize the PCU interface abstraction */
5476 f_init_raw(testcasename(), info_ind);
5477
5478 /* Make sure we are not affected by full cache from previous tests */
5479 f_pcuvty_flush_neigh_caches();
5480
5481 /* Establish BSSGP connection to the PCU */
5482 f_bssgp_establish();
5483 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5484
5485 /* Send PACKET RESOURCE REQUEST */
5486 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5487 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5488 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5489
5490 /* Start NACC from MS side */
5491 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5492 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5493
5494 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005495 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 +01005496 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5497 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5498 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5499 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5500 f_outbound_nacc_rim_tx_resp(info_ind);
5501 timer T := 1.0;
5502 T.start;
5503 alt {
5504 [] RIM.receive {
5505 setverdict(fail, "Received unexpected RIM message");
5506 f_shutdown(__BFILE__, __LINE__);
5507 }
5508 [] T.timeout {
5509 setverdict(pass);
5510 }
5511 }
5512
5513 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005514 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005515
5516 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5517 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5518 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5519 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5520 f_shutdown(__BFILE__, __LINE__);
5521 }
5522 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5523 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5524 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5525 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5526 }
5527
5528 f_shutdown(__BFILE__, __LINE__, final := true);
5529}
5530
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005531/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5532testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5533 var PollFnCtx pollctx;
5534 var GprsMS ms;
5535 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5536 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5537 var RlcmacDlBlock dl_block;
5538 var uint32_t sched_fn;
5539 var CtrlMessage rx_ctrl;
5540 var GsmArfcn req_arfcn := 862;
5541 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005542 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005543
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005544 if (use_old_ctrl_iface) {
5545 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5546 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5547 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005548
5549 /* Initialize NS/BSSGP side */
5550 f_init_bssgp();
5551 /* Initialize GPRS MS side */
5552 f_init_gprs_ms();
5553 ms := g_ms[0]; /* We only use first MS in this test */
5554
5555 /* Initialize the PCU interface abstraction */
5556 f_init_raw(testcasename(), info_ind);
5557
5558 /* Make sure we are not affected by full cache from previous tests */
5559 f_pcuvty_flush_neigh_caches();
5560
5561 /* Establish BSSGP connection to the PCU */
5562 f_bssgp_establish();
5563 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5564
5565 /* Send PACKET RESOURCE REQUEST */
5566 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5567 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5568 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5569
5570 /* Start NACC from MS side */
5571 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5572 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5573
5574 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005575 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 +01005576 /* RIM procedure: */
5577 as_outbound_nacc_rim_resolve(info_ind);
5578
5579 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5580 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5581 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5582
5583 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5584 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5585
5586 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5587 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5588 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5589 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5590 f_shutdown(__BFILE__, __LINE__);
5591 }
5592 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5593 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5594 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5595 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5596 }
5597}
5598
5599/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5600testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5601 var PollFnCtx pollctx;
5602 var GprsMS ms;
5603 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5604 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5605 var RlcmacDlBlock dl_block;
5606 var uint32_t sched_fn;
5607 var CtrlMessage rx_ctrl;
5608 var GsmArfcn req_arfcn := 862;
5609 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005610 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005611
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005612 if (use_old_ctrl_iface) {
5613 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5614 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5615 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005616
5617 /* Initialize NS/BSSGP side */
5618 f_init_bssgp();
5619 /* Initialize GPRS MS side */
5620 f_init_gprs_ms();
5621 ms := g_ms[0]; /* We only use first MS in this test */
5622
5623 /* Initialize the PCU interface abstraction */
5624 f_init_raw(testcasename(), info_ind);
5625
5626 /* Make sure we are not affected by full cache from previous tests */
5627 f_pcuvty_flush_neigh_caches();
5628
5629 /* Establish BSSGP connection to the PCU */
5630 f_bssgp_establish();
5631 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5632
5633 /* Send PACKET RESOURCE REQUEST */
5634 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5635 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5636 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5637
5638 /* Start NACC from MS side */
5639 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5640 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5641
5642 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005643 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 +01005644 /* RIM procedure: */
5645 as_outbound_nacc_rim_resolve(info_ind);
5646
5647 /* Announce SI back to MS, continue NACC procedure */
5648 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5649
5650 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5651 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5652
5653 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5654 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5655 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5656 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5657 f_shutdown(__BFILE__, __LINE__);
5658 }
5659 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5660 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5661 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5662 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5663 }
5664}
5665
5666/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
5667testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
5668 var PollFnCtx pollctx;
5669 var GprsMS ms;
5670 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5671 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5672 var RlcmacDlBlock dl_block;
5673 var uint32_t sched_fn;
5674 var CtrlMessage rx_ctrl;
5675 var GsmArfcn req_arfcn := 862;
5676 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005677 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005678
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005679 if (use_old_ctrl_iface) {
5680 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5681 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5682 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005683
5684 /* Initialize NS/BSSGP side */
5685 f_init_bssgp();
5686 /* Initialize GPRS MS side */
5687 f_init_gprs_ms();
5688 ms := g_ms[0]; /* We only use first MS in this test */
5689
5690 /* Initialize the PCU interface abstraction */
5691 f_init_raw(testcasename(), info_ind);
5692
5693 /* Make sure we are not affected by full cache from previous tests */
5694 f_pcuvty_flush_neigh_caches();
5695
5696 /* Establish BSSGP connection to the PCU */
5697 f_bssgp_establish();
5698 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5699
5700 /* Send PACKET RESOURCE REQUEST */
5701 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5702 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5703 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5704
5705 /* Start NACC from MS side */
5706 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5707 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5708
5709 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005710 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 +01005711 /* RIM procedure: */
5712 as_outbound_nacc_rim_resolve(info_ind);
5713
5714 /* Announce SI back to MS, continue NACC procedure */
5715 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5716
5717 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5718 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5719 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5720 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5721 f_shutdown(__BFILE__, __LINE__);
5722 }
5723 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5724 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5725
5726 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5727 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5728 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5729 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5730 }
5731}
5732
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005733/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5734 * while waiting for CTRL resolution */
5735testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
5736 var PollFnCtx pollctx;
5737 var GprsMS ms;
5738 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5739 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5740 var RlcmacDlBlock dl_block;
5741 var uint32_t sched_fn;
5742 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005743 var charstring ctrl_var;
5744 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005745 var GsmArfcn req_arfcn := 862;
5746 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005747 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005748
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005749 if (use_old_ctrl_iface) {
5750 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5751 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5752 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005753
5754 /* Initialize NS/BSSGP side */
5755 f_init_bssgp();
5756 /* Initialize GPRS MS side */
5757 f_init_gprs_ms();
5758 ms := g_ms[0]; /* We only use first MS in this test */
5759
5760 /* Initialize the PCU interface abstraction */
5761 f_init_raw(testcasename(), info_ind);
5762
5763 /* Make sure we are not affected by full cache from previous tests */
5764 f_pcuvty_flush_neigh_caches();
5765
5766 /* Establish BSSGP connection to the PCU */
5767 f_bssgp_establish();
5768 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5769
5770 /* Send PACKET RESOURCE REQUEST */
5771 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5772 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5773 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5774
5775 /* Start NACC from MS side */
5776 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5777 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5778
5779 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005780 if (use_old_ctrl_iface) {
5781 f_ipa_ctrl_wait_link_up();
5782 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5783 int2str(info_ind.lac) & "." &
5784 int2str(info_ind.cell_id) & "." &
5785 int2str(req_arfcn) & "." &
5786 int2str(req_bsic);
5787 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5788 } else {
5789 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5790 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005791 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
5792 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5793 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5794 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005795 if (use_old_ctrl_iface) {
5796 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5797 } else {
5798 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5799 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005800 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005801 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 +01005802
5803 /* And finally everything continues as usual with RIN procedure */
5804 as_outbound_nacc_rim_resolve(info_ind);
5805
5806 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005807 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005808
5809 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5810 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5811 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5812 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5813 f_shutdown(__BFILE__, __LINE__);
5814 }
5815 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5816 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5817 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5818 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5819 }
5820
5821 f_shutdown(__BFILE__, __LINE__, final := true);
5822}
5823
5824/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5825 * while waiting for SI resolution */
5826testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
5827 var PollFnCtx pollctx;
5828 var GprsMS ms;
5829 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5830 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5831 var RlcmacDlBlock dl_block;
5832 var uint32_t sched_fn;
5833 var CtrlMessage rx_ctrl;
5834 var GsmArfcn req_arfcn := 862;
5835 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005836 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005837
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005838 if (use_old_ctrl_iface) {
5839 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5840 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5841 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005842
5843 /* Initialize NS/BSSGP side */
5844 f_init_bssgp();
5845 /* Initialize GPRS MS side */
5846 f_init_gprs_ms();
5847 ms := g_ms[0]; /* We only use first MS in this test */
5848
5849 /* Initialize the PCU interface abstraction */
5850 f_init_raw(testcasename(), info_ind);
5851
5852 /* Make sure we are not affected by full cache from previous tests */
5853 f_pcuvty_flush_neigh_caches();
5854
5855 /* Establish BSSGP connection to the PCU */
5856 f_bssgp_establish();
5857 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5858
5859 /* Send PACKET RESOURCE REQUEST */
5860 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5861 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5862 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5863
5864 /* Start NACC from MS side */
5865 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5866 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5867
5868 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005869 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 +01005870 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5871 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
5872 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5873 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5874 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5875 f_outbound_nacc_rim_tx_resp(info_ind);
5876
5877 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005878 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 +01005879
5880 /* And finally everything continues as usual with RIN procedure */
5881 as_outbound_nacc_rim_resolve(info_ind);
5882
5883 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005884 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005885
5886 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5887 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5888 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5889 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5890 f_shutdown(__BFILE__, __LINE__);
5891 }
5892 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5893 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5894 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5895 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5896 }
5897
5898 f_shutdown(__BFILE__, __LINE__, final := true);
5899}
5900
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005901/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5902 * while sending Pkt Neigh Data Change */
5903testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
5904 var PollFnCtx pollctx;
5905 var GprsMS ms;
5906 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5907 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5908 var RlcmacDlBlock dl_block;
5909 var uint32_t sched_fn;
5910 var CtrlMessage rx_ctrl;
5911 var GsmArfcn req_arfcn := 862;
5912 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005913 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005914
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005915 if (use_old_ctrl_iface) {
5916 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5917 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5918 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005919
5920 /* Initialize NS/BSSGP side */
5921 f_init_bssgp();
5922 /* Initialize GPRS MS side */
5923 f_init_gprs_ms();
5924 ms := g_ms[0]; /* We only use first MS in this test */
5925
5926 /* Initialize the PCU interface abstraction */
5927 f_init_raw(testcasename(), info_ind);
5928
5929 /* Make sure we are not affected by full cache from previous tests */
5930 f_pcuvty_flush_neigh_caches();
5931
5932 /* Establish BSSGP connection to the PCU */
5933 f_bssgp_establish();
5934 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5935
5936 /* Send PACKET RESOURCE REQUEST */
5937 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5938 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5939 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5940
5941 /* Start NACC from MS side */
5942 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5943 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5944
5945 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005946 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 +01005947 /* RIM procedure: */
5948 as_outbound_nacc_rim_resolve(info_ind);
5949
5950 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
5951 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5952 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5953 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5954
5955 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005956 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 +01005957 /* RIM procedure: */
5958 as_outbound_nacc_rim_resolve(info_ind);
5959 /* Transmit SI back to MS */
5960 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5961
5962 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5963 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5964 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5965 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5966 f_shutdown(__BFILE__, __LINE__);
5967 }
5968 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5969 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5970 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5971 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5972 }
5973}
5974
5975/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
5976testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
5977 var PollFnCtx pollctx;
5978 var GprsMS ms;
5979 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5980 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5981 var RlcmacDlBlock dl_block;
5982 var uint32_t sched_fn;
5983 var CtrlMessage rx_ctrl;
5984 var GsmArfcn req_arfcn := 862;
5985 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005986 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005987
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005988 if (use_old_ctrl_iface) {
5989 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5990 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5991 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005992
5993 /* Initialize NS/BSSGP side */
5994 f_init_bssgp();
5995 /* Initialize GPRS MS side */
5996 f_init_gprs_ms();
5997 ms := g_ms[0]; /* We only use first MS in this test */
5998
5999 /* Initialize the PCU interface abstraction */
6000 f_init_raw(testcasename(), info_ind);
6001
6002 /* Make sure we are not affected by full cache from previous tests */
6003 f_pcuvty_flush_neigh_caches();
6004
6005 /* Establish BSSGP connection to the PCU */
6006 f_bssgp_establish();
6007 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6008
6009 /* Send PACKET RESOURCE REQUEST */
6010 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6011 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6012 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6013
6014 /* Start NACC from MS side */
6015 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6016 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6017
6018 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006019 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 +01006020 /* RIM procedure: */
6021 as_outbound_nacc_rim_resolve(info_ind);
6022
6023 /* Announce SI back to MS, continue NACC procedure */
6024 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6025
6026 /* trigger a Pkt Cell Change Notif with different tgt cell */
6027 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6028 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6029
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006030 /* It should trigger RAC_CI resolution to start again: */
6031 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6032
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006033 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6034 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6035
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006036 /* RIM procedure: */
6037 as_outbound_nacc_rim_resolve(info_ind);
6038 /* Transmit SI back to MS */
6039 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6040
6041 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6042 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6043 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6044 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6045 f_shutdown(__BFILE__, __LINE__);
6046 }
6047 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6048 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6049 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6050 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6051 }
6052}
6053
6054/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6055testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6056 var PollFnCtx pollctx;
6057 var GprsMS ms;
6058 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6059 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6060 var RlcmacDlBlock dl_block;
6061 var uint32_t sched_fn;
6062 var CtrlMessage rx_ctrl;
6063 var GsmArfcn req_arfcn := 862;
6064 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006065 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006066
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006067 if (use_old_ctrl_iface) {
6068 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6069 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6070 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006071
6072 /* Initialize NS/BSSGP side */
6073 f_init_bssgp();
6074 /* Initialize GPRS MS side */
6075 f_init_gprs_ms();
6076 ms := g_ms[0]; /* We only use first MS in this test */
6077
6078 /* Initialize the PCU interface abstraction */
6079 f_init_raw(testcasename(), info_ind);
6080
6081 /* Make sure we are not affected by full cache from previous tests */
6082 f_pcuvty_flush_neigh_caches();
6083
6084 /* Establish BSSGP connection to the PCU */
6085 f_bssgp_establish();
6086 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6087
6088 /* Send PACKET RESOURCE REQUEST */
6089 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6090 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6091 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6092
6093 /* Start NACC from MS side */
6094 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6095 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6096
6097 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006098 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 +01006099 /* RIM procedure: */
6100 as_outbound_nacc_rim_resolve(info_ind);
6101
6102 /* Announce SI back to MS, continue NACC procedure */
6103 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6104
6105 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6106 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6107 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6108 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6109 f_shutdown(__BFILE__, __LINE__);
6110 }
6111
6112 /* trigger a Pkt Cell Change Notif with different tgt cell */
6113 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6114 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6115
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006116 /* It should trigger RAC_CI resolution to start again: */
6117 /* When using new PCUIF interface for resolution, we must
6118 * PCUIF.receive() here since that's the first message in the PCUIF
6119 * queue that PCU will have sent. Calling other functions doing
6120 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6121 * due to unexpected message receive. */
6122 if (not use_old_ctrl_iface) {
6123 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6124 }
6125
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006126 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6127 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6128 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6129 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6130 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006131
6132 /* When using CTRL interface, we must schedule the ACK before (see
6133 * above) blocking here waiting for the resoltion, otherwise we'll be
6134 * too late scheduling by the time the resolution is done. */
6135 if (use_old_ctrl_iface) {
6136 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6137 }
6138
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006139 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6140 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6141
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006142 /* RIM procedure: */
6143 as_outbound_nacc_rim_resolve(info_ind);
6144 /* Transmit SI back to MS */
6145 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6146
6147 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6148 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6149 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6150 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6151 f_shutdown(__BFILE__, __LINE__);
6152 }
6153 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6154 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6155 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6156 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6157 }
6158}
6159
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006160/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6161testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6162 var PollFnCtx pollctx;
6163 var GprsMS ms;
6164 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6165 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6166 var RlcmacDlBlock dl_block;
6167 var uint32_t sched_fn, dl_fn;
6168 var CtrlMessage rx_ctrl;
6169 var GsmArfcn req_arfcn := 862;
6170 var uint6_t req_bsic := 43;
6171 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006172 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006173
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006174 if (use_old_ctrl_iface) {
6175 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6176 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6177 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006178
6179 /* Initialize NS/BSSGP side */
6180 f_init_bssgp();
6181 /* Initialize GPRS MS side */
6182 f_init_gprs_ms();
6183 ms := g_ms[0]; /* We only use first MS in this test */
6184
6185 /* Initialize the PCU interface abstraction */
6186 f_init_raw(testcasename(), info_ind);
6187
6188 /* Make sure we are not affected by full cache from previous tests */
6189 f_pcuvty_flush_neigh_caches();
6190
6191 /* Establish BSSGP connection to the PCU */
6192 f_bssgp_establish();
6193 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6194
6195 /* Send PACKET RESOURCE REQUEST */
6196 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6197 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6198 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6199
6200 /* Start NACC from MS side */
6201 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6202 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6203
6204 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006205 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 +01006206 /* RIM procedure: */
6207 as_outbound_nacc_rim_resolve(info_ind);
6208
6209 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6210 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6211 f_sleep(0.1);
6212 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6213 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6214
6215 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6216 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6217 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6218 * Data with unassigned DL TBF in line above): */
6219 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6220 /* Continue receiving Pkt Cell Neighbor Data */
6221 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6222
6223 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6224 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6225 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6226 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6227 f_shutdown(__BFILE__, __LINE__);
6228 }
6229 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6230 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6231 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6232 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6233 }
6234
6235 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6236 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6237 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6238 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6239 f_dl_block_ack_fn(dl_block, dl_fn));
6240}
6241
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006242
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006243function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6244runs on RAW_PCU_Test_CT
6245{
6246 var template (value) RAN_Information_Request_RIM_Container req_cont;
6247 var template (value) PDU_BSSGP bssgp_rim_pdu;
6248 var template PDU_BSSGP bssgp_rim_pdu_expect;
6249 var template RAN_Information_RIM_Container rim_cont_expect;
6250 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006251
6252 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006253 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 +01006254 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006255 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 +01006256 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006257 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);
6258 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006259 f_sleep(1.0);
6260
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006261 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006262
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006263 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6264 ts_RIM_Sequence_Number(1),
6265 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6266 ts_RIM_Protocol_Version_Number(1),
6267 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6268 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006269 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6270 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006271
6272 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6273 tr_RIM_Sequence_Number(1),
6274 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6275 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006276 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 +01006277 omit);
6278
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006279 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6280 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006281 rim_cont_expect);
6282 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006283 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006284 T.start;
6285 alt {
6286 [] RIM.receive(bssgp_rim_pdu_expect) { }
6287 [] RIM.receive {
6288 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6289 }
6290 [] T.timeout {
6291 setverdict(fail, "No BSSGP RIM PDU received");
6292 mtc.stop;
6293 }
6294 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006295}
6296/* Send a RIM RAN info request to the PCU and verify the response, we expect
6297 * getting the system information back which we have transfered to the PCU via
6298 * PCUIF on startup. */
6299testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6300 /* Initialize NS/BSSGP side */
6301 f_init_bssgp();
6302
6303 /* Initialize the PCU interface abstraction */
6304 f_init_raw(testcasename());
6305
6306 /* Establish BSSGP connection to the PCU */
6307 f_bssgp_establish();
6308
6309 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6310 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6311
6312 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6313 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6314
6315 f_shutdown(__BFILE__, __LINE__, final := true);
6316}
6317
6318/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6319 * Routing information, to verify PCU handles that kind of address just fine
6320 */
6321testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6322 /* Initialize NS/BSSGP side */
6323 f_init_bssgp();
6324
6325 /* Initialize the PCU interface abstraction */
6326 f_init_raw(testcasename());
6327
6328 /* Establish BSSGP connection to the PCU */
6329 f_bssgp_establish();
6330
6331 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6332 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6333
6334 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6335 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006336
6337 f_shutdown(__BFILE__, __LINE__, final := true);
6338}
6339
6340/* Same as above, but in this case we simulate the rare case in which the PCU
6341 * has no system information available. We expect getting a response back but
6342 * with no system information inside. */
6343testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006344 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006345 var PCUIF_Message pcu_msg;
6346 timer T := 2.0;
6347
6348 /* Initialize NS/BSSGP side */
6349 f_init_bssgp();
6350
6351 /* Initialize the PCU interface abstraction */
6352 f_init_raw(testcasename(), info_ind);
6353
6354 /* Establish BSSGP connection to the PCU */
6355 f_bssgp_establish();
6356
6357 /* Clear sysinfo from the PCU */
6358 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);
6359 BTS.send(si1_data_ind);
6360 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);
6361 BTS.send(si3_data_ind);
6362 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);
6363 BTS.send(si16_data_ind);
6364 f_sleep(1.0);
6365
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006366 var RIM_Routing_Address dst_addr;
6367 var RIM_Routing_Address src_addr;
6368 var template (value) RAN_Information_Request_RIM_Container req_cont;
6369 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006370 var template PDU_BSSGP bssgp_rim_pdu_expect;
6371 var template RAN_Information_RIM_Container rim_cont_expect;
6372
6373 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 +01006374 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6375 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006376
6377 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6378 ts_RIM_Sequence_Number(1),
6379 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6380 ts_RIM_Protocol_Version_Number(1),
6381 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6382 omit);
6383 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6384 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6385 req_cont);
6386
6387
6388 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6389 tr_RIM_Sequence_Number(1),
6390 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6391 tr_RIM_Protocol_Version_Number(1),
6392 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6393 omit);
6394
6395 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6396 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6397 rim_cont_expect);
6398 RIM.send(bssgp_rim_pdu);
6399 T.start;
6400 alt {
6401 [] RIM.receive(bssgp_rim_pdu_expect) { }
6402 [] RIM.receive {
6403 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6404 }
6405 [] T.timeout {
6406 setverdict(fail, "No BSSGP RIM PDU received");
6407 mtc.stop;
6408 }
6409 }
6410
6411 f_shutdown(__BFILE__, __LINE__, final := true);
6412}
6413
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006414/* 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 +02006415testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6416 var PCUIF_info_ind info_ind;
6417 var template (value) TsTrxBtsNum nr;
6418 var RlcmacDlBlock dl_block;
6419 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006420 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006421 timer T;
6422
6423 /* Initialize NS/BSSGP side */
6424 f_init_bssgp();
6425
6426 info_ind := valueof(ts_PCUIF_INFO_default);
6427 /* The 2 first TRX are enabled. */
6428 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6429 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6430 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6431
6432 /* Initialize the PCU interface abstraction */
6433 f_init_raw(testcasename(), info_ind);
6434
6435 /* Establish BSSGP connection to the PCU */
6436 f_bssgp_establish();
6437
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006438 for (ts := 0; ts < 2; ts := ts + 1) {
6439 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006440
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006441 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6442 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6443 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6444 T.start(0.5);
6445 alt {
6446 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6447 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6448 omit)) -> value data_msg {
6449 setverdict(pass);
6450 T.stop;
6451 }
6452 [] as_rx_fail_dummy(nr);
6453 [] BTS.receive {
6454 setverdict(fail, "Unexpected block from BTS");
6455 f_shutdown(__BFILE__, __LINE__);
6456 }
6457 [] T.timeout {
6458 setverdict(fail, "Expected IDLE block from BTS");
6459 f_shutdown(__BFILE__, __LINE__);
6460 }
6461 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006462 }
6463
6464 f_shutdown(__BFILE__, __LINE__, final := true);
6465}
6466
Oliver Smith3d174882021-09-03 11:38:51 +02006467/* Test stats for available and occupied PDCHs */
6468testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6469 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6470 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6471
6472 /* Initialize NS/BSSGP side */
6473 f_init_bssgp();
6474
Oliver Smithedcded22021-09-14 09:26:55 +02006475 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6476 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6477 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6478 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6479 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6480 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006481
Oliver Smith72d0c692021-09-08 10:03:52 +02006482 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006483 f_init_gprs_ms(4);
6484
6485 /* Initialize the PCU interface abstraction */
6486 f_init_raw(testcasename(), info_ind);
6487
6488 /* Reset stats */
6489 f_statsd_reset();
6490
6491 /* Establish BSSGP */
6492 f_bssgp_establish();
6493
6494 /* 8 PDCHs available, 0 occupied */
6495 var StatsDExpects expect := {
6496 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006497 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6498 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6499 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006500 };
6501 f_statsd_expect(expect);
6502
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006503 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006504 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006505 f_ms_establish_ul_tbf(g_ms[0]);
6506 f_ms_establish_ul_tbf(g_ms[1]);
6507 f_ms_establish_ul_tbf(g_ms[2]);
6508 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 +02006509
6510 /* 4 PDCHs occupied */
6511 expect := {
6512 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006513 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6514 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6515 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006516 };
6517 f_statsd_expect(expect);
6518
6519 f_shutdown(__BFILE__, __LINE__, final := true);
6520}
6521
Oliver Smithf04762d2021-09-14 17:20:38 +02006522/* Test stats for available and occupied PDCHs, for MS which is not known by
6523 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6524 * data arrives from SGSN) */
6525function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6526 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6527 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6528
6529 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6530 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6531 gprsmultislotclass := '00001'B,
6532 gprsextendeddynalloccap := '0'B
6533 };
6534 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6535 egprsmultislotclass := '00001'B,
6536 egprsextendeddynalloccap := '0'B
6537 };
6538 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6539 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6540 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6541 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6542
6543 /* Initialize NS/BSSGP side */
6544 f_init_bssgp();
6545
6546 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6547 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6548 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6549 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6550 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6551 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6552
6553 /* Allocate 1 GprsMS instance */
6554 f_init_gprs_ms(1);
6555
6556 /* Initialize the PCU interface abstraction */
6557 f_init_raw(testcasename(), info_ind);
6558
6559 /* Reset stats */
6560 f_statsd_reset();
6561
6562 /* Establish BSSGP */
6563 f_bssgp_establish();
6564
6565 /* 8 PDCHs available, 0 occupied */
6566 var StatsDExpects expect := {
6567 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6568 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6569 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6570 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6571 };
6572 f_statsd_expect(expect);
6573
6574 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6575 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6576
6577 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6578 var octetstring data := f_rnd_octstring(1400);
6579 if (egprs) {
6580 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6581 } else {
6582 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6583 }
6584 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6585
6586 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6587 f_sleep(X2002);
6588
6589 /* 1 PDCH occupied */
6590 if (egprs) {
6591 expect := {
6592 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6593 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6594 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6595 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6596 };
6597 } else {
6598 expect := {
6599 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6600 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6601 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6602 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6603 };
6604 }
6605 f_statsd_expect(expect);
6606
6607 /* Clean up */
6608 f_shutdown(__BFILE__, __LINE__, final := true);
6609}
6610testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6611 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6612}
6613testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6614 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6615}
6616
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006617/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6618testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
6619 var PCUIF_info_ind info_ind;
6620 var template IARRestOctets rest;
6621 var BIT11 ra11;
6622
6623 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006624
6625 /* Only the first TRX is enabled. */
6626 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
6627 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6628
6629 /* Initialize the PCU interface abstraction */
6630 f_init_raw(testcasename(), info_ind);
6631 f_statsd_reset();
6632
6633 var EGPRSPktChRequest req := {
6634 one_phase := {
6635 tag := '0'B,
6636 multislot_class := '10101'B,
6637 priority := '01'B,
6638 random_bits := '101'B
6639 }
6640 };
6641
6642 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
6643 for (var integer i := 0; i < 7; i := i + 1) {
6644 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
6645 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
6646 }
6647
6648 ra11 := enc_EGPRSPktChRequest2bits(req);
6649 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
6650
6651 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01006652 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006653
6654 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
6655 f_sleep(2.0);
6656 var StatsDExpects expect := {
6657 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
6658 };
6659 f_statsd_expect(expect);
6660
6661 f_shutdown(__BFILE__, __LINE__, final := true);
6662}
6663
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006664control {
6665 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01006666 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006667 execute( TC_ta_ptcch_idle() );
6668 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02006669 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006670 execute( TC_ta_idle_dl_tbf_ass() );
6671 execute( TC_ta_ptcch_ul_multi_tbf() );
6672 execute( TC_cs_lqual_ul_tbf() );
6673 execute( TC_cs_initial_ul() );
6674 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01006675 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01006676 execute( TC_cs_max_dl() );
6677 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01006678 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01006679 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01006680 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01006681 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02006682 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01006683 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02006684 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01006685 execute( TC_x2031_t3191() );
6686 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006687 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01006688 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01006689 execute( TC_t3172_wait_ind_size0() );
6690 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02006691 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02006692 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02006693 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006694 execute( TC_mo_ping_pong() );
6695 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02006696 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006697 execute( TC_mt_ping_pong() );
6698 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006699 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006700 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07006701 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006702 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01006703 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006704 execute( TC_paging_cs_from_bts() );
6705 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
6706 execute( TC_paging_cs_from_sgsn_sign() );
6707 execute( TC_paging_cs_from_sgsn_ptp() );
6708 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
6709 execute( TC_paging_ps_from_sgsn_sign() );
6710 execute( TC_paging_ps_from_sgsn_ptp() );
Oliver Smithe1a77c42021-07-28 13:36:09 +02006711 if (mp_osmo_pcu_newer_than_0_9_0) {
6712 execute( TC_paging_pch_timeout() );
6713 }
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07006714 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
6715 execute( TC_paging_cs_multi_ms_imsi() );
6716 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02006717 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
6718 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01006719 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
6720 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006721
6722 /* EGPRS specific test cases */
6723 execute( TC_egprs_pkt_chan_req_signalling() );
6724 execute( TC_egprs_pkt_chan_req_one_phase() );
6725 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07006726 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07006727 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07006728 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02006729
6730 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07006731
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006732 /* Immediate Assignment on AGCH/PCH */
6733 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
6734 execute( TC_pcuif_fh_imm_ass_ul() );
6735 execute( TC_pcuif_fh_imm_ass_dl() );
6736 /* Packet Uplink/Downlink Assignment on PACCH */
6737 execute( TC_pcuif_fh_pkt_ass_ul() );
6738 execute( TC_pcuif_fh_pkt_ass_dl() );
6739 execute( TC_multitrx_multims_alloc() );
6740 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
6741 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
6742 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02006743 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02006744 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006745
Pau Espin Pedrole1303052020-11-16 11:13:51 +01006746 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07006747
6748 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01006749 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01006750 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006751 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01006752 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01006753 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006754 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006755 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
6756 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006757 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
6758 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
6759 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006760 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
6761 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006762 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
6763 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
6764 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006765 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006766 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
6767 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
6768 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
6769 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006770
6771 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006772 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006773 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006774
6775 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02006776
6777 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02006778 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
6779 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006780 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006781}
6782
Harald Weltea419df22019-03-21 17:23:04 +01006783}