blob: d7ab69bbf9b9a13c8f560d39f323f454be356e64 [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 Pedrol59aa1092021-11-15 18:53:34 +01003403/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3404 * transmitted on ul slot provided by its DL TBF.
3405 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3406function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3407 var GprsMS ms;
3408 var octetstring data := f_rnd_octstring(10);
3409 var RlcmacDlBlock dl_block;
3410 var template RlcmacDlBlock rej_tmpl;
3411 var uint32_t dl_fn;
3412 var uint32_t sched_fn;
3413 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3414
3415 if (use_egprs == true) {
3416 racap_tmpl := bssgp_ms_racap_egprs_def;
3417 } else {
3418 racap_tmpl := bssgp_ms_racap_gprs_def;
3419 }
3420
3421 /* Initialize NS/BSSGP side */
3422 f_init_bssgp();
3423 /* Initialize GPRS MS side */
3424 f_init_gprs_ms();
3425 ms := g_ms[0]; /* We only use first MS in this test */
3426 /* Initialize the PCU interface abstraction */
3427 f_init_raw(testcasename());
3428
3429 /* Establish BSSGP connection to the PCU */
3430 f_bssgp_establish();
3431 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3432
3433 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3434 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3435 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3436
3437 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3438 f_sleep(X2002);
3439 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3440
3441 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3442 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3443 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3444 f_dl_block_ack_fn(dl_block, dl_fn));
3445
3446 /* We should receive a Pkt Ul ASS */
3447 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3448 f_shutdown(__BFILE__, __LINE__, final := true);
3449}
3450testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3451 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3452}
3453testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3454 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3455}
3456
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003457/* Test CS paging over the BTS<->PCU socket.
3458 * 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.
3459 * Paging should be send on the PACCH.
3460 *
3461 * 1. Send a Paging Request over PCU socket.
3462 * 2. Send a Ready-To-Send message over PCU socket
3463 * 3. Expect a Paging Frame
3464 */
3465testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003466 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003467 var MobileIdentityLV mi;
3468 var octetstring mi_enc_lv;
3469 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003470 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003471
3472 /* Initialize NS/BSSGP side */
3473 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003474 /* Initialize GPRS MS side */
3475 f_init_gprs_ms();
3476 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003477
3478 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003479 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003480
3481 /* Establish BSSGP connection to the PCU */
3482 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003483 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003484
3485 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003486 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003487
3488 /* build mobile Identity */
3489 mi := valueof(ts_MI_IMSI_LV(imsi));
3490 mi_enc_lv := enc_MobileIdentityLV(mi);
3491 /* Send paging request */
3492 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3493 sapi :=PCU_IF_SAPI_PDTCH));
3494
3495 /* Receive it on BTS side towards MS */
3496 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3497
3498 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003499 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3500 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3501 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3502 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003503
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003504 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003505}
3506
3507/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3508 */
3509private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3510runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003511 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003512 var hexstring imsi := f_gen_imsi(42);
3513 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003514 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003515
3516 /* Initialize NS/BSSGP side */
3517 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003518 /* Initialize GPRS MS side */
3519 f_init_gprs_ms();
3520 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003521
3522 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003523 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003524
3525 /* Establish BSSGP connection to the PCU */
3526 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003527 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003528
3529 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003530 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003531
3532 /* Send paging request with or without TMSI */
3533 if (use_ptmsi) {
3534 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3535 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3536 } else {
3537 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3538 }
3539
3540 /* Receive it on BTS side towards MS */
3541 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3542
3543 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003544 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003545 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003546 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3547 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3548 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003549 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003550 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3551 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3552 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003553 }
3554
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003555 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003556}
3557
3558testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3559 f_tc_paging_cs_from_sgsn(0, true);
3560}
3561
3562testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3563 f_tc_paging_cs_from_sgsn(0);
3564}
3565
3566testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003567 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003568}
3569
3570/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3571 */
3572private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3573runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003574 var integer imsi_suff_tx := 423;
3575 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003576 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003577
3578 /* Initialize NS/BSSGP side */
3579 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003580 /* Initialize GPRS MS side */
3581 f_init_gprs_ms();
3582 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003583
Oliver Smith61b4e732021-07-22 08:14:29 +02003584 f_statsd_reset();
3585
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003586 /* Establish BSSGP connection to the PCU */
3587 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003588 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003589
3590 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3591 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3592 if (use_ptmsi) {
3593 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3594 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3595 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3596 } else {
3597 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3598 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3599 }
3600
Oliver Smith61b4e732021-07-22 08:14:29 +02003601 if (mp_osmo_pcu_newer_than_0_9_0) {
3602 var StatsDExpects expect := {
Oliver Smith36d95d82021-08-06 22:01:53 +02003603 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3604 /* After the PCU receives the paging request from SGSN,
3605 * and it doesn't have any errors, PCU sends it to the
3606 * BTS to do paging over PCH. */
3607 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
Oliver Smith61b4e732021-07-22 08:14:29 +02003608 };
3609 f_statsd_expect(expect);
3610 }
Oliver Smithfbd39312021-07-27 15:23:39 +02003611}
3612
3613testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3614 /* Initialize the PCU interface abstraction */
3615 f_init_raw(testcasename());
3616
3617 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003618
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003619 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003620}
3621
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003622testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003623 /* Initialize the PCU interface abstraction */
3624 f_init_raw(testcasename());
3625
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003626 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003627
3628 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003629}
3630
3631testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003632 /* Initialize the PCU interface abstraction */
3633 f_init_raw(testcasename());
3634
Harald Welte5339b2e2020-10-04 22:52:56 +02003635 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003636
3637 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003638}
3639
Oliver Smithe1a77c42021-07-28 13:36:09 +02003640testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3641 /* Initialize the PCU interface abstraction */
3642 f_init_raw(testcasename());
3643
3644 /* Set T3113 to 1s to shorten the test duration */
3645 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3646
3647 /* Reset stats and send paging PS request */
3648 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3649
3650 /* Verify that counter increases when T3113 times out (MS did not start
3651 * TBF to respond to paging). */
3652 f_sleep(1.2);
3653 var StatsDExpects expect := {
3654 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3655 };
3656 f_statsd_expect(expect);
3657
3658 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3659 f_shutdown(__BFILE__, __LINE__, final := true);
3660}
3661
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003662/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3663testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3664 var RlcmacDlBlock dl_block;
3665 var octetstring data := f_rnd_octstring(10);
3666 var uint32_t sched_fn;
3667 var uint32_t dl_fn;
3668 var GprsMS ms;
3669
3670 /* Initialize NS/BSSGP side */
3671 f_init_bssgp();
3672 /* Initialize GPRS MS side */
3673 f_init_gprs_ms();
3674 ms := g_ms[0]; /* We only use first MS in this test */
3675
3676 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003677 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003678
Daniel Willmann535aea62020-09-21 13:27:08 +02003679 f_statsd_reset();
3680
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003681 /* Establish BSSGP connection to the PCU */
3682 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003683 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003684
3685 /* Establish an Uplink TBF */
3686 f_ms_establish_ul_tbf(ms);
3687
3688 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003689 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 +02003690 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3691 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3692 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3693
3694 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003695 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003696
3697 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3698 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3699 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3700
3701 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3702 f_sleep(X2002);
3703 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3704
3705 /* ACK the DL block */
3706 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3707 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3708 f_dl_block_ack_fn(dl_block, dl_fn));
3709
Daniel Willmann535aea62020-09-21 13:27:08 +02003710 var StatsDExpects expect := {
3711 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3712 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3713 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3714 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003715 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003716 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003717 };
3718 f_statsd_expect(expect);
3719
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003720 f_shutdown(__BFILE__, __LINE__, final := true);
3721}
3722
3723/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3724testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3725 var RlcmacDlBlock dl_block;
3726 var octetstring data := f_rnd_octstring(10);
3727 var uint32_t sched_fn;
3728 var uint32_t dl_fn;
3729 var GprsMS ms;
3730
3731 /* Initialize NS/BSSGP side */
3732 f_init_bssgp();
3733 /* Initialize GPRS MS side */
3734 f_init_gprs_ms();
3735 ms := g_ms[0]; /* We only use first MS in this test */
3736
3737 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003738 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003739
3740 /* Establish BSSGP connection to the PCU */
3741 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003742 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003743
3744 /* Establish an Uplink TBF */
3745 f_ms_establish_ul_tbf(ms);
3746
3747 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003748 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 +02003749 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3750 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3751 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3752
3753 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003754 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003755
3756 /* Now SGSN sends some DL data with an invalid IMSI */
3757 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3758
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003759 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003760
3761 /* TODO: make sure no data is sent over PCU -> MS */
3762
3763 f_shutdown(__BFILE__, __LINE__, final := true);
3764}
3765
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003766private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3767 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3768 var octetstring data := f_rnd_octstring(6);
3769 var RlcmacDlBlock dl_block;
3770 var GprsMS ms;
3771 var uint32_t fn;
3772
3773 /* Initialize NS/BSSGP side */
3774 f_init_bssgp();
3775 /* Initialize GPRS MS side */
3776 f_init_gprs_ms();
3777 ms := g_ms[0]; /* We only use first MS in this test */
3778
3779 /* Initialize the PCU interface abstraction */
3780 f_init_raw(testcasename());
3781
3782 /* Establish BSSGP connection to the PCU */
3783 f_bssgp_establish();
3784 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3785
3786 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3787 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3788 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3789
3790 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3791 f_sleep(X2002);
3792
3793 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3794 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3795
3796 if (ischosen(dl_block.data_egprs)) {
3797 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3798 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3799 f_shutdown(__BFILE__, __LINE__);
3800 }
3801 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3802 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3803 f_shutdown(__BFILE__, __LINE__);
3804 }
3805 if (not match(dl_block.data_egprs.blocks[1].payload,
3806 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3807 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3808 f_shutdown(__BFILE__, __LINE__);
3809 }
3810 } else if (lengthof(dl_block.data.blocks) > 1) {
3811 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3812 f_shutdown(__BFILE__, __LINE__);
3813 }
3814
3815 f_shutdown(__BFILE__, __LINE__, final := true);
3816}
3817
3818/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3819 * containing llc data. See OS#4849 */
3820testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3821 f_tc_dl_data_no_llc_ui_dummy(omit);
3822}
3823
3824/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3825 * containing llc data. See OS#4849 */
3826testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003827 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003828}
3829
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003830private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003831 template GsmRrMessage t_imm_ass := ?,
3832 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003833runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003834 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003835 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003836
3837 ra11 := enc_EGPRSPktChRequest2uint(req);
3838 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
3839
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07003840 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003841 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003842 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003843 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003844 }
3845
3846 setverdict(pass);
3847}
3848
3849testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
3850 var template GsmRrMessage imm_ass;
3851 var template IaRestOctets rest;
3852 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003853 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003854
3855 /* Initialize the PCU interface abstraction */
3856 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003857 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003858
3859 var EGPRSPktChRequest req := {
3860 /* NOTE: other fields are set in the loop */
3861 signalling := { tag := '110011'B }
3862 };
3863
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003864 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003865 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3866 req.signalling.random_bits := ext_ra;
3867
3868 /* For signalling, do we expect Multiblock UL TBF Assignment? */
3869 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3870 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3871 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3872
3873 f_TC_egprs_pkt_chan_req(req, imm_ass);
3874 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003875
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003876 if (mp_osmo_pcu_newer_than_0_9_0) {
3877 var StatsDExpects expect := {
3878 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3879 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3880 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3881 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3882 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3883 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3884 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3885 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3886 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3887 };
3888 f_statsd_expect(expect);
3889 }
3890
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003891 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003892}
3893
3894testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
3895 var template GsmRrMessage imm_ass;
3896 var template IaRestOctets rest;
3897 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003898 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003899
3900 /* Initialize the PCU interface abstraction */
3901 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003902 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003903
3904 var EGPRSPktChRequest req := {
3905 /* NOTE: other fields are set in the loop */
3906 one_phase := { tag := '0'B }
3907 };
3908
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003909 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003910 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3911 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
3912 var BIT2 priority := substr(ext_ra, 0, 2);
3913 var BIT3 rand := substr(ext_ra, 2, 3);
3914
3915 req.one_phase.multislot_class := mslot_class;
3916 req.one_phase.priority := priority;
3917 req.one_phase.random_bits := rand;
3918
3919 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
3920 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
3921 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3922 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3923
3924 f_TC_egprs_pkt_chan_req(req, imm_ass);
3925 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003926
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003927 if (mp_osmo_pcu_newer_than_0_9_0) {
3928 var StatsDExpects expect := {
3929 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3930 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3931 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
3932 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3933 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3934 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
3935 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3936 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3937 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3938 };
3939 f_statsd_expect(expect);
3940 }
3941
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003942 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003943}
3944
3945testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
3946 var template GsmRrMessage imm_ass;
3947 var template IaRestOctets rest;
3948 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003949 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003950
3951 /* Initialize the PCU interface abstraction */
3952 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003953 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003954
3955 var EGPRSPktChRequest req := {
3956 /* NOTE: other fields are set in the loop */
3957 two_phase := { tag := '110000'B }
3958 };
3959
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003960 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003961 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3962 var BIT2 priority := substr(ext_ra, 0, 2);
3963 var BIT3 rand := substr(ext_ra, 2, 3);
3964
3965 req.two_phase.priority := priority;
3966 req.two_phase.random_bits := rand;
3967
3968 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
3969 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3970 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3971 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3972
3973 f_TC_egprs_pkt_chan_req(req, imm_ass);
3974 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003975
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003976 if (mp_osmo_pcu_newer_than_0_9_0) {
3977 var StatsDExpects expect := {
3978 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3979 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3980 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3981 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3982 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3983 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3984 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3985 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3986 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3987 };
3988 f_statsd_expect(expect);
3989 }
3990
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003991 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003992}
3993
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003994private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
3995 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003996 PCUIF_BurstType bt := BURST_TYPE_1,
3997 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003998runs on RAW_PCU_Test_CT {
3999 var template ReqRefWaitInd tr_ref;
4000 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004001
4002 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4003 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4004 ra := bit2int(ra11), is_11bit := 1,
4005 burst_type := bt, fn := fn,
4006 arfcn := 871));
4007
4008 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004009 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004010
4011 /* Just to have a short-name reference to the actual message */
4012 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4013
4014 /* Make sure that Request Reference list contains at least one entry
4015 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004016 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004017 if (not match(iar.payload, { *, tr_ref, * })) {
4018 setverdict(fail, "Request Reference list does not match");
4019 f_shutdown(__BFILE__, __LINE__);
4020 }
4021
4022 /* Match Feature Indicator (must indicate PS domain) */
4023 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4024 setverdict(fail, "Feature Indicator does not match");
4025 f_shutdown(__BFILE__, __LINE__);
4026 }
4027
4028 /* Match IAR Rest Octets */
4029 if (not match(iar.rest_octets, rest)) {
4030 setverdict(fail, "IAR Rest Octets does not match: ",
4031 iar.rest_octets, " vs expected ", rest);
4032 f_shutdown(__BFILE__, __LINE__);
4033 }
4034
4035 setverdict(pass);
4036}
4037
4038/* Verify the contents of RR Immediate Assignment Reject message and its
4039 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4040testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4041 var template IARRestOctets rest;
4042 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004043 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004044
4045 /* Initialize the PCU interface abstraction */
4046 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004047 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004048
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004049 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004050 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4051 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4052
4053 /* Intentionally incorrect message (see table 11.2.5a.2) */
4054 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4055 }
4056
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004057 if (mp_osmo_pcu_newer_than_0_9_0) {
4058 var StatsDExpects expect := {
4059 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4060 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4061 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4062 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4063 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4064 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4065 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4066 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4067 };
4068 f_statsd_expect(expect);
4069 }
4070
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004071 f_shutdown(__BFILE__, __LINE__, final := true);
4072}
4073
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004074/* At the moment, the IUT does not support any emergency services. Make sure
4075 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4076testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4077 var template IARRestOctets rest;
4078 var BIT5 ext_ra;
4079 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004080 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004081
4082 /* Initialize the PCU interface abstraction */
4083 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004084 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004085
4086 var EGPRSPktChRequest req := {
4087 /* NOTE: other fields are set in the loop */
4088 emergency := { tag := '110111'B }
4089 };
4090
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004091 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004092 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4093 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4094
4095 req.emergency.random_bits := ext_ra;
4096 ra11 := enc_EGPRSPktChRequest2bits(req);
4097
4098 /* Intentionally incorrect message (see table 11.2.5a.2) */
4099 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4100 }
4101
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004102 if (mp_osmo_pcu_newer_than_0_9_0) {
4103 var StatsDExpects expect := {
4104 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4105 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4106 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4107 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4108 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4109 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4110 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4111 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4112 };
4113 f_statsd_expect(expect);
4114 }
4115
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004116 f_shutdown(__BFILE__, __LINE__, final := true);
4117}
4118
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004119/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4120testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004121 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004122 var template IARRestOctets rest;
4123 var BIT11 ra11;
4124
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004125 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004126 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004127
4128 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004129 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4130 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004131
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004132 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004133 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004134 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004135
4136 var EGPRSPktChRequest req := {
4137 one_phase := {
4138 tag := '0'B,
4139 multislot_class := '10101'B,
4140 priority := '01'B,
4141 random_bits := '101'B
4142 }
4143 };
4144
4145 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4146 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4147 for (var integer i := 0; i < 7; i := i + 1) {
4148 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4149 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4150 }
4151
4152 ra11 := enc_EGPRSPktChRequest2bits(req);
4153 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4154
4155 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004156 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004157
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004158 if (mp_osmo_pcu_newer_than_0_9_0) {
4159 var StatsDExpects expect := {
4160 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4161 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4162 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4163 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4164 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4165 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4166 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4167 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4168 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4169 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4170 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4171 };
4172 f_statsd_expect(expect);
4173 }
4174
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004175 f_shutdown(__BFILE__, __LINE__, final := true);
4176}
4177
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004178/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004179private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004180return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004181 /* Pick a random MA length in range 2 .. max_ma_len */
4182 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4183
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004184 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4185 hsn := f_rnd_int(63),
4186 maio := f_rnd_int(63),
4187 ma := f_rnd_bitstring(ma_len));
4188}
4189
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004190private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4191 in GsmRrMessage rr_msg)
4192{
4193 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004194 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004195
4196 var template PacketChannelDescription tr_pkt_chan_desc := {
4197 channel_Type_spare := ?,
4198 tn := ?,
4199 tsc := ts.tsc,
4200 presence := '1'B,
4201 zero := omit,
4202 one := {
4203 maio := ts.maio,
4204 hsn := ts.hsn
4205 }
4206 };
4207
4208 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4209 setverdict(fail, "Packet Channel Description does not match: ",
4210 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4211 }
4212
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004213 /* Mobile Allocation is expected to be octet-aligned */
4214 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4215 var template MobileAllocationLV tr_ma := {
4216 len := ma_oct_len, /* in bytes */
4217 ma := substr(ts.ma, 0, ma_oct_len * 8)
4218 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004219
4220 if (not match(ia.mobile_allocation, tr_ma)) {
4221 setverdict(fail, "Mobile Allocation does not match: ",
4222 ia.mobile_allocation, " vs ", tr_ma);
4223 }
4224
4225 setverdict(pass);
4226}
4227
4228/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4229testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004230 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004231 var GprsMS ms := valueof(t_GprsMS_def);
4232
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004233 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004234 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004235
4236 /* Initialize the PCU interface abstraction */
4237 f_init_raw(testcasename(), info_ind);
4238
4239 /* EGPRS Packet Channel Request (cause=Signalling) */
4240 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4241
4242 /* Establish an Uplink EGPRS TBF */
4243 f_ms_establish_ul_tbf(ms);
4244
4245 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4246 f_shutdown(__BFILE__, __LINE__, final := true);
4247}
4248
4249/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4250testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004251 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004252 var GprsMS ms := valueof(t_GprsMS_def);
4253
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004254 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004255 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004256
4257 /* Initialize the PCU interface abstraction */
4258 f_init_raw(testcasename(), info_ind);
4259
4260 /* Establish an Uplink TBF */
4261 f_ms_establish_ul_tbf(ms);
4262
4263 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4264 f_shutdown(__BFILE__, __LINE__, final := true);
4265}
4266
4267/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4268testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004269 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004270 var GprsMS ms := valueof(t_GprsMS_def);
4271
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004272 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004273 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004274
4275 /* Initialize NS/BSSGP side */
4276 f_init_bssgp();
4277
4278 /* Initialize the PCU interface abstraction */
4279 f_init_raw(testcasename(), info_ind);
4280
4281 /* Establish BSSGP connection to the PCU */
4282 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004283 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004284
4285 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4286 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4287 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4288
4289 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4290 f_shutdown(__BFILE__, __LINE__, final := true);
4291}
4292
4293private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4294 in FrequencyParameters fp)
4295{
4296 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004297 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004298
4299 /* Table 12.8.1: Frequency Parameters information elements */
4300 var template FrequencyParameters tr_fp := {
4301 tsc := ts.tsc,
4302 presence := '10'B, /* Direct encoding 1 */
4303 arfcn := omit,
4304 indirect := omit,
4305 direct1 := {
4306 maio := ts.maio,
4307 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4308 mobile_allocation := {
4309 hsn := ts.hsn,
4310 rfl_number_list_present := '0'B,
4311 rfl_number_list := omit,
4312 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004313 ma_length := ts.ma_bit_len,
4314 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004315 }
4316 },
4317 direct2 := omit
4318 };
4319
4320 if (not match(fp, tr_fp)) {
4321 setverdict(fail, "Frequency Parameters IE does not match: ",
4322 fp, " vs ", tr_fp);
4323 }
4324
4325 setverdict(pass);
4326}
4327
4328/* Make sure that Packet Uplink Assignment contains hopping parameters */
4329testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004330 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004331 var GprsMS ms := valueof(t_GprsMS_def);
4332 var uint32_t poll_fn;
4333
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004334 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004335 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004336
4337 /* Initialize the PCU interface abstraction */
4338 f_init_raw(testcasename(), info_ind);
4339
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004340 /* Single block (two phase) packet access */
4341 var uint16_t ra := bit2int(chan_req_sb);
4342 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4343
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004344 /* Establish an Uplink TBF */
4345 f_ms_establish_ul_tbf(ms);
4346
4347 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004348 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4349 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004350
4351 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004352 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4353 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004354
4355 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4356 var template (omit) FrequencyParameters fp;
4357 if (ua.is_egprs == '1'B) {
4358 fp := ua.egprs.freq_par;
4359 } else {
4360 fp := ua.gprs.freq_par;
4361 }
4362
4363 /* This is an optional IE, so it's worth to check its presence */
4364 if (istemplatekind(fp, "omit")) {
4365 setverdict(fail, "Frequency Parameters IE is not present");
4366 f_shutdown(__BFILE__, __LINE__);
4367 }
4368
4369 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4370 f_shutdown(__BFILE__, __LINE__, final := true);
4371}
4372
4373/* Make sure that Packet Downlink Assignment contains hopping parameters */
4374testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004375 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004376 var octetstring data := f_rnd_octstring(10);
4377 var GprsMS ms := valueof(t_GprsMS_def);
4378 var RlcmacDlBlock dl_block;
4379 var uint32_t poll_fn;
4380
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004381 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004382 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004383
4384 /* Initialize NS/BSSGP side */
4385 f_init_bssgp();
4386
4387 /* Initialize the PCU interface abstraction */
4388 f_init_raw(testcasename(), info_ind);
4389
4390 /* Establish BSSGP connection to the PCU */
4391 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004392 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004393
4394 /* Establish an Uplink TBF */
4395 f_ms_establish_ul_tbf(ms);
4396
4397 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004398 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 +07004399
4400 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4401 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4402 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4403
4404 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4405 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4406
4407 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004408 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4409 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004410
4411 /* This is an optional IE, so it's worth to check its presence */
4412 if (not ispresent(da.freq_par)) {
4413 setverdict(fail, "Frequency Parameters IE is not present");
4414 f_shutdown(__BFILE__, __LINE__);
4415 }
4416
4417 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4418 f_shutdown(__BFILE__, __LINE__, final := true);
4419}
4420
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004421/* Check if the IUT handles subsequent INFO.ind messages */
4422testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004423 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004424 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004425
4426 /* Initialize the PCU interface abstraction */
4427 f_init_raw(testcasename(), info_ind);
4428
4429 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4430 for (var integer i := 0; i < 16; i := i + 1) {
4431 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004432 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004433 }
4434
4435 f_shutdown(__BFILE__, __LINE__, final := true);
4436}
4437
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004438/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4439testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4440 var PCUIF_info_ind info_ind;
4441 var integer i;
4442 const integer num_ms := 8;
4443
4444 /* Initialize NS/BSSGP side */
4445 f_init_bssgp();
4446 /* Initialize GPRS MS side */
4447 f_init_gprs_ms(num_ms);
4448
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004449 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004450 /* Only the 3 first TRX are enabled. The enabled ones all have same
4451 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004452 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4453 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4454 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4455 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004456
4457 /* Initialize the PCU interface abstraction */
4458 f_init_raw(testcasename(), info_ind);
4459
4460 /* Establish BSSGP connection to the PCU */
4461 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004462 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004463
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004464 /* Establish an Uplink TBF for each GprsMS instance */
4465 f_multi_ms_establish_tbf(do_activate := false);
4466
4467 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004468 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004469 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004470 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004471 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004472 f_shutdown(__BFILE__, __LINE__);
4473 }
4474 }
4475
4476 f_shutdown(__BFILE__, __LINE__, final := true);
4477}
4478
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004479/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4480 * downgraded to CS1-4 so that GPRS can read the USF).
4481 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4482 */
4483testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4484 var PCUIF_info_ind info_ind;
4485 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4486 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004487 var uint32_t sched_fn, dl_fn, ack_fn;
4488 var octetstring data := f_rnd_octstring(10);
4489 var RlcmacDlBlock dl_block;
4490 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004491 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004492 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4493 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4494
4495 /* Initialize NS/BSSGP side */
4496 f_init_bssgp();
4497 /* Initialize GPRS MS side */
4498 f_init_gprs_ms(num_ms);
4499
4500 info_ind := valueof(ts_PCUIF_INFO_default);
4501 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004502 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4503 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004504
4505 /* Initialize the PCU interface abstraction */
4506 f_init_raw(testcasename(), info_ind);
4507
4508 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4509 g_mcs_initial_dl := 5;
4510 g_mcs_max_dl := 5;
4511 f_pcuvty_set_allowed_cs_mcs();
4512
4513 /* Establish BSSGP connection to the PCU */
4514 f_bssgp_establish();
4515 f_multi_ms_bssgp_register();
4516
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004517 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004518 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 +01004519 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4520 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4521 f_shutdown(__BFILE__, __LINE__);
4522 }
4523 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4524 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4525
4526 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004527 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 +01004528 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4529 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4530 f_shutdown(__BFILE__, __LINE__);
4531 }
4532 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4533 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4534
4535 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4536 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4537 f_sleep(0.1);
4538 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4539 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4540 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4541 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4542 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4543 /* ACK the DL block */
4544 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4545 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4546 f_dl_block_ack_fn(dl_block, dl_fn));
4547
4548 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4549 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4550 f_sleep(0.1);
4551 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4552 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4553 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4554 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4555 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4556 /* ACK the DL block */
4557 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4558 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4559 f_dl_block_ack_fn(dl_block, dl_fn));
4560
4561 data := f_rnd_octstring(1400);
4562 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4563 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4564
4565 for (var integer i := 0; i < 800; i := i + 1) {
4566 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4567
4568 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
4569 /* No more data to receive, done */
4570 break;
4571 }
4572
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004573 usf_ms := -1;
4574
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004575 if (ischosen(dl_block.ctrl)) {
4576 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4577 f_shutdown(__BFILE__, __LINE__);
4578 } else if (ischosen(dl_block.data_egprs)) {
4579 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4580 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4581 f_shutdown(__BFILE__, __LINE__);
4582 }
4583 tgt_ms := 1;
4584 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4585 if (dl_block.data_egprs.mcs > MCS_4) {
4586 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4587 f_shutdown(__BFILE__, __LINE__);
4588 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004589 usf_ms := 0;
4590 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004591 } else {
4592 if (dl_block.data_egprs.mcs <= MCS_4) {
4593 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4594 f_shutdown(__BFILE__, __LINE__);
4595 }
4596 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004597 usf_ms := 1;
4598 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004599 }
4600 }
4601 } else {
4602 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4603 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4604 f_shutdown(__BFILE__, __LINE__);
4605 }
4606 tgt_ms := 0;
4607 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 +01004608 usf_ms := 0;
4609 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004610 } 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 +01004611 usf_ms := 1;
4612 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004613 }
4614 }
4615
4616 /* Keep Ack/Nack description updated */
4617 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4618
4619 /* TDMA frame number on which we are supposed to send the ACK */
4620 if (f_dl_block_rrbp_valid(dl_block)) {
4621 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4622 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);
4623 if (tx_data_remain != 0) {
4624 /* Submit more data from time to time to keep the TBF ongoing */
4625 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4626 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4627 tx_data_remain := tx_data_remain - 1;
4628 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004629 } else if (tx_data_remain != 0) {
4630 /* keep sending UL blocks when requested by USF to avoid
4631 * UL TBF timeout and hence stop receival of USFs */
4632 if (usf_ms != -1) {
4633 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4634 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004635 }
4636 }
4637
4638 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 +01004639 /* He we check that DL blocks scheduled at GPRS can still request UL
4640 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4641 * condition also ensures the downgrade to <=MCS4 condition is tested
4642 * above */
4643 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4644 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004645 f_shutdown(__BFILE__, __LINE__);
4646 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004647 /* Here check for some level of fairness between them (at least ~40%): */
4648 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4649 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4650 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4651 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4652 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4653 f_shutdown(__BFILE__, __LINE__);
4654 }
4655 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4656 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4657 f_shutdown(__BFILE__, __LINE__);
4658 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004659
4660 f_shutdown(__BFILE__, __LINE__, final := true);
4661}
4662
4663
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004664private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4665 boolean exp_imsi, boolean exp_tmsi)
4666runs on RAW_PCU_Test_CT {
4667 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4668 var integer pending := lengthof(g_ms);
4669 var RlcmacDlBlock dl_block;
4670 var boolean f1, f2;
4671
4672 while (pending > 0) {
4673 var uint32_t poll_fn;
4674
4675 /* Obtain a Downlink block and make sure it is a paging request */
4676 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4677 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4678 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4679 break;
4680 }
4681
4682 /* This should not happen in general, but who knows... */
4683 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4684 if (not ispresent(req.repeated_pageinfo)) {
4685 setverdict(fail, "Repeated Page Info IE is absent?!?");
4686 break;
4687 }
4688
4689 /* A single message may contain several MIs depending on their type */
4690 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4691 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4692 ps_domain := false);
4693 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4694 ps_domain := false);
4695 if (not f1 and not f2)
4696 { continue; }
4697
4698 /* Detect duplicate MIs */
4699 if (mask[i] == '1'B) {
4700 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4701 continue;
4702 }
4703
4704 mask[i] := '1'B;
4705 }
4706
4707 pending := pending - lengthof(req.repeated_pageinfo);
4708 }
4709
4710 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4711 if (mask[i] != '1'B) {
4712 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
4713 log("===== mask := ", mask);
4714 }
4715 }
4716
4717 /* All messages must have been received by now, expect a dummy block */
4718 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
4719}
4720
4721private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
4722runs on RAW_PCU_Test_CT {
4723 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4724 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4725
4726 /* Initialize NS/BSSGP side */
4727 f_init_bssgp();
4728
4729 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004730 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004731
4732 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
4733 f_init_gprs_ms(7 * 8);
4734
4735 /* Initialize the PCU interface abstraction */
4736 f_init_raw(testcasename(), info_ind);
4737
4738 /* Establish BSSGP connection to the PCU */
4739 f_bssgp_establish();
4740 f_multi_ms_bssgp_register();
4741
4742 /* Establish an Uplink TBF for each GprsMS instance */
4743 f_multi_ms_establish_tbf(do_activate := true);
4744}
4745
4746testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
4747 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4748
4749 /* Common part: send INFO.ind, establish TBFs... */
4750 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4751
4752 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
4753 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4754 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
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 := false);
4765 }
4766
4767 f_shutdown(__BFILE__, __LINE__, final := true);
4768}
4769
4770testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
4771 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4772
4773 /* Common part: send INFO.ind, establish TBFs... */
4774 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4775
4776 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
4777 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4778 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4779 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4780 }
4781
4782 /* FIXME: work around a race condition between PCUIF and BSSGP */
4783 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4784
4785 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4786 * The IUT is expected to page on all PDCH slots of all transceivers. */
4787 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4788 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4789 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
4790 }
4791
4792 f_shutdown(__BFILE__, __LINE__, final := true);
4793}
4794
4795testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
4796 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4797
4798 /* Common part: send INFO.ind, establish TBFs... */
4799 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4800
4801 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
4802 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4803 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4804 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
4805 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4806 } else {
4807 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4808 }
4809 }
4810
4811 /* FIXME: work around a race condition between PCUIF and BSSGP */
4812 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4813
4814 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4815 * The IUT is expected to page on all PDCH slots of all transceivers. */
4816 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4817 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4818 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
4819 }
4820
4821 f_shutdown(__BFILE__, __LINE__, final := true);
4822}
4823
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004824private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004825runs on RAW_PCU_Test_CT return RlcmacDlBlock {
4826 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004827 var integer i := 0;
4828 while (true) {
4829 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4830 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
4831 break;
4832 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004833 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004834 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4835 f_shutdown(__BFILE__, __LINE__);
4836 }
4837 i := i + 1;
4838 }
4839 return dl_block;
4840}
4841
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004842private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
4843runs on RAW_PCU_Test_CT {
4844 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),
4845 info_ind.lac),
4846 info_ind.rac),
4847 info_ind.cell_id));
4848 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4849 423),
4850 2),
4851 5));
4852 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4853 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4854 var template (value) RAN_Information_RIM_Container res_cont :=
4855 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
4856 ts_RIM_Sequence_Number(2),
4857 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
4858 ts_RIM_Protocol_Version_Number(1),
4859 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
4860 omit);
4861 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4862 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4863 res_cont));
4864}
4865
4866altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
4867runs on RAW_PCU_Test_CT {
4868 /* RIM procedure: */
4869 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),
4870 info_ind.lac),
4871 info_ind.rac),
4872 info_ind.cell_id));
4873 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4874 423),
4875 2),
4876 5));
4877 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4878 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4879 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4880 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4881 tr_RAN_Information_Request_RIM_Container)) {
4882 if (do_answer) {
4883 f_outbound_nacc_rim_tx_resp(info_ind);
4884 }
4885 if (do_repeat) {
4886 repeat;
4887 }
4888 }
4889}
4890
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004891private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
4892 boolean answer := true, boolean use_old_ctrl_iface := false)
4893runs on RAW_PCU_Test_CT {
4894 if (use_old_ctrl_iface == true) {
4895 f_ipa_ctrl_wait_link_up();
4896 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4897 int2str(info_ind.lac) & "." &
4898 int2str(info_ind.cell_id) & "." &
4899 int2str(req_arfcn) & "." &
4900 int2str(req_bsic);
4901 if (answer) {
4902 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4903 } else {
4904 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
4905 }
4906 } else {
4907 var PCUIF_Message pcu_msg;
4908 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
4909 if (answer) {
4910 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
4911 }
4912 }
4913}
4914
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004915/* Start NACC from MS side */
4916private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004917 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004918 boolean skip_final_ctrl_ack := false,
4919 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004920runs on RAW_PCU_Test_CT {
4921 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4922 var RlcmacDlBlock dl_block;
4923 var uint32_t sched_fn;
4924 var GsmArfcn req_arfcn := 862;
4925 var uint6_t req_bsic := 43;
4926
4927 /* Start NACC from MS side */
4928 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4929 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4930
4931 if (exp_rac_ci_query == true) {
4932 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004933 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 +01004934 }
4935
4936 if (exp_si_query == true) {
4937 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004938 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004939 }
4940
4941 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004942 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004943
4944 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
4945 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4946 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4947 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4948 f_shutdown(__BFILE__, __LINE__);
4949 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004950 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004951 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004952 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4953 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4954 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004955}
4956
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004957/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
4958testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004959 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004960 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004961 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004962 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004963
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004964 if (use_old_ctrl_iface) {
4965 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4966 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4967 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004968
4969 /* Initialize NS/BSSGP side */
4970 f_init_bssgp();
4971 /* Initialize GPRS MS side */
4972 f_init_gprs_ms();
4973 ms := g_ms[0]; /* We only use first MS in this test */
4974
4975 /* Initialize the PCU interface abstraction */
4976 f_init_raw(testcasename(), info_ind);
4977
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004978 /* Make sure we are not affected by full cache from previous tests */
4979 f_pcuvty_flush_neigh_caches();
4980
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004981 /* Establish BSSGP connection to the PCU */
4982 f_bssgp_establish();
4983 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4984
4985 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004986 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 +01004987 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4988 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4989
4990 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004991 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004992
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004993 f_shutdown(__BFILE__, __LINE__, final := true);
4994}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004995
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004996/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
4997testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
4998 var PollFnCtx pollctx;
4999 var GprsMS ms;
5000 var RlcmacDlBlock dl_block;
5001 var uint32_t sched_fn;
5002 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005003 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005004
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005005 if (use_old_ctrl_iface) {
5006 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5007 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5008 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005009
5010 /* Initialize NS/BSSGP side */
5011 f_init_bssgp();
5012 /* Initialize GPRS MS side */
5013 f_init_gprs_ms();
5014 ms := g_ms[0]; /* We only use first MS in this test */
5015
5016 /* Initialize the PCU interface abstraction */
5017 f_init_raw(testcasename(), info_ind);
5018
5019 /* Make sure we are not affected by full cache from previous tests */
5020 f_pcuvty_flush_neigh_caches();
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 Pedrol2abbba92021-02-02 11:52:57 +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, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005032 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 +01005033
5034 /* Wait until we receive something non-dummy */
5035 dl_block := f_skip_dummy(0, sched_fn);
5036 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5037 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5038 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5039 }
5040 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5041 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5042 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5043 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5044 }
5045
5046 f_shutdown(__BFILE__, __LINE__, final := true);
5047}
5048
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005049/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5050testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5051 var PollFnCtx pollctx;
5052 var GprsMS ms;
5053 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005054 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005055 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005056
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005057 if (use_old_ctrl_iface) {
5058 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5059 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5060 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005061
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005062 /* Initialize NS/BSSGP side */
5063 f_init_bssgp();
5064 /* Initialize GPRS MS side */
5065 f_init_gprs_ms();
5066 ms := g_ms[0]; /* We only use first MS in this test */
5067
5068 /* Initialize the PCU interface abstraction */
5069 f_init_raw(testcasename(), info_ind);
5070
5071 /* Make sure we are not affected by full cache from previous tests */
5072 f_pcuvty_flush_neigh_caches();
5073 /* Set timeout values for caches so that entries will be in cache during second try */
5074 f_pcuvty_set_neigh_caches(10, 10);
5075
5076 /* Establish BSSGP connection to the PCU */
5077 f_bssgp_establish();
5078 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5079
5080 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005081 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 +01005082 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5083 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5084
5085 /* Start NACC from MS side */
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 Pedrol43be4252021-01-27 16:40:54 +01005087
5088 /* 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 +02005089 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 +01005090
5091 f_shutdown(__BFILE__, __LINE__, final := true);
5092}
5093
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005094/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5095 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5096 */
5097testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5098 var PollFnCtx pollctx;
5099 var GprsMS ms;
5100 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005101 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005102 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005103
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005104 if (use_old_ctrl_iface) {
5105 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5106 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5107 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005108
5109 /* Initialize NS/BSSGP side */
5110 f_init_bssgp();
5111 /* Initialize GPRS MS side */
5112 f_init_gprs_ms();
5113 ms := g_ms[0]; /* We only use first MS in this test */
5114
5115 /* Initialize the PCU interface abstraction */
5116 f_init_raw(testcasename(), info_ind);
5117
5118 /* Make sure we are not affected by full cache from previous tests */
5119 f_pcuvty_flush_neigh_caches();
5120 /* Set timeout values for caches so that entries will be erased before the second try */
5121 f_pcuvty_set_neigh_caches(1, 1);
5122
5123 /* Establish BSSGP connection to the PCU */
5124 f_bssgp_establish();
5125 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5126
5127 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005128 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 +01005129 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5130 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5131
5132 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005133 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005134
5135 /* CTRL client should have disconnected from us */
5136 f_ipa_ctrl_wait_link_down();
5137 /* wait for cache entries to time out */
5138 f_sleep(2.0);
5139 /* 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 +02005140 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005141
5142 f_shutdown(__BFILE__, __LINE__, final := true);
5143}
5144
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005145/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005146testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5147 var RlcmacDlBlock dl_block;
5148 var PollFnCtx pollctx;
5149 var uint32_t sched_fn;
5150 var GprsMS ms;
5151 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5152 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005153 var GsmArfcn req_arfcn := 862;
5154 var uint6_t req_bsic := 43;
5155
5156 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5157 * resolution CTRL port, to trigger Conn Refused by socket:
5158 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5159 */
5160
5161 /* Initialize NS/BSSGP side */
5162 f_init_bssgp();
5163 /* Initialize GPRS MS side */
5164 f_init_gprs_ms();
5165 ms := g_ms[0]; /* We only use first MS in this test */
5166
5167 /* Initialize the PCU interface abstraction */
5168 f_init_raw(testcasename(), info_ind);
5169
5170 /* Make sure we are not affected by full cache from previous tests */
5171 f_pcuvty_flush_neigh_caches();
5172
5173 /* Establish BSSGP connection to the PCU */
5174 f_bssgp_establish();
5175 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5176
5177 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005178 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 +01005179 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5180 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5181
5182 /* Start NACC from MS side */
5183 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5184 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5185
5186 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005187 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005188 /* Make sure it is a Pkt Cell Chg Continue */
5189 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5190 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5191 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005192 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5193 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5194 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5195 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5196 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005197
5198 f_shutdown(__BFILE__, __LINE__, final := true);
5199}
5200
5201/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005202testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5203 var RlcmacDlBlock dl_block;
5204 var PollFnCtx pollctx;
5205 var uint32_t sched_fn;
5206 var GprsMS ms;
5207 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5208 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005209 var GsmArfcn req_arfcn := 862;
5210 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005211 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005212
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005213 if (use_old_ctrl_iface) {
5214 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5215 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5216 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005217
5218 /* Initialize NS/BSSGP side */
5219 f_init_bssgp();
5220 /* Initialize GPRS MS side */
5221 f_init_gprs_ms();
5222 ms := g_ms[0]; /* We only use first MS in this test */
5223
5224 /* Initialize the PCU interface abstraction */
5225 f_init_raw(testcasename(), info_ind);
5226
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005227 /* Make sure we are not affected by full cache from previous tests */
5228 f_pcuvty_flush_neigh_caches();
5229
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005230 /* Establish BSSGP connection to the PCU */
5231 f_bssgp_establish();
5232 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5233
5234 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005235 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 +01005236 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5237 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5238
5239 /* Start NACC from MS side */
5240 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5241 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5242
5243 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005244 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005245 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 +01005246
5247 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005248 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005249 /* Make sure it is a Pkt Cell Chg Continue */
5250 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5251 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5252 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005253 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5254 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5255 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5256 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5257 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005258
5259 f_shutdown(__BFILE__, __LINE__, final := true);
5260}
5261
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005262/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5263testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5264 var RlcmacDlBlock dl_block;
5265 var PollFnCtx pollctx;
5266 var uint32_t sched_fn;
5267 var GprsMS ms;
5268 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5269 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005270 var GsmArfcn req_arfcn := 862;
5271 var uint6_t req_bsic := 43;
5272
5273 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5274 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5275
5276 /* Initialize NS/BSSGP side */
5277 f_init_bssgp();
5278 /* Initialize GPRS MS side */
5279 f_init_gprs_ms();
5280 ms := g_ms[0]; /* We only use first MS in this test */
5281
5282 /* Initialize the PCU interface abstraction */
5283 f_init_raw(testcasename(), info_ind);
5284
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005285 /* Make sure we are not affected by full cache from previous tests */
5286 f_pcuvty_flush_neigh_caches();
5287
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005288 /* Establish BSSGP connection to the PCU */
5289 f_bssgp_establish();
5290 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5291
5292 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005293 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 +01005294 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5295 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5296
5297 /* Start NACC from MS side */
5298 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5299 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5300
5301 /* osmo-pcu should now ask for resolution: */
5302 f_ipa_ctrl_wait_link_up();
5303 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5304 int2str(info_ind.lac) & "." &
5305 int2str(info_ind.cell_id) & "." &
5306 int2str(req_arfcn) & "." &
5307 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005308 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005309 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5310
5311 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005312 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005313 /* Make sure it is a Pkt Cell Chg Continue */
5314 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5315 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5316 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005317 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5318 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5319 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5320 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5321 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005322
5323 f_shutdown(__BFILE__, __LINE__, final := true);
5324}
5325
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005326/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5327testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5328 var RlcmacDlBlock dl_block;
5329 var PollFnCtx pollctx;
5330 var uint32_t sched_fn;
5331 var GprsMS ms;
5332 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5333 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005334 var GsmArfcn req_arfcn := 862;
5335 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005336 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005337 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 */
5338 info_ind.lac),
5339 info_ind.rac),
5340 info_ind.cell_id));
5341 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5342 423),
5343 2),
5344 5));
5345 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
5346 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
5347
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005348 if (use_old_ctrl_iface) {
5349 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5350 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5351 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005352
5353 /* Initialize NS/BSSGP side */
5354 f_init_bssgp();
5355 /* Initialize GPRS MS side */
5356 f_init_gprs_ms();
5357 ms := g_ms[0]; /* We only use first MS in this test */
5358
5359 /* Initialize the PCU interface abstraction */
5360 f_init_raw(testcasename(), info_ind);
5361
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005362 /* Make sure we are not affected by full cache from previous tests */
5363 f_pcuvty_flush_neigh_caches();
5364
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005365 /* Establish BSSGP connection to the PCU */
5366 f_bssgp_establish();
5367 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5368
5369 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005370 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 +01005371 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5372 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5373
5374 /* Start NACC from MS side */
5375 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5376 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5377
5378 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005379 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 +01005380
5381 /* RIM procedure: */
5382 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5383 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5384 tr_RAN_Information_Request_RIM_Container));
5385 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5386
5387 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005388 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005389 /* Make sure it is a Pkt Cell Chg Continue */
5390 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5391 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5392 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005393 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5394 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5395 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5396 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5397 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005398
5399 f_shutdown(__BFILE__, __LINE__, final := true);
5400}
5401
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005402/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5403testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5404 var PollFnCtx pollctx;
5405 var GprsMS ms;
5406 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5407 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5408 var RlcmacDlBlock dl_block;
5409 var uint32_t sched_fn;
5410 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005411 var charstring ctrl_var;
5412 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005413 var GsmArfcn req_arfcn := 862;
5414 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005415 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005416
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005417 if (use_old_ctrl_iface) {
5418 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5419 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5420 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005421
5422 /* Initialize NS/BSSGP side */
5423 f_init_bssgp();
5424 /* Initialize GPRS MS side */
5425 f_init_gprs_ms();
5426 ms := g_ms[0]; /* We only use first MS in this test */
5427
5428 /* Initialize the PCU interface abstraction */
5429 f_init_raw(testcasename(), info_ind);
5430
5431 /* Make sure we are not affected by full cache from previous tests */
5432 f_pcuvty_flush_neigh_caches();
5433
5434 /* Establish BSSGP connection to the PCU */
5435 f_bssgp_establish();
5436 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5437
5438 /* Send PACKET RESOURCE REQUEST */
5439 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5440 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5441 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5442
5443 /* Start NACC from MS side */
5444 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5445 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5446
5447 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005448 if (use_old_ctrl_iface) {
5449 f_ipa_ctrl_wait_link_up();
5450 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5451 int2str(info_ind.lac) & "." &
5452 int2str(info_ind.cell_id) & "." &
5453 int2str(req_arfcn) & "." &
5454 int2str(req_bsic);
5455 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5456 } else {
5457 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5458 }
5459
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005460 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5461 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5462 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005463
5464 if (use_old_ctrl_iface) {
5465 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5466 } else {
5467 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5468 }
5469
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005470 timer T := 2.0;
5471 T.start;
5472 alt {
5473 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005474 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005475 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5476 f_shutdown(__BFILE__, __LINE__);
5477 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005478 [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 {
5479 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5480 f_shutdown(__BFILE__, __LINE__);
5481 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005482 [] T.timeout {
5483 setverdict(pass);
5484 }
5485 }
5486
5487 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005488 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005489
5490 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5491 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5492 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5493 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5494 f_shutdown(__BFILE__, __LINE__);
5495 }
5496 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5497 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5498 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5499 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5500 }
5501
5502 f_shutdown(__BFILE__, __LINE__, final := true);
5503}
5504
5505/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5506testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5507 var PollFnCtx pollctx;
5508 var GprsMS ms;
5509 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5510 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5511 var RlcmacDlBlock dl_block;
5512 var uint32_t sched_fn;
5513 var CtrlMessage rx_ctrl;
5514 var GsmArfcn req_arfcn := 862;
5515 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005516 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005517
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005518 if (use_old_ctrl_iface) {
5519 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5520 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5521 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005522
5523 /* Initialize NS/BSSGP side */
5524 f_init_bssgp();
5525 /* Initialize GPRS MS side */
5526 f_init_gprs_ms();
5527 ms := g_ms[0]; /* We only use first MS in this test */
5528
5529 /* Initialize the PCU interface abstraction */
5530 f_init_raw(testcasename(), info_ind);
5531
5532 /* Make sure we are not affected by full cache from previous tests */
5533 f_pcuvty_flush_neigh_caches();
5534
5535 /* Establish BSSGP connection to the PCU */
5536 f_bssgp_establish();
5537 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5538
5539 /* Send PACKET RESOURCE REQUEST */
5540 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5541 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5542 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5543
5544 /* Start NACC from MS side */
5545 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5546 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5547
5548 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005549 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 +01005550 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5551 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5552 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5553 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5554 f_outbound_nacc_rim_tx_resp(info_ind);
5555 timer T := 1.0;
5556 T.start;
5557 alt {
5558 [] RIM.receive {
5559 setverdict(fail, "Received unexpected RIM message");
5560 f_shutdown(__BFILE__, __LINE__);
5561 }
5562 [] T.timeout {
5563 setverdict(pass);
5564 }
5565 }
5566
5567 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005568 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005569
5570 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5571 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5572 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5573 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5574 f_shutdown(__BFILE__, __LINE__);
5575 }
5576 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5577 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5578 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5579 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5580 }
5581
5582 f_shutdown(__BFILE__, __LINE__, final := true);
5583}
5584
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005585/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5586testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5587 var PollFnCtx pollctx;
5588 var GprsMS ms;
5589 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5590 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5591 var RlcmacDlBlock dl_block;
5592 var uint32_t sched_fn;
5593 var CtrlMessage rx_ctrl;
5594 var GsmArfcn req_arfcn := 862;
5595 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005596 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005597
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005598 if (use_old_ctrl_iface) {
5599 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5600 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5601 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005602
5603 /* Initialize NS/BSSGP side */
5604 f_init_bssgp();
5605 /* Initialize GPRS MS side */
5606 f_init_gprs_ms();
5607 ms := g_ms[0]; /* We only use first MS in this test */
5608
5609 /* Initialize the PCU interface abstraction */
5610 f_init_raw(testcasename(), info_ind);
5611
5612 /* Make sure we are not affected by full cache from previous tests */
5613 f_pcuvty_flush_neigh_caches();
5614
5615 /* Establish BSSGP connection to the PCU */
5616 f_bssgp_establish();
5617 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5618
5619 /* Send PACKET RESOURCE REQUEST */
5620 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5621 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5622 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5623
5624 /* Start NACC from MS side */
5625 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5626 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5627
5628 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005629 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 +01005630 /* RIM procedure: */
5631 as_outbound_nacc_rim_resolve(info_ind);
5632
5633 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5634 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5635 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5636
5637 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5638 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5639
5640 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5641 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5642 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5643 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5644 f_shutdown(__BFILE__, __LINE__);
5645 }
5646 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5647 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5648 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5649 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5650 }
5651}
5652
5653/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5654testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5655 var PollFnCtx pollctx;
5656 var GprsMS ms;
5657 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5658 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5659 var RlcmacDlBlock dl_block;
5660 var uint32_t sched_fn;
5661 var CtrlMessage rx_ctrl;
5662 var GsmArfcn req_arfcn := 862;
5663 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005664 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005665
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005666 if (use_old_ctrl_iface) {
5667 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5668 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5669 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005670
5671 /* Initialize NS/BSSGP side */
5672 f_init_bssgp();
5673 /* Initialize GPRS MS side */
5674 f_init_gprs_ms();
5675 ms := g_ms[0]; /* We only use first MS in this test */
5676
5677 /* Initialize the PCU interface abstraction */
5678 f_init_raw(testcasename(), info_ind);
5679
5680 /* Make sure we are not affected by full cache from previous tests */
5681 f_pcuvty_flush_neigh_caches();
5682
5683 /* Establish BSSGP connection to the PCU */
5684 f_bssgp_establish();
5685 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5686
5687 /* Send PACKET RESOURCE REQUEST */
5688 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5689 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5690 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5691
5692 /* Start NACC from MS side */
5693 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5694 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5695
5696 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005697 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 +01005698 /* RIM procedure: */
5699 as_outbound_nacc_rim_resolve(info_ind);
5700
5701 /* Announce SI back to MS, continue NACC procedure */
5702 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5703
5704 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5705 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5706
5707 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5708 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5709 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5710 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5711 f_shutdown(__BFILE__, __LINE__);
5712 }
5713 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5714 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5715 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5716 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5717 }
5718}
5719
5720/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
5721testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
5722 var PollFnCtx pollctx;
5723 var GprsMS ms;
5724 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5725 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5726 var RlcmacDlBlock dl_block;
5727 var uint32_t sched_fn;
5728 var CtrlMessage rx_ctrl;
5729 var GsmArfcn req_arfcn := 862;
5730 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005731 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005732
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005733 if (use_old_ctrl_iface) {
5734 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5735 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5736 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005737
5738 /* Initialize NS/BSSGP side */
5739 f_init_bssgp();
5740 /* Initialize GPRS MS side */
5741 f_init_gprs_ms();
5742 ms := g_ms[0]; /* We only use first MS in this test */
5743
5744 /* Initialize the PCU interface abstraction */
5745 f_init_raw(testcasename(), info_ind);
5746
5747 /* Make sure we are not affected by full cache from previous tests */
5748 f_pcuvty_flush_neigh_caches();
5749
5750 /* Establish BSSGP connection to the PCU */
5751 f_bssgp_establish();
5752 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5753
5754 /* Send PACKET RESOURCE REQUEST */
5755 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5756 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5757 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5758
5759 /* Start NACC from MS side */
5760 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5761 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5762
5763 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005764 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 +01005765 /* RIM procedure: */
5766 as_outbound_nacc_rim_resolve(info_ind);
5767
5768 /* Announce SI back to MS, continue NACC procedure */
5769 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5770
5771 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5772 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5773 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5774 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5775 f_shutdown(__BFILE__, __LINE__);
5776 }
5777 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5778 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5779
5780 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5781 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5782 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5783 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5784 }
5785}
5786
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005787/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5788 * while waiting for CTRL resolution */
5789testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
5790 var PollFnCtx pollctx;
5791 var GprsMS ms;
5792 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5793 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5794 var RlcmacDlBlock dl_block;
5795 var uint32_t sched_fn;
5796 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005797 var charstring ctrl_var;
5798 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005799 var GsmArfcn req_arfcn := 862;
5800 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005801 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005802
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005803 if (use_old_ctrl_iface) {
5804 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5805 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5806 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005807
5808 /* Initialize NS/BSSGP side */
5809 f_init_bssgp();
5810 /* Initialize GPRS MS side */
5811 f_init_gprs_ms();
5812 ms := g_ms[0]; /* We only use first MS in this test */
5813
5814 /* Initialize the PCU interface abstraction */
5815 f_init_raw(testcasename(), info_ind);
5816
5817 /* Make sure we are not affected by full cache from previous tests */
5818 f_pcuvty_flush_neigh_caches();
5819
5820 /* Establish BSSGP connection to the PCU */
5821 f_bssgp_establish();
5822 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5823
5824 /* Send PACKET RESOURCE REQUEST */
5825 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5826 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5827 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5828
5829 /* Start NACC from MS side */
5830 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5831 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5832
5833 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005834 if (use_old_ctrl_iface) {
5835 f_ipa_ctrl_wait_link_up();
5836 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5837 int2str(info_ind.lac) & "." &
5838 int2str(info_ind.cell_id) & "." &
5839 int2str(req_arfcn) & "." &
5840 int2str(req_bsic);
5841 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5842 } else {
5843 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5844 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005845 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
5846 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5847 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5848 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005849 if (use_old_ctrl_iface) {
5850 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5851 } else {
5852 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5853 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005854 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005855 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 +01005856
5857 /* And finally everything continues as usual with RIN procedure */
5858 as_outbound_nacc_rim_resolve(info_ind);
5859
5860 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005861 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005862
5863 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5864 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5865 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5866 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5867 f_shutdown(__BFILE__, __LINE__);
5868 }
5869 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5870 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5871 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5872 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5873 }
5874
5875 f_shutdown(__BFILE__, __LINE__, final := true);
5876}
5877
5878/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5879 * while waiting for SI resolution */
5880testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
5881 var PollFnCtx pollctx;
5882 var GprsMS ms;
5883 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5884 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5885 var RlcmacDlBlock dl_block;
5886 var uint32_t sched_fn;
5887 var CtrlMessage rx_ctrl;
5888 var GsmArfcn req_arfcn := 862;
5889 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005890 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005891
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005892 if (use_old_ctrl_iface) {
5893 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5894 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5895 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005896
5897 /* Initialize NS/BSSGP side */
5898 f_init_bssgp();
5899 /* Initialize GPRS MS side */
5900 f_init_gprs_ms();
5901 ms := g_ms[0]; /* We only use first MS in this test */
5902
5903 /* Initialize the PCU interface abstraction */
5904 f_init_raw(testcasename(), info_ind);
5905
5906 /* Make sure we are not affected by full cache from previous tests */
5907 f_pcuvty_flush_neigh_caches();
5908
5909 /* Establish BSSGP connection to the PCU */
5910 f_bssgp_establish();
5911 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5912
5913 /* Send PACKET RESOURCE REQUEST */
5914 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5915 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5916 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5917
5918 /* Start NACC from MS side */
5919 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5920 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5921
5922 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005923 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 +01005924 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5925 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
5926 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5927 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5928 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5929 f_outbound_nacc_rim_tx_resp(info_ind);
5930
5931 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005932 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 +01005933
5934 /* And finally everything continues as usual with RIN procedure */
5935 as_outbound_nacc_rim_resolve(info_ind);
5936
5937 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005938 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005939
5940 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5941 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5942 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5943 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5944 f_shutdown(__BFILE__, __LINE__);
5945 }
5946 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5947 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5948 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5949 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5950 }
5951
5952 f_shutdown(__BFILE__, __LINE__, final := true);
5953}
5954
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005955/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5956 * while sending Pkt Neigh Data Change */
5957testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
5958 var PollFnCtx pollctx;
5959 var GprsMS ms;
5960 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5961 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5962 var RlcmacDlBlock dl_block;
5963 var uint32_t sched_fn;
5964 var CtrlMessage rx_ctrl;
5965 var GsmArfcn req_arfcn := 862;
5966 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005967 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005968
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005969 if (use_old_ctrl_iface) {
5970 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5971 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5972 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005973
5974 /* Initialize NS/BSSGP side */
5975 f_init_bssgp();
5976 /* Initialize GPRS MS side */
5977 f_init_gprs_ms();
5978 ms := g_ms[0]; /* We only use first MS in this test */
5979
5980 /* Initialize the PCU interface abstraction */
5981 f_init_raw(testcasename(), info_ind);
5982
5983 /* Make sure we are not affected by full cache from previous tests */
5984 f_pcuvty_flush_neigh_caches();
5985
5986 /* Establish BSSGP connection to the PCU */
5987 f_bssgp_establish();
5988 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5989
5990 /* Send PACKET RESOURCE REQUEST */
5991 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5992 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5993 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5994
5995 /* Start NACC from MS side */
5996 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5997 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5998
5999 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006000 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 +01006001 /* RIM procedure: */
6002 as_outbound_nacc_rim_resolve(info_ind);
6003
6004 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6005 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6006 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6007 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6008
6009 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006010 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 +01006011 /* RIM procedure: */
6012 as_outbound_nacc_rim_resolve(info_ind);
6013 /* Transmit SI back to MS */
6014 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6015
6016 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6017 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6018 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6019 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6020 f_shutdown(__BFILE__, __LINE__);
6021 }
6022 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6023 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6024 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6025 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6026 }
6027}
6028
6029/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6030testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6031 var PollFnCtx pollctx;
6032 var GprsMS ms;
6033 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6034 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6035 var RlcmacDlBlock dl_block;
6036 var uint32_t sched_fn;
6037 var CtrlMessage rx_ctrl;
6038 var GsmArfcn req_arfcn := 862;
6039 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006040 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006041
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006042 if (use_old_ctrl_iface) {
6043 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6044 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6045 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006046
6047 /* Initialize NS/BSSGP side */
6048 f_init_bssgp();
6049 /* Initialize GPRS MS side */
6050 f_init_gprs_ms();
6051 ms := g_ms[0]; /* We only use first MS in this test */
6052
6053 /* Initialize the PCU interface abstraction */
6054 f_init_raw(testcasename(), info_ind);
6055
6056 /* Make sure we are not affected by full cache from previous tests */
6057 f_pcuvty_flush_neigh_caches();
6058
6059 /* Establish BSSGP connection to the PCU */
6060 f_bssgp_establish();
6061 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6062
6063 /* Send PACKET RESOURCE REQUEST */
6064 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6065 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6066 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6067
6068 /* Start NACC from MS side */
6069 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6070 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6071
6072 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006073 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 +01006074 /* RIM procedure: */
6075 as_outbound_nacc_rim_resolve(info_ind);
6076
6077 /* Announce SI back to MS, continue NACC procedure */
6078 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6079
6080 /* trigger a Pkt Cell Change Notif with different tgt cell */
6081 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6082 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6083
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006084 /* It should trigger RAC_CI resolution to start again: */
6085 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6086
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006087 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6088 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6089
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006090 /* RIM procedure: */
6091 as_outbound_nacc_rim_resolve(info_ind);
6092 /* Transmit SI back to MS */
6093 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6094
6095 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6096 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6097 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6098 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6099 f_shutdown(__BFILE__, __LINE__);
6100 }
6101 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6102 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6103 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6104 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6105 }
6106}
6107
6108/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6109testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6110 var PollFnCtx pollctx;
6111 var GprsMS ms;
6112 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6113 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6114 var RlcmacDlBlock dl_block;
6115 var uint32_t sched_fn;
6116 var CtrlMessage rx_ctrl;
6117 var GsmArfcn req_arfcn := 862;
6118 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006119 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006120
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006121 if (use_old_ctrl_iface) {
6122 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6123 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6124 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006125
6126 /* Initialize NS/BSSGP side */
6127 f_init_bssgp();
6128 /* Initialize GPRS MS side */
6129 f_init_gprs_ms();
6130 ms := g_ms[0]; /* We only use first MS in this test */
6131
6132 /* Initialize the PCU interface abstraction */
6133 f_init_raw(testcasename(), info_ind);
6134
6135 /* Make sure we are not affected by full cache from previous tests */
6136 f_pcuvty_flush_neigh_caches();
6137
6138 /* Establish BSSGP connection to the PCU */
6139 f_bssgp_establish();
6140 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6141
6142 /* Send PACKET RESOURCE REQUEST */
6143 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6144 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6145 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6146
6147 /* Start NACC from MS side */
6148 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6149 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6150
6151 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006152 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 +01006153 /* RIM procedure: */
6154 as_outbound_nacc_rim_resolve(info_ind);
6155
6156 /* Announce SI back to MS, continue NACC procedure */
6157 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6158
6159 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6160 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6161 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6162 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6163 f_shutdown(__BFILE__, __LINE__);
6164 }
6165
6166 /* trigger a Pkt Cell Change Notif with different tgt cell */
6167 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6168 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6169
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006170 /* It should trigger RAC_CI resolution to start again: */
6171 /* When using new PCUIF interface for resolution, we must
6172 * PCUIF.receive() here since that's the first message in the PCUIF
6173 * queue that PCU will have sent. Calling other functions doing
6174 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6175 * due to unexpected message receive. */
6176 if (not use_old_ctrl_iface) {
6177 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6178 }
6179
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006180 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6181 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6182 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6183 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6184 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006185
6186 /* When using CTRL interface, we must schedule the ACK before (see
6187 * above) blocking here waiting for the resoltion, otherwise we'll be
6188 * too late scheduling by the time the resolution is done. */
6189 if (use_old_ctrl_iface) {
6190 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6191 }
6192
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006193 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6194 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6195
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006196 /* RIM procedure: */
6197 as_outbound_nacc_rim_resolve(info_ind);
6198 /* Transmit SI back to MS */
6199 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6200
6201 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6202 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6203 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6204 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6205 f_shutdown(__BFILE__, __LINE__);
6206 }
6207 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6208 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6209 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6210 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6211 }
6212}
6213
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006214/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6215testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6216 var PollFnCtx pollctx;
6217 var GprsMS ms;
6218 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6219 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6220 var RlcmacDlBlock dl_block;
6221 var uint32_t sched_fn, dl_fn;
6222 var CtrlMessage rx_ctrl;
6223 var GsmArfcn req_arfcn := 862;
6224 var uint6_t req_bsic := 43;
6225 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006226 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006227
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006228 if (use_old_ctrl_iface) {
6229 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6230 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6231 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006232
6233 /* Initialize NS/BSSGP side */
6234 f_init_bssgp();
6235 /* Initialize GPRS MS side */
6236 f_init_gprs_ms();
6237 ms := g_ms[0]; /* We only use first MS in this test */
6238
6239 /* Initialize the PCU interface abstraction */
6240 f_init_raw(testcasename(), info_ind);
6241
6242 /* Make sure we are not affected by full cache from previous tests */
6243 f_pcuvty_flush_neigh_caches();
6244
6245 /* Establish BSSGP connection to the PCU */
6246 f_bssgp_establish();
6247 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6248
6249 /* Send PACKET RESOURCE REQUEST */
6250 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6251 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6252 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6253
6254 /* Start NACC from MS side */
6255 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6256 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6257
6258 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006259 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 +01006260 /* RIM procedure: */
6261 as_outbound_nacc_rim_resolve(info_ind);
6262
6263 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6264 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6265 f_sleep(0.1);
6266 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6267 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6268
6269 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6270 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6271 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6272 * Data with unassigned DL TBF in line above): */
6273 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6274 /* Continue receiving Pkt Cell Neighbor Data */
6275 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6276
6277 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6278 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6279 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6280 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6281 f_shutdown(__BFILE__, __LINE__);
6282 }
6283 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6284 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6285 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6286 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6287 }
6288
6289 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6290 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6291 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6292 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6293 f_dl_block_ack_fn(dl_block, dl_fn));
6294}
6295
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006296
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006297function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6298runs on RAW_PCU_Test_CT
6299{
6300 var template (value) RAN_Information_Request_RIM_Container req_cont;
6301 var template (value) PDU_BSSGP bssgp_rim_pdu;
6302 var template PDU_BSSGP bssgp_rim_pdu_expect;
6303 var template RAN_Information_RIM_Container rim_cont_expect;
6304 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006305
6306 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006307 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 +01006308 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006309 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 +01006310 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006311 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);
6312 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006313 f_sleep(1.0);
6314
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006315 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006316
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006317 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6318 ts_RIM_Sequence_Number(1),
6319 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6320 ts_RIM_Protocol_Version_Number(1),
6321 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6322 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006323 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6324 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006325
6326 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6327 tr_RIM_Sequence_Number(1),
6328 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6329 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006330 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 +01006331 omit);
6332
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006333 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6334 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006335 rim_cont_expect);
6336 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006337 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006338 T.start;
6339 alt {
6340 [] RIM.receive(bssgp_rim_pdu_expect) { }
6341 [] RIM.receive {
6342 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6343 }
6344 [] T.timeout {
6345 setverdict(fail, "No BSSGP RIM PDU received");
6346 mtc.stop;
6347 }
6348 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006349}
6350/* Send a RIM RAN info request to the PCU and verify the response, we expect
6351 * getting the system information back which we have transfered to the PCU via
6352 * PCUIF on startup. */
6353testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6354 /* Initialize NS/BSSGP side */
6355 f_init_bssgp();
6356
6357 /* Initialize the PCU interface abstraction */
6358 f_init_raw(testcasename());
6359
6360 /* Establish BSSGP connection to the PCU */
6361 f_bssgp_establish();
6362
6363 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6364 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6365
6366 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6367 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6368
6369 f_shutdown(__BFILE__, __LINE__, final := true);
6370}
6371
6372/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6373 * Routing information, to verify PCU handles that kind of address just fine
6374 */
6375testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6376 /* Initialize NS/BSSGP side */
6377 f_init_bssgp();
6378
6379 /* Initialize the PCU interface abstraction */
6380 f_init_raw(testcasename());
6381
6382 /* Establish BSSGP connection to the PCU */
6383 f_bssgp_establish();
6384
6385 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6386 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6387
6388 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6389 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006390
6391 f_shutdown(__BFILE__, __LINE__, final := true);
6392}
6393
6394/* Same as above, but in this case we simulate the rare case in which the PCU
6395 * has no system information available. We expect getting a response back but
6396 * with no system information inside. */
6397testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006398 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006399 var PCUIF_Message pcu_msg;
6400 timer T := 2.0;
6401
6402 /* Initialize NS/BSSGP side */
6403 f_init_bssgp();
6404
6405 /* Initialize the PCU interface abstraction */
6406 f_init_raw(testcasename(), info_ind);
6407
6408 /* Establish BSSGP connection to the PCU */
6409 f_bssgp_establish();
6410
6411 /* Clear sysinfo from the PCU */
6412 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);
6413 BTS.send(si1_data_ind);
6414 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);
6415 BTS.send(si3_data_ind);
6416 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);
6417 BTS.send(si16_data_ind);
6418 f_sleep(1.0);
6419
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006420 var RIM_Routing_Address dst_addr;
6421 var RIM_Routing_Address src_addr;
6422 var template (value) RAN_Information_Request_RIM_Container req_cont;
6423 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006424 var template PDU_BSSGP bssgp_rim_pdu_expect;
6425 var template RAN_Information_RIM_Container rim_cont_expect;
6426
6427 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 +01006428 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6429 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006430
6431 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6432 ts_RIM_Sequence_Number(1),
6433 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6434 ts_RIM_Protocol_Version_Number(1),
6435 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6436 omit);
6437 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6438 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6439 req_cont);
6440
6441
6442 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6443 tr_RIM_Sequence_Number(1),
6444 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6445 tr_RIM_Protocol_Version_Number(1),
6446 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6447 omit);
6448
6449 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6450 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6451 rim_cont_expect);
6452 RIM.send(bssgp_rim_pdu);
6453 T.start;
6454 alt {
6455 [] RIM.receive(bssgp_rim_pdu_expect) { }
6456 [] RIM.receive {
6457 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6458 }
6459 [] T.timeout {
6460 setverdict(fail, "No BSSGP RIM PDU received");
6461 mtc.stop;
6462 }
6463 }
6464
6465 f_shutdown(__BFILE__, __LINE__, final := true);
6466}
6467
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006468/* 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 +02006469testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6470 var PCUIF_info_ind info_ind;
6471 var template (value) TsTrxBtsNum nr;
6472 var RlcmacDlBlock dl_block;
6473 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006474 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006475 timer T;
6476
6477 /* Initialize NS/BSSGP side */
6478 f_init_bssgp();
6479
6480 info_ind := valueof(ts_PCUIF_INFO_default);
6481 /* The 2 first TRX are enabled. */
6482 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6483 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6484 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6485
6486 /* Initialize the PCU interface abstraction */
6487 f_init_raw(testcasename(), info_ind);
6488
6489 /* Establish BSSGP connection to the PCU */
6490 f_bssgp_establish();
6491
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006492 for (ts := 0; ts < 2; ts := ts + 1) {
6493 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006494
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006495 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6496 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6497 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6498 T.start(0.5);
6499 alt {
6500 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6501 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6502 omit)) -> value data_msg {
6503 setverdict(pass);
6504 T.stop;
6505 }
6506 [] as_rx_fail_dummy(nr);
6507 [] BTS.receive {
6508 setverdict(fail, "Unexpected block from BTS");
6509 f_shutdown(__BFILE__, __LINE__);
6510 }
6511 [] T.timeout {
6512 setverdict(fail, "Expected IDLE block from BTS");
6513 f_shutdown(__BFILE__, __LINE__);
6514 }
6515 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006516 }
6517
6518 f_shutdown(__BFILE__, __LINE__, final := true);
6519}
6520
Oliver Smith3d174882021-09-03 11:38:51 +02006521/* Test stats for available and occupied PDCHs */
6522testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6523 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6524 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6525
6526 /* Initialize NS/BSSGP side */
6527 f_init_bssgp();
6528
Oliver Smithedcded22021-09-14 09:26:55 +02006529 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6530 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6531 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6532 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6533 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6534 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006535
Oliver Smith72d0c692021-09-08 10:03:52 +02006536 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006537 f_init_gprs_ms(4);
6538
6539 /* Initialize the PCU interface abstraction */
6540 f_init_raw(testcasename(), info_ind);
6541
6542 /* Reset stats */
6543 f_statsd_reset();
6544
6545 /* Establish BSSGP */
6546 f_bssgp_establish();
6547
6548 /* 8 PDCHs available, 0 occupied */
6549 var StatsDExpects expect := {
6550 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006551 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6552 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6553 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006554 };
6555 f_statsd_expect(expect);
6556
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006557 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006558 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006559 f_ms_establish_ul_tbf(g_ms[0]);
6560 f_ms_establish_ul_tbf(g_ms[1]);
6561 f_ms_establish_ul_tbf(g_ms[2]);
6562 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 +02006563
6564 /* 4 PDCHs occupied */
6565 expect := {
6566 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006567 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6568 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6569 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006570 };
6571 f_statsd_expect(expect);
6572
6573 f_shutdown(__BFILE__, __LINE__, final := true);
6574}
6575
Oliver Smithf04762d2021-09-14 17:20:38 +02006576/* Test stats for available and occupied PDCHs, for MS which is not known by
6577 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6578 * data arrives from SGSN) */
6579function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6580 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6581 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6582
6583 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6584 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6585 gprsmultislotclass := '00001'B,
6586 gprsextendeddynalloccap := '0'B
6587 };
6588 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6589 egprsmultislotclass := '00001'B,
6590 egprsextendeddynalloccap := '0'B
6591 };
6592 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6593 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6594 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6595 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6596
6597 /* Initialize NS/BSSGP side */
6598 f_init_bssgp();
6599
6600 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6601 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6602 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6603 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6604 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6605 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6606
6607 /* Allocate 1 GprsMS instance */
6608 f_init_gprs_ms(1);
6609
6610 /* Initialize the PCU interface abstraction */
6611 f_init_raw(testcasename(), info_ind);
6612
6613 /* Reset stats */
6614 f_statsd_reset();
6615
6616 /* Establish BSSGP */
6617 f_bssgp_establish();
6618
6619 /* 8 PDCHs available, 0 occupied */
6620 var StatsDExpects expect := {
6621 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6622 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6623 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6624 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6625 };
6626 f_statsd_expect(expect);
6627
6628 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6629 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6630
6631 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6632 var octetstring data := f_rnd_octstring(1400);
6633 if (egprs) {
6634 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6635 } else {
6636 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6637 }
6638 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6639
6640 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6641 f_sleep(X2002);
6642
6643 /* 1 PDCH occupied */
6644 if (egprs) {
6645 expect := {
6646 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6647 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6648 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6649 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6650 };
6651 } else {
6652 expect := {
6653 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6654 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6655 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6656 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6657 };
6658 }
6659 f_statsd_expect(expect);
6660
6661 /* Clean up */
6662 f_shutdown(__BFILE__, __LINE__, final := true);
6663}
6664testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6665 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6666}
6667testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6668 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6669}
6670
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006671/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6672testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
6673 var PCUIF_info_ind info_ind;
6674 var template IARRestOctets rest;
6675 var BIT11 ra11;
6676
6677 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006678
6679 /* Only the first TRX is enabled. */
6680 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
6681 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6682
6683 /* Initialize the PCU interface abstraction */
6684 f_init_raw(testcasename(), info_ind);
6685 f_statsd_reset();
6686
6687 var EGPRSPktChRequest req := {
6688 one_phase := {
6689 tag := '0'B,
6690 multislot_class := '10101'B,
6691 priority := '01'B,
6692 random_bits := '101'B
6693 }
6694 };
6695
6696 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
6697 for (var integer i := 0; i < 7; i := i + 1) {
6698 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
6699 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
6700 }
6701
6702 ra11 := enc_EGPRSPktChRequest2bits(req);
6703 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
6704
6705 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01006706 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006707
6708 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
6709 f_sleep(2.0);
6710 var StatsDExpects expect := {
6711 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
6712 };
6713 f_statsd_expect(expect);
6714
6715 f_shutdown(__BFILE__, __LINE__, final := true);
6716}
6717
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006718control {
6719 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01006720 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006721 execute( TC_ta_ptcch_idle() );
6722 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02006723 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006724 execute( TC_ta_idle_dl_tbf_ass() );
6725 execute( TC_ta_ptcch_ul_multi_tbf() );
6726 execute( TC_cs_lqual_ul_tbf() );
6727 execute( TC_cs_initial_ul() );
6728 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01006729 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01006730 execute( TC_cs_max_dl() );
6731 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01006732 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01006733 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01006734 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01006735 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02006736 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01006737 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02006738 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01006739 execute( TC_x2031_t3191() );
6740 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006741 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01006742 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01006743 execute( TC_t3172_wait_ind_size0() );
6744 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02006745 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02006746 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02006747 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006748 execute( TC_mo_ping_pong() );
6749 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02006750 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006751 execute( TC_mt_ping_pong() );
6752 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006753 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006754 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07006755 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006756 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01006757 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006758 execute( TC_paging_cs_from_bts() );
6759 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
6760 execute( TC_paging_cs_from_sgsn_sign() );
6761 execute( TC_paging_cs_from_sgsn_ptp() );
6762 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
6763 execute( TC_paging_ps_from_sgsn_sign() );
6764 execute( TC_paging_ps_from_sgsn_ptp() );
Oliver Smithe1a77c42021-07-28 13:36:09 +02006765 if (mp_osmo_pcu_newer_than_0_9_0) {
6766 execute( TC_paging_pch_timeout() );
6767 }
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07006768 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
6769 execute( TC_paging_cs_multi_ms_imsi() );
6770 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02006771 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
6772 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01006773 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
6774 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006775
6776 /* EGPRS specific test cases */
6777 execute( TC_egprs_pkt_chan_req_signalling() );
6778 execute( TC_egprs_pkt_chan_req_one_phase() );
6779 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07006780 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07006781 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07006782 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02006783
6784 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07006785
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006786 /* Immediate Assignment on AGCH/PCH */
6787 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
6788 execute( TC_pcuif_fh_imm_ass_ul() );
6789 execute( TC_pcuif_fh_imm_ass_dl() );
6790 /* Packet Uplink/Downlink Assignment on PACCH */
6791 execute( TC_pcuif_fh_pkt_ass_ul() );
6792 execute( TC_pcuif_fh_pkt_ass_dl() );
6793 execute( TC_multitrx_multims_alloc() );
6794 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
6795 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
6796 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02006797 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02006798 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01006799 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
6800 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006801
Pau Espin Pedrole1303052020-11-16 11:13:51 +01006802 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07006803
6804 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01006805 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01006806 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006807 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01006808 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01006809 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006810 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006811 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
6812 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006813 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
6814 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
6815 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006816 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
6817 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006818 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
6819 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
6820 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006821 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006822 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
6823 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
6824 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
6825 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006826
6827 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006828 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006829 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006830
6831 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02006832
6833 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02006834 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
6835 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006836 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006837}
6838
Harald Weltea419df22019-03-21 17:23:04 +01006839}