blob: 804644a36bd3ef26e1bb7d0fa57bca0039287a52 [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
72 charstring mp_ctrl_neigh_ip := "127.0.0.1";
73 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 Pedrol745a48b2020-10-30 15:31:07 +0100249private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200250 map(self:PCUVTY, system:PCUVTY);
251 f_vty_set_prompts(PCUVTY);
252 f_vty_transceive(PCUVTY, "enable");
253
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100254 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
255 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200256 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
257 } else {
258 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
259 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200260
261 if (g_force_two_phase_access) {
262 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
263 } else {
264 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
265 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200266}
267
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200268function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200269runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200270 /* Start the guard timer */
271 g_T_guard.start;
272 activate(as_Tguard_RAW());
273
274 /* Init PCU interface component */
Harald Welte5339b2e2020-10-04 22:52:56 +0200275 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200276 connect(vc_PCUIF:MTC, self:PCUIF);
277 map(vc_PCUIF:PCU, system:PCU);
278
279 /* Create one BTS component (we may want more some day) */
Harald Welte5339b2e2020-10-04 22:52:56 +0200280 vc_BTS := RAW_PCU_BTS_CT.create("BTS");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200281 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
282 connect(vc_BTS:TC, self:BTS);
283
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100284 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200285
Daniel Willmann535aea62020-09-21 13:27:08 +0200286 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
287 /* This is normally done in the ConnHdlr component, but here
288 * the Test_CT doubles as ConnHdlr */
289 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
290
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200291 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100292 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200293
294 /* Wait until the BTS is ready (SI13 negotiated) */
295 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
296}
297
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700298/* Register TLLI of each allocated GprsMS instance */
299private function f_multi_ms_bssgp_register()
300runs on RAW_PCU_Test_CT {
301 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
302 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
303 }
304}
305
306/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
307private function f_multi_ms_establish_tbf(boolean do_activate := false)
308runs on RAW_PCU_Test_CT {
309 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
310 /* Establish an Uplink TBF */
311 f_ms_establish_ul_tbf(g_ms[i]);
312
313 /* Send a random block, so this TBF becomes "active" */
314 if (do_activate) {
315 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100316 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700317 var octetstring dummy := f_rnd_octstring(12);
318 var RlcmacDlBlock dl_block;
319 var uint32_t poll_fn;
320
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200321 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 +0700322 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
323 }
324 }
325}
326
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100327private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
328 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
329runs on RAW_PCU_Test_CT return PollFnCtx {
330 var PollFnCtx pollctx;
331
332 /* Single block (two phase) packet access */
333 var uint16_t ra := bit2int(chan_req_sb);
334 if (g_force_two_phase_access) {
335 /* If 2phase access is enforced by the network, then let's
336 * request a One phase packet access, we'll receive a single block
337 * anyway
338 */
339 ra := bit2int(chan_req_def);
340 }
341
342 /* Establish an Uplink TBF */
343 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
344 f_ms_establish_ul_tbf(ms);
345
346 /* Make sure we've got an Uplink TBF assignment */
347 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
348 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
349 f_shutdown(__BFILE__, __LINE__);
350 }
351
352 /* Send PACKET RESOURCE REQUEST
353 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
354 */
355 if (istemplatekind(pkt_res_req, "omit")) {
356 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
357 }
358
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200359 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 +0100360 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100361 * overwrite the TS allocation on MS with info from new UL TBF:
362 */
363 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
364 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
365 return pollctx;
366}
367
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200368testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200369 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100370 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200371 timer T;
372
373 /* Initialize NS/BSSGP side */
374 f_init_bssgp();
375
376 /* Initialize the PCU interface abstraction */
377 f_init_raw(testcasename());
378
379 /* Establish BSSGP connection to the PCU */
380 f_bssgp_establish();
381
382 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
383
384 T.start(2.0);
385 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100386 [] 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 +0200387 setverdict(pass);
388 }
389 [] T.timeout {
390 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
391 }
392 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700393
394 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200395}
396
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100397/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
398testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
399 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
400 var RlcmacDlBlock dl_block;
401 var octetstring data := f_rnd_octstring(10);
402 var uint32_t sched_fn;
403 var uint32_t dl_fn;
404 var GprsMS ms;
405 timer T;
406
407 /* Initialize NS/BSSGP side */
408 f_init_bssgp();
409 /* Initialize GPRS MS side */
410 f_init_gprs_ms();
411 ms := g_ms[0]; /* We only use first MS in this test */
412
413 /* Initialize the PCU interface abstraction */
414 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
415
416 /* Establish BSSGP connection to the PCU */
417 f_bssgp_establish();
418 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
419
420 /* Establish an Uplink TBF */
421 f_ms_establish_ul_tbf(ms);
422
423 /* Send one UL block (with TLLI since we are in One-Phase Access
424 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200425 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 +0100426 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
427 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
428 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
429
430 /* UL block should be received in SGSN */
431 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
432
433 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
434 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
435 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
436
437 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
438 f_sleep(X2002);
439 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
440
441 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
442 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
443
444 T.start(2.0);
445 alt {
446 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
447 setverdict(pass);
448 }
449 [] T.timeout {
450 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
451 f_shutdown(__BFILE__, __LINE__);
452 }
453 }
454
455 /* Make sure we don't receive data for that TBF since it was released
456 * before. Also check our TBF is not polled for UL. */
457 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
458 if (dl_block.ctrl.mac_hdr.usf != USF_UNUSED) {
459 setverdict(fail, "Unexpected USF ", dl_block.ctrl.mac_hdr.usf);
460 f_shutdown(__BFILE__, __LINE__);
461 }
462
463 /* New data arrives, PCU should page the MS since no TBF active exists: */
464 /* Send some more data, it will never reach the MS */
465 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
466 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
467
468 f_shutdown(__BFILE__, __LINE__, final := true);
469}
470
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200471/* Test of correct Timing Advance at the time of TBF establishment
472 * (derived from timing offset of the Access Burst). */
473testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200474 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200475
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200476 /* Initialize GPRS MS side */
477 f_init_gprs_ms();
478 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200479 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100480 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200481
482 /* We cannot send too many TBF requests in a short time because
483 * at some point the PCU will fail to allocate a new TBF. */
484 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
485 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200486 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700487 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200488
489 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200490 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700491 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200492 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700493 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700494 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200495 }
496 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700497
498 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200499}
500
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200501/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
502 * sent in response to the first Uplink block after resource allocation. */
503testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
504 var GprsMS ms := valueof(t_GprsMS_def);
505 var PacketUlAckNack ul_ack_nack;
506 var PacketTimingAdvance pkt_ta;
507 var RlcmacDlBlock dl_block;
508 var uint32_t sched_fn;
509
510 /* Initialize NS/BSSGP side */
511 f_init_bssgp();
512
513 /* Initialize the PCU interface abstraction */
514 f_init_raw(testcasename());
515
516 /* Establish BSSGP connection to the PCU */
517 f_bssgp_establish();
518 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
519
520 /* Establish an Uplink TBF */
521 f_ms_establish_ul_tbf(ms);
522
523 /* In a busy network, there can be a significant delay between resource
524 * allocation (Packet Uplink Assignment above) and the actual time when
525 * the MS is allowed to transmit the first Uplink data block. */
526
527 /* Simulate a delay > 0 */
528 ms.ta := 2;
529
530 /* We're in One-Phase Access contention resoultion, include TLLI */
531 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
532 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
533
534 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
535 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
536 pkt_ta := ul_ack_nack.gprs.pkt_ta;
537 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
538 pkt_ta := ul_ack_nack.egprs.pkt_ta;
539 } else {
540 setverdict(fail, "PacketTimingAdvance IE is not present");
541 f_shutdown(__BFILE__, __LINE__);
542 }
543
544 if (not ispresent(pkt_ta.val)) {
545 setverdict(fail, "Timing Advance value is not present");
546 f_shutdown(__BFILE__, __LINE__);
547 } else if (pkt_ta.val != ms.ta) {
548 setverdict(fail, "Timing Advance mismatch: expected ",
549 ms.ta, ", but received ", pkt_ta.val);
550 f_shutdown(__BFILE__, __LINE__);
551 }
552}
553
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200554/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
555 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
556 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
557 * no active TBF exists at the moment of establishment (idle mode). */
558testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100559 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200560
561 /* Initialize NS/BSSGP side */
562 f_init_bssgp();
563
564 /* Initialize the PCU interface abstraction */
565 f_init_raw(testcasename());
566
567 /* Establish BSSGP connection to the PCU */
568 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100569 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200570
571 /* SGSN sends some DL data, PCU will initiate Packet Downlink
572 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100573 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
574 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200575
576 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
577 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
578 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100579 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700580 setverdict(fail, "Timing Advance value doesn't match");
581 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700582
583 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200584}
585
586/* Verify that the PCU generates valid PTCCH/D messages
587 * while neither Uplink nor Downlink TBF is established. */
588testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100589 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200590 timer T;
591
592 /* Initialize the PCU interface abstraction */
593 f_init_raw(testcasename());
594
595 /* Sent an RTS.req for PTCCH/D */
596 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
597 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
598 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100599
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200600 T.start(5.0);
601 alt {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100602 /* Make sure the message is encoded correctly
603 * TODO: do we expect all TA values to be equal '1111111'B? */
604 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg);
605
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200606 [] BTS.receive(PCUIF_Message:?) { repeat; }
607 [] T.timeout {
608 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700609 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200610 }
611 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100612 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700613
614 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200615}
616
617/* Test of correct Timing Advance during an active Uplink TBF.
618 *
619 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
620 * are not continuous and there can be long time gaps between them. This happens
621 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
622 * significantly change between such rare Uplink transmissions, so GPRS introduces
623 * additional mechanisms to control Timing Advance, and thus reduce interference
624 * between neighboring TDMA time-slots.
625 *
626 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
627 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
628 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
629 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
630 * among with the initial Timing Advance value. And here PTCCH comes to play.
631 *
632 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
633 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
634 * continuously. To ensure continuous measurements of the signal propagation
635 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
636 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
637 *
638 * The purpose of this test case is to verify the assignment of Timing Advance
639 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
640 * first establishes several Uplink TBFs, but does not transmit any Uplink
641 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
642 * indications to the PCU, checking the correctness of two received PTCCH/D
643 * messages (period of PTCCH/D is two multi-frames).
644 */
645
646/* List of ToA values for Access Bursts to be sent on PTCCH/U,
647 * each ToA (Timing of Arrival) value is in units of 1/4 of
648 * a symbol (i.e. 1 symbol is 4 QTA units). */
649type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
650const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
651 0, 0, 0, 0,
652 0, 0, 0, 0,
653 0, 0, 0, 0,
654 0, 0, 0, 0
655};
656
657private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
658 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
659runs on RAW_PCU_Test_CT {
660 var RAW_PCU_Event event;
661 var integer ss;
662
663 /* Send Access Bursts on PTCCH/U for every TA Index */
664 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
665 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700666 if (ss < 0) { /* Shall not happen */
667 f_shutdown(__BFILE__, __LINE__);
668 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200669
670 log("Sending an Access Burst on PTCCH/U",
671 ", sub-slot=", ss, " (TAI)",
672 ", fn=", event.data.tdma_fn,
673 ", ToA=", toa_map[ss], " (QTA)");
674 /* TODO: do we care about RA and burst format? */
675 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
676 ra := oct2int('3A'O),
677 is_11bit := 0,
678 burst_type := BURST_TYPE_0,
679 fn := event.data.tdma_fn,
680 arfcn := 871,
681 qta := toa_map[ss],
682 sapi := PCU_IF_SAPI_PTCCH));
683 repeat;
684 }
685}
686
687private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
688 template PTCCHDownlinkMsg t_ta_msg)
689runs on RAW_PCU_Test_CT {
690 var PTCCHDownlinkMsg ta_msg;
691 var PCUIF_Message pcu_msg;
692 timer T;
693
694 /* First, send an RTS.req for the upcoming PTCCH/D block */
695 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
696 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
697 arfcn := 871, block_nr := 0));
698 T.start(2.0);
699 alt {
700 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
701 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
702 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
703 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
704 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
705 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
706 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
707 log("Rx PTCCH/D message: ", ta_msg);
708
709 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700710 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200711 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
712 }
713 }
714 [] BTS.receive { repeat; }
715 [] T.timeout {
716 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200717 }
718 }
719}
720
721testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
722 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200723 var GprsMS ms;
724
725 /* Initialize GPRS MS side */
726 f_init_gprs_ms();
727 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200728
729 /* Initialize the PCU interface abstraction */
730 f_init_raw(testcasename());
731
732 /* Enable forwarding of PTCCH/U TDMA events to us */
733 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
734
735 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
736 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200737 /* Establish an Uplink TBF */
738 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200739
740 /* We expect incremental TFI/USF assignment (dynamic allocation) */
741 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200742 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200743 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700744 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200745 }
746
747 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200748 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200749 setverdict(fail, "Failed to match Timing Advance Index for #", i);
750 /* Keep going, the current OsmoPCU does not assign TA Index */
751 }
752 }
753
754 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
755 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
756 for (var integer i := 0; i < 7; i := i + 1) {
757 /* ToA in units of 1/4 of a symbol */
758 toa_map[i] := (i + 1) * 7 * 4;
759 }
760
761 /* Now we have all 7 TBFs established in one-phase access mode,
762 * however we will not be sending any data on them. Instead, we
763 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
764 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
765 *
766 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
767 * time-slots, so at the moment of scheduling a PTCCH/D block
768 * the PCU has odd number of PTCCH/U Access Bursts received. */
769 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
770 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
771 /* Other values are not known (yet) */
772 tai3_ta := ?));
773 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
774 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
775 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
776 /* Other values are out of our interest */
777 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700778
779 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200780}
781
782/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
783 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
784 *
785 * NOTE: the ranges are intentionally overlapping because OsmoPCU
786 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
787private template integer CS1_lqual_dB_range := (-infinity .. 6);
788private template integer CS2_lqual_dB_range := (5 .. 8);
789private template integer CS3_lqual_dB_range := (7 .. 13);
790private template integer CS4_lqual_dB_range := (12 .. infinity);
791
792testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200793 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200794 var GprsMS ms;
795 var uint32_t unused_fn, sched_fn;
796 var uint4_t cv;
797
798 /* Initialize GPRS MS side */
799 f_init_gprs_ms();
800 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200801
802 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100803 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200804
805 f_pcuvty_set_allowed_cs_mcs();
806 f_pcuvty_set_link_quality_ranges();
807
808 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200809 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200810
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200811
812 /* The actual / old link quality values. We need to keep track of the old
813 * (basically previous) link quality value, because OsmoPCU actually
814 * changes the coding scheme if not only the actual, but also the old
815 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200816 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200817 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200818
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200819 /* Send one UL block (with TLLI since we are in One-Phase Access
820 contention resoultion) and make sure it is ACKED fine. */
821 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
822 /* 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 +0200823 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 +0200824 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
825 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
826 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200827
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200828 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
829 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200831 lqual_old := ms.lqual_cb;
832 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200833
834 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200835 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
836 if (i > g_bs_cv_max) {
837 cv := 15;
838 } else {
839 cv := i;
840 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200841
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200842 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
843
844 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
845 f_rx_rlcmac_dl_block(dl_block, unused_fn);
846 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
847 continue;
848 }
849 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
850 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
851 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
852 f_shutdown(__BFILE__, __LINE__);
853 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200854
855 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
856 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
857
858 /* Match the received Channel Coding Command. Since we are increasing
859 * the link quality value on each iteration and not decreasing, there
860 * is no need to check the both old and current link quality values. */
861 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200862 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200863 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
864 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
865 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
866 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
867 }
868
869 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
870 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200871 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200872 }
873 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700874
875 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200876}
877
878/* Test the max UL CS set by VTY works fine */
879testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200880 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200881 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200882 var uint32_t unused_fn, sched_fn;
883 var GprsMS ms;
884
885 /* Initialize GPRS MS side */
886 f_init_gprs_ms();
887 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200888
889 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100890 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200891
892 /* Set initial UL CS to 3 */
893 g_cs_initial_ul := 3;
894 f_pcuvty_set_allowed_cs_mcs();
895 f_pcuvty_set_link_quality_ranges();
896
897 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200898 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200899
900 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200901 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200902
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200903 /* Send one UL block (with TLLI since we are in One-Phase Access
904 contention resoultion) and make sure it is ACKED fine. */
905 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
906 /* 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 +0200907 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 +0200908 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
909 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
910 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200911
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200912 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
913 while (true) {
914 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
915 f_rx_rlcmac_dl_block(dl_block, unused_fn);
916 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
917 continue;
918 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200919
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200920 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
921 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
922 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
923 f_shutdown(__BFILE__, __LINE__);
924 break;
925 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200926
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200927 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200928 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200929 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200930 if (last_ch_coding != CH_CODING_CS3) {
931 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200932 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200933 }
934
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200935 /* Remaining UL blocks are used to make sure regardless of initial
936 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200937 /* 0 dB, make sure we downgrade CS */
938 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200939 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200940 f_ms_tx_ul_data_block_multi(ms, 5);
941 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
942 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
943 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200944
945 if (last_ch_coding != CH_CODING_CS1) {
946 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200947 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200948 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700949
950 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200951}
952
953/* Test the max UL CS set by VTY works fine */
954testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200955 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200956 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200957 var uint32_t unused_fn, sched_fn;
958 var GprsMS ms;
959
960 /* Initialize GPRS MS side */
961 f_init_gprs_ms();
962 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200963
964 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100965 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200966
967 /* Set maximum allowed UL CS to 3 */
968 g_cs_max_ul := 3;
969 f_pcuvty_set_allowed_cs_mcs();
970 f_pcuvty_set_link_quality_ranges();
971
972 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200973 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200974
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200975 /* Send one UL block (with TLLI since we are in One-Phase Access
976 contention resoultion) and make sure it is ACKED fine. */
977 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
978 /* 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 +0200979 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 +0200980 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
981 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
982 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200983
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200984 ms.lqual_cb := 40*10; /* 40 dB */
985 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200986
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200987 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
988 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200989
990 if (last_ch_coding != CH_CODING_CS3) {
991 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200992 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200993 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700994
995 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200996}
997
Pau Espin Pedrol75122592020-11-03 15:22:59 +0100998/* Test the initial DL CS set by VTY works fine */
999testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1000 var octetstring data := f_rnd_octstring(10);
1001 var CodingScheme exp_dl_cs_mcs;
1002 var RlcmacDlBlock dl_block;
1003 var uint32_t poll_fn;
1004 var GprsMS ms;
1005
1006 /* Initialize NS/BSSGP side */
1007 f_init_bssgp();
1008 /* Initialize GPRS MS side */
1009 f_init_gprs_ms();
1010 ms := g_ms[0]; /* We only use first MS in this test */
1011
1012 /* Initialize the PCU interface abstraction */
1013 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1014
1015 /* Set initial allowed DL CS to 3 */
1016 g_cs_initial_dl := 3;
1017 exp_dl_cs_mcs := CS_3;
1018 /* Set maximum allowed UL CS to 4 */
1019 g_cs_max_dl := 4;
1020 f_pcuvty_set_allowed_cs_mcs();
1021 f_pcuvty_set_link_quality_ranges();
1022
1023 /* Establish BSSGP connection to the PCU */
1024 f_bssgp_establish();
1025 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1026
1027 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1028 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1029 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1030
1031 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1032 f_sleep(X2002);
1033 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1034
1035 /* ACK the DL block */
1036 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1037 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1038 f_dl_block_ack_fn(dl_block, poll_fn));
1039
1040 f_shutdown(__BFILE__, __LINE__, final := true);
1041}
1042
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001043/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001044function 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 +01001045 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001046 var RlcmacDlBlock prev_dl_block, dl_block;
1047 var uint32_t ack_fn;
1048 var uint32_t fn;
1049 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001050 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001051 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001052 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1053 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001054 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001055
1056 if (using_egprs) {
1057 exp_tmp_csmcs := mcs_egprs_any;
1058 bsn_mod := 2048;
1059 } else {
1060 exp_tmp_csmcs := cs_gprs_any;
1061 bsn_mod := 128;
1062 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001063
1064 /* Establish BSSGP connection to the PCU */
1065 f_bssgp_establish();
1066
1067 ms := g_ms[0]; /* We only use first MS in this test */
1068 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1069
1070 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001071 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001072 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1073
1074 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1075 f_sleep(X2002);
1076
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001077 for (var integer i := 0; i < 800; i := i + 1) {
1078 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001079 f_rx_rlcmac_dl_block(dl_block, fn);
1080
1081 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
1082 /* No more data to receive, done */
1083 break;
1084 }
1085
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001086 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001087
1088 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001089 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001090
1091 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001092 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001093 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001094 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 +01001095 if (tx_data_remain != 0) {
1096 /* Submit more data from time to time to keep the TBF ongoing */
1097 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1098 tx_data_remain := tx_data_remain - 1;
1099 }
1100 }
1101 prev_dl_block := dl_block;
1102 }
1103
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001104 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1105 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001106
1107
1108 f_shutdown(__BFILE__, __LINE__, final := true);
1109}
1110
1111/* Verify DL CS above "cs max" set by VTY is never used */
1112testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1113 /* Initialize NS/BSSGP side */
1114 f_init_bssgp();
1115 /* Initialize GPRS MS side */
1116 f_init_gprs_ms();
1117
1118 /* Initialize the PCU interface abstraction */
1119 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1120
1121 /* Set maximum allowed DL CS to 3 */
1122 g_cs_initial_dl := 1;
1123 g_cs_max_dl := 3;
1124 f_pcuvty_set_allowed_cs_mcs();
1125 f_pcuvty_set_link_quality_ranges();
1126
1127 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1128}
1129
1130/* Check DL CS4 is used in good link conditions if allowed by config */
1131testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1132 /* Initialize NS/BSSGP side */
1133 f_init_bssgp();
1134 /* Initialize GPRS MS side */
1135 f_init_gprs_ms();
1136
1137 /* Initialize the PCU interface abstraction */
1138 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1139
1140 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1141 g_cs_initial_dl := 1;
1142 g_cs_max_dl := 4;
1143 f_pcuvty_set_allowed_cs_mcs();
1144 f_pcuvty_set_link_quality_ranges();
1145
1146 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1147}
1148
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001149/* Test the initial UL MCS set by VTY works fine */
1150testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1151 var RlcmacDlBlock dl_block;
1152 var PollFnCtx pollctx;
1153 var EgprsChCodingCommand last_ch_coding;
1154 var uint32_t unused_fn, sched_fn;
1155 var GprsMS ms;
1156 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001157
1158 /* Initialize GPRS MS side */
1159 f_init_gprs_ms();
1160 ms := g_ms[0]; /* We only use first MS in this test */
1161
1162 /* Initialize the PCU interface abstraction */
1163 f_init_raw(testcasename());
1164
1165 /* Set initial UL MCS to 3 */
1166 g_mcs_initial_ul := 3;
1167 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1168 f_pcuvty_set_allowed_cs_mcs();
1169 f_pcuvty_set_link_quality_ranges();
1170
1171 /* Take lqual (dB->cB) so that we stay in that MCS */
1172 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1173
1174 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001175 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 +01001176
1177 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1178 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1179 f_shutdown(__BFILE__, __LINE__);
1180 }
1181
1182 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1183 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1184
1185 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1186 while (true) {
1187 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1188 f_rx_rlcmac_dl_block(dl_block, unused_fn);
1189 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1190 continue;
1191 }
1192
1193 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1194 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1195 f_shutdown(__BFILE__, __LINE__);
1196 break;
1197 }
1198
1199 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1200 break;
1201 }
1202 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1203 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1204 f_shutdown(__BFILE__, __LINE__);
1205 }
1206
1207 /* Remaining UL blocks are used to make sure regardless of initial
1208 * lqual, we can go lower at any time
1209 * 0 dB, make sure we downgrade MCS */
1210 ms.lqual_cb := 0;
1211 /* 5 UL blocks, check we are in same initial MCS: */
1212 f_ms_tx_ul_data_block_multi(ms, 5);
1213 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1214 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1215 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1216
1217 if (last_ch_coding != CH_CODING_MCS1) {
1218 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1219 f_shutdown(__BFILE__, __LINE__);
1220 }
1221
1222 f_shutdown(__BFILE__, __LINE__, final := true);
1223}
1224
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001225/* Test the maximum UL MCS set by VTY works fine */
1226testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1227 var RlcmacDlBlock dl_block;
1228 var EgprsChCodingCommand last_ch_coding;
1229 var PollFnCtx pollctx;
1230 var uint32_t unused_fn, sched_fn;
1231 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001232
1233 /* Initialize GPRS MS side */
1234 f_init_gprs_ms();
1235 ms := g_ms[0]; /* We only use first MS in this test */
1236
1237 /* Initialize the PCU interface abstraction */
1238 f_init_raw(testcasename());
1239
1240 /* Set maximum allowed UL MCS to 5 */
1241 g_mcs_max_ul := 5;
1242 f_pcuvty_set_allowed_cs_mcs();
1243 f_pcuvty_set_link_quality_ranges();
1244
1245 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001246 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 +01001247 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1248 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1249
1250 ms.lqual_cb := 40*10; /* 40 dB */
1251 f_ms_tx_ul_data_block_multi(ms, 16);
1252
1253 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1254 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1255
1256 if (last_ch_coding != CH_CODING_MCS5) {
1257 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1258 f_shutdown(__BFILE__, __LINE__);
1259 }
1260
1261 f_shutdown(__BFILE__, __LINE__, final := true);
1262}
1263
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001264/* Test the initial DL CS set by VTY works fine */
1265testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1266 var octetstring data := f_rnd_octstring(10);
1267 var CodingScheme exp_dl_cs_mcs;
1268 var RlcmacDlBlock dl_block;
1269 var uint32_t poll_fn;
1270 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001271
1272 /* Initialize NS/BSSGP side */
1273 f_init_bssgp();
1274 /* Initialize GPRS MS side */
1275 f_init_gprs_ms();
1276 ms := g_ms[0]; /* We only use first MS in this test */
1277
1278 /* Initialize the PCU interface abstraction */
1279 f_init_raw(testcasename());
1280
1281 /* Set initial allowed DL MCS to 3 */
1282 g_mcs_initial_dl := 3;
1283 exp_dl_cs_mcs := MCS_3;
1284 /* Set maximum allowed DL MCS to 4 */
1285 g_mcs_max_dl := 4;
1286 f_pcuvty_set_allowed_cs_mcs();
1287 f_pcuvty_set_link_quality_ranges();
1288
1289 /* Establish BSSGP connection to the PCU */
1290 f_bssgp_establish();
1291 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1292
1293 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001294 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001295 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1296
1297 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1298 f_sleep(X2002);
1299 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1300
1301 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001302 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1303 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 +01001304 f_dl_block_ack_fn(dl_block, poll_fn));
1305
1306 f_shutdown(__BFILE__, __LINE__, final := true);
1307}
1308
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001309/* Verify DL MCS above "mcs max" set by VTY is never used */
1310testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1311 /* Initialize NS/BSSGP side */
1312 f_init_bssgp();
1313 /* Initialize GPRS MS side */
1314 f_init_gprs_ms();
1315
1316 /* Initialize the PCU interface abstraction */
1317 f_init_raw(testcasename());
1318
1319 /* Set maximum allowed DL CS to 3 */
1320 g_mcs_initial_dl := 1;
1321 g_mcs_max_dl := 3;
1322 f_pcuvty_set_allowed_cs_mcs();
1323 f_pcuvty_set_link_quality_ranges();
1324
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001325 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 +01001326}
1327
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001328/* Verify PCU drops TBF after some time of inactivity. */
1329testcase TC_t3141() runs on RAW_PCU_Test_CT {
1330 var PCUIF_info_ind info_ind;
1331 var template (value) TsTrxBtsNum nr;
1332 var BTS_PDTCH_Block data_msg;
1333 var GprsMS ms;
1334 var uint3_t rx_usf;
1335 timer T_3141 := 1.0;
1336 var boolean ul_tbf_usf_req := false;
1337
1338 /* Initialize NS/BSSGP side */
1339 f_init_bssgp();
1340 /* Initialize GPRS MS side */
1341 f_init_gprs_ms();
1342 ms := g_ms[0]; /* We only use first MS in this test */
1343
1344 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1345 /* Only use 1 PDCH to simplify test: */
1346 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1347 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1348 /* Initialize the PCU interface abstraction */
1349 f_init_raw(testcasename(), info_ind);
1350
1351 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1352
1353 /* Establish BSSGP connection to the PCU */
1354 f_bssgp_establish();
1355 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1356
1357 /* Establish a one-phase access Uplink TBF */
1358 f_ms_establish_ul_tbf(ms);
1359
1360 T_3141.start;
1361
1362 /* Now we wait for PCU to transmit our USF */
1363 nr := ts_TsTrxBtsNum;
1364 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1365 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1366 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1367 block_nr := nr.blk_nr));
1368
1369 alt {
1370 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1371 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1372 ?)) -> value data_msg {
1373 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1374 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1375 f_shutdown(__BFILE__, __LINE__);
1376 }
1377
1378 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1379 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1380 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1381 ul_tbf_usf_req := true;
1382 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))
1383 } else if (rx_usf == USF_UNUSED) {
1384 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1385 if (ul_tbf_usf_req) {
1386 /* TBF was dropped by T3141, success */
1387 setverdict(pass);
1388 break;
1389 } else {
1390 log("PCU never requested USF, unexpected");
1391 f_shutdown(__BFILE__, __LINE__);
1392 }
1393 } /* else: Keep waiting for TBF to be active by network */
1394 } else {
1395 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1396 f_shutdown(__BFILE__, __LINE__);
1397 }
1398
1399 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1400 if (match(data_msg.dl_block,
1401 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1402 tr_UlAckNackGprs(tlli := ?,
1403 acknack_desc := ?,
1404 rel99 := *))))
1405 {
1406 log("Received UL ACK/NACK with TLLI set");
1407 f_shutdown(__BFILE__, __LINE__);
1408 }
1409
1410 nr := ts_TsTrxBtsNum;
1411 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1412 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1413 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1414 block_nr := nr.blk_nr));
1415 repeat;
1416 }
1417 [] T_3141.timeout {
1418 log("T_3141 expired but TBF is still active, unexpected");
1419 f_shutdown(__BFILE__, __LINE__);
1420 }
1421 [] BTS.receive {
1422 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1423 * because we never sent the TLLI to the PCU */
1424 setverdict(fail, "Unexpected BTS message");
1425 f_shutdown(__BFILE__, __LINE__);
1426 }
1427 }
1428
1429 f_shutdown(__BFILE__, __LINE__, final := true);
1430}
1431
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001432/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1433 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1434 * T3169. See OS#5033 */
1435testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1436 var PCUIF_info_ind info_ind;
1437 var template (value) TsTrxBtsNum nr;
1438 var BTS_PDTCH_Block data_msg;
1439 var GprsMS ms;
1440 var uint3_t rx_usf;
1441 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1442 var integer n3101 := 0;
1443 timer T_3169 := 1.0;
1444
1445 /* Initialize NS/BSSGP side */
1446 f_init_bssgp();
1447 /* Initialize GPRS MS side */
1448 f_init_gprs_ms();
1449 ms := g_ms[0]; /* We only use first MS in this test */
1450
1451 /* Initialize the PCU interface abstraction */
1452 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1453 info_ind.n3101 := N3101_MAX;
1454 info_ind.t3169 := 1;
1455 f_init_raw(testcasename(), info_ind);
1456
1457 /* Establish BSSGP connection to the PCU */
1458 f_bssgp_establish();
1459 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1460
1461 /* Establish UL TBF */
1462 f_ms_establish_ul_tbf(ms);
1463
1464 /* Now we wait for PCU to transmit our USF */
1465 nr := ts_TsTrxBtsNum;
1466 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1467 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1468 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1469 block_nr := nr.blk_nr));
1470
1471 alt {
1472 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1473 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1474 ?)) -> value data_msg {
1475 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1476 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1477 f_shutdown(__BFILE__, __LINE__);
1478 }
1479
1480 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1481 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1482 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1483 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001484 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1485 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001486 f_shutdown(__BFILE__, __LINE__);
1487 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001488 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001489 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1490 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1491 if (not T_3169.running) {
1492 log("T3169 started");
1493 T_3169.start;
1494 }
1495 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1496 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1497 f_shutdown(__BFILE__, __LINE__);
1498 } else {
1499 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1500 }
1501 nr := ts_TsTrxBtsNum;
1502 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1503 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1504 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1505 block_nr := nr.blk_nr));
1506 repeat;
1507 }
1508 [] T_3169.timeout {
1509 log("T_3169 expired");
1510 /* Done in alt */
1511 }
1512 [] BTS.receive {
1513 setverdict(fail, "Unexpected BTS message");
1514 f_shutdown(__BFILE__, __LINE__);
1515 }
1516 }
1517
1518 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1519 /* USFs as per previous TBF since they were freed at expiration time: */
1520 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1521 var uint5_t old_tfi := ms.ul_tbf.tfi;
1522 f_ms_establish_ul_tbf(ms);
1523 if (old_tfi != ms.ul_tbf.tfi) {
1524 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1525 f_shutdown(__BFILE__, __LINE__);
1526 }
1527 for (var integer i := 0; i < 8; i := i +1) {
1528 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1529 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1530 f_shutdown(__BFILE__, __LINE__);
1531 }
1532 }
1533
1534 f_shutdown(__BFILE__, __LINE__, final := true);
1535}
1536
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001537
1538/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1539 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1540 the final UL ACK sent at us. */
1541testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1542 var PCUIF_info_ind info_ind;
1543 var BTS_PDTCH_Block data_msg;
1544 var RlcmacDlBlock dl_block;
1545 var uint32_t sched_fn;
1546 var template (value) TsTrxBtsNum nr;
1547 var template RlcmacDlBlock exp_ul_ack;
1548 var template UlAckNackGprs exp_ul_ack_sub;
1549 var GprsMS ms;
1550 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1551 var integer N3103 := 0;
1552 timer T_3169 := 1.0;
1553
1554 /* Initialize GPRS MS side */
1555 f_init_gprs_ms();
1556 ms := g_ms[0]; /* We only use first MS in this test */
1557
1558 /* Initialize the PCU interface abstraction */
1559 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1560 info_ind.n3103 := N3103_MAX;
1561 info_ind.t3169 := 1;
1562 f_init_raw(testcasename(), info_ind);
1563
1564 /* Establish an Uplink TBF */
1565 f_ms_establish_ul_tbf(ms);
1566
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001567 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001568 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1569 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1570
1571 nr := ts_TsTrxBtsNum;
1572 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1573 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1574 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1575 block_nr := nr.blk_nr));
1576 alt {
1577 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1578 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1579 exp_ul_ack)) -> value data_msg {
1580 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1581 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1582 f_shutdown(__BFILE__, __LINE__);
1583 }
1584
1585 nr := ts_TsTrxBtsNum;
1586 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1587 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1588 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1589 block_nr := nr.blk_nr));
1590 N3103 := N3103 + 1;
1591 if (N3103 == N3103_MAX) {
1592 /* At this point in time (N3103_MAX reached), PCU is
1593 * moving the TBF to RELEASE state so no data/ctrl for
1594 * it is tx'ed, hence the dummy blocks: */
1595 T_3169.start;
1596 }
1597 repeat;
1598 }
1599 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1600 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1601 exp_ul_ack)) -> value data_msg {
1602 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1603 f_shutdown(__BFILE__, __LINE__);
1604 }
1605 [] as_ms_rx_ignore_dummy(ms, nr);
1606 [T_3169.running] T_3169.timeout {
1607 log("T_3169 timeout");
1608 /* Done in alt, wait for pending RTS initiated previously in
1609 * above case before continuing (expect /* Dummy block): */
1610 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1611 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1612 tr_RLCMAC_DUMMY_CTRL));
1613 }
1614 [] BTS.receive {
1615 setverdict(fail, "Unexpected BTS message");
1616 f_shutdown(__BFILE__, __LINE__);
1617 }
1618 }
1619
1620 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1621 * USFs as per previous TBF since they were freed at expiration time: */
1622 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1623 var uint5_t old_tfi := ms.ul_tbf.tfi;
1624 f_ms_establish_ul_tbf(ms);
1625 if (old_tfi != ms.ul_tbf.tfi) {
1626 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1627 f_shutdown(__BFILE__, __LINE__);
1628 }
1629 for (var integer i := 0; i < 8; i := i +1) {
1630 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1631 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1632 f_shutdown(__BFILE__, __LINE__);
1633 }
1634 }
1635
1636 f_shutdown(__BFILE__, __LINE__, final := true);
1637}
1638
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001639/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1640 * point the TBF is no longer available. In order to get to start of T3191, we
1641 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1642 * until TBF release procedure starts after draining DL queue. */
1643testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1644 var PCUIF_info_ind info_ind;
1645 var RlcmacDlBlock dl_block;
1646 var octetstring data1 := f_rnd_octstring(200);
1647 var octetstring data2 := f_rnd_octstring(10);
1648 var uint32_t dl_fn;
1649 var template (value) TsTrxBtsNum nr;
1650 var BTS_PDTCH_Block data_msg;
1651 var GprsMS ms;
1652
1653 /* Initialize NS/BSSGP side */
1654 f_init_bssgp();
1655 /* Initialize GPRS MS side */
1656 f_init_gprs_ms();
1657 ms := g_ms[0]; /* We only use first MS in this test */
1658
1659 /* Initialize the PCU interface abstraction */
1660 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1661 /* Set timer to 1 sec (default 5) to speedup test: */
1662 info_ind.t3191 := 1;
1663 f_init_raw(testcasename(), info_ind);
1664
1665 /* Establish BSSGP connection to the PCU */
1666 f_bssgp_establish();
1667 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1668
1669 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1670 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1671 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1672
1673 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1674 f_sleep(X2002);
1675
1676 while (true) {
1677 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1678
1679 /* Keep Ack/Nack description updated (except for last BSN) */
1680 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1681
1682 if (f_dl_block_rrbp_valid(dl_block)) {
1683 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1684 f_dl_block_ack_fn(dl_block, dl_fn));
1685 break;
1686 }
1687 }
1688
1689 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1690 nr := ts_TsTrxBtsNum;
1691 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1692 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1693 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1694 block_nr := nr.blk_nr));
1695 alt {
1696 [] as_ms_rx_ignore_dummy(ms, nr);
1697 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1698 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1699 ?)) -> value data_msg {
1700 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1701 log("Received FINAL_ACK");
1702 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1703 break;
1704 }
1705 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1706 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1707 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1708 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1709 }
1710 nr := ts_TsTrxBtsNum;
1711 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1712 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1713 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1714 block_nr := nr.blk_nr));
1715 repeat;
1716 }
1717 [] BTS.receive {
1718 setverdict(fail, "Unexpected BTS message");
1719 f_shutdown(__BFILE__, __LINE__);
1720 }
1721 }
1722
1723 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1724 to time out. We simply sleep instead of requesting blocks because
1725 otherwise retransmissions would keep restarting the timer. */
1726 f_sleep(int2float(info_ind.t3191));
1727
1728 /* The TBF should be freed now, so new data should trigger an Assignment: */
1729 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1730 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1731
1732 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1733 f_sleep(X2002);
1734 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1735 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1736 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1737 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1738 f_dl_block_ack_fn(dl_block, dl_fn));
1739
1740 f_shutdown(__BFILE__, __LINE__, final := true);
1741}
1742
1743/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1744testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1745 var PCUIF_info_ind info_ind;
1746 var RlcmacDlBlock dl_block;
1747 var octetstring data1 := f_rnd_octstring(1400);
1748 var octetstring data2 := f_rnd_octstring(10);
1749 var uint32_t dl_fn;
1750 var GprsMS ms;
1751
1752 /* Initialize NS/BSSGP side */
1753 f_init_bssgp();
1754 /* Initialize GPRS MS side */
1755 f_init_gprs_ms();
1756 ms := g_ms[0]; /* We only use first MS in this test */
1757
1758 /* Initialize the PCU interface abstraction */
1759 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1760 /* Set timer to 1 sec (default 5) to speedup test: */
1761 info_ind.t3191 := 1;
1762 f_init_raw(testcasename(), info_ind);
1763
1764 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1765
1766 /* Establish BSSGP connection to the PCU */
1767 f_bssgp_establish();
1768 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1769
1770 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1771 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1772 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1773
1774 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1775 f_sleep(X2002);
1776
1777 /* Send enough DL data to at least be able to DL ACK once (excl the
1778 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1779 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1780 while (true) {
1781 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1782
1783 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1784 log("Received FINAL_ACK");
1785 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1786 break;
1787 }
1788
1789 /* Keep Ack/Nack description updated (except for last BSN) */
1790 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1791
1792 if (f_dl_block_rrbp_valid(dl_block)) {
1793 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1794 f_dl_block_ack_fn(dl_block, dl_fn));
1795 }
1796 }
1797
1798 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1799 to time out. We simply sleep instead of requesting blocks because
1800 otherwise retransmissions would keep restarting the timer. */
1801 f_sleep(int2float(info_ind.t3191));
1802
1803 /* The TBF should be freed now, so new data should trigger an Assignment: */
1804 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1805 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1806
1807 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1808 f_sleep(X2002);
1809 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1810 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1811 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1812 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1813 f_dl_block_ack_fn(dl_block, dl_fn));
1814
1815 f_shutdown(__BFILE__, __LINE__, final := true);
1816}
1817
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001818/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1819 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1820 * T3193) after DL TBF release */
1821testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001822 var RlcmacDlBlock dl_block;
1823 var octetstring data := f_rnd_octstring(10);
1824 var boolean ok;
1825 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001826 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001827 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001828 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1829
1830 /* Initialize NS/BSSGP side */
1831 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001832 /* Initialize GPRS MS side */
1833 f_init_gprs_ms();
1834 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001835
1836 /* Initialize the PCU interface abstraction */
1837 f_init_raw(testcasename());
1838
1839 /* Establish BSSGP connection to the PCU */
1840 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001841 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001842
1843 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001844 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1845 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001846
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001847 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1848 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001849 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001850
1851 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001852 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1853 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1854 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001855
1856 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001857 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001858 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001859 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001860 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001861
1862 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001863
1864 /* 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 +07001865 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001866 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1867 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1868 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001869
1870 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001871}
1872
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001873/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1874 freed and no longer available. Trigger it by sending DL blocks and never DL
1875 ACKing the data (which are requested through RRBP) */
1876testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1877 var PCUIF_info_ind info_ind;
1878 var RlcmacDlBlock dl_block;
1879 var octetstring data1 := f_rnd_octstring(1000);
1880 var octetstring data2 := f_rnd_octstring(10);
1881 var uint32_t dl_fn;
1882 var template (value) TsTrxBtsNum nr;
1883 var BTS_PDTCH_Block data_msg;
1884 var GprsMS ms;
1885 const integer N3105_MAX := 2;
1886 var integer N3105 := 0;
1887 timer T_3195 := 1.0;
1888 var integer num_poll_recv := 0;
1889
1890 /* Initialize NS/BSSGP side */
1891 f_init_bssgp();
1892 /* Initialize GPRS MS side */
1893 f_init_gprs_ms();
1894 ms := g_ms[0]; /* We only use first MS in this test */
1895
1896 /* Initialize the PCU interface abstraction */
1897 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1898 /* Speedup test: */
1899 info_ind.n3105 := N3105_MAX;
1900 info_ind.t3195 := 1;
1901 f_init_raw(testcasename(), info_ind);
1902
1903 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1904 * MS and retransmitted after the TBF is released and later on created
1905 * (because the MS is reused) */
1906 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1907
1908 /* Establish BSSGP connection to the PCU */
1909 f_bssgp_establish();
1910 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1911
1912 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1913 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1914 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1915
1916 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1917 f_sleep(X2002);
1918
1919 /* Now we go on receiving DL data and not answering RRBP: */
1920 nr := ts_TsTrxBtsNum;
1921 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1922 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1923 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1924 block_nr := nr.blk_nr));
1925 alt {
1926 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1927 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1928 tr_RLCMAC_DATA)) -> value data_msg {
1929 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1930 if (num_poll_recv == 0) {
1931 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1932 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1933 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1934 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1935 } else {
1936 log("Ignoring RRBP ", num_poll_recv);
1937 N3105 := N3105 + 1;
1938 }
1939 num_poll_recv := num_poll_recv + 1;
1940 }
1941
1942 nr := ts_TsTrxBtsNum;
1943 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1944 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1945 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1946 block_nr := nr.blk_nr));
1947 repeat;
1948 }
1949 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
1950 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
1951 */
1952 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1953 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1954 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
1955 if (not T_3195.running) {
1956 T_3195.start;
1957 /* We even send some new data, nothing should be sent to MS */
1958 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1959 }
1960 nr := ts_TsTrxBtsNum;
1961 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1962 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1963 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1964 block_nr := nr.blk_nr));
1965 repeat;
1966 }
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02001967 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001968 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02001969 /* Done in alt, wait for pending RTS initiated previously in
1970 * above case before continuing (expect /* Dummy block): */
1971 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1972 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1973 tr_RLCMAC_DUMMY_CTRL));
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001974 }
1975 [] BTS.receive {
1976 setverdict(fail, "Unexpected BTS message");
1977 f_shutdown(__BFILE__, __LINE__);
1978 }
1979 }
1980
1981 /* after T_3195 timeout, TBF is released */
1982 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1983 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1984
1985 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1986 f_sleep(X2002);
1987 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1988
1989 /* ACK the DL block */
1990 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1991 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1992 f_dl_block_ack_fn(dl_block, dl_fn));
1993
1994 f_shutdown(__BFILE__, __LINE__, final := true);
1995}
1996
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001997/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
1998testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001999 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002000 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002001 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002002 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002003
2004 /* Initialize NS/BSSGP side */
2005 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002006 /* Initialize GPRS MS side */
2007 f_init_gprs_ms();
2008 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002009
2010 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002011 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002012
2013 /* Establish BSSGP connection to the PCU */
2014 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002015 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002016
2017 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002018 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002019
2020 /* Send one UL block (with TLLI since we are in One-Phase Access
2021 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002022 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002023 /* 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 +02002024 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 +02002025 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2026 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002027 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002028
2029 /* Send enough blocks to test whole procedure: Until Nth block
2030 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2031 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002032 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002033 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2034 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002035 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002036
2037 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002038 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 +07002039
2040 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002041}
2042
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002043/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2044testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2045 var RlcmacDlBlock dl_block;
2046 var uint32_t dl_fn, sched_fn;
2047 var octetstring payload;
2048 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002049 var template (value) LlcBlockHdr blk_hdr;
2050 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002051 var integer blk_len;
2052 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002053 var GprsMS ms;
2054
2055 /* Initialize NS/BSSGP side */
2056 f_init_bssgp();
2057 /* Initialize GPRS MS side */
2058 f_init_gprs_ms();
2059 ms := g_ms[0]; /* We only use first MS in this test */
2060
2061 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002062 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002063
2064 /* Establish BSSGP connection to the PCU */
2065 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002066 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002067
2068 /* Establish an Uplink TBF */
2069 f_ms_establish_ul_tbf(ms);
2070
2071 /* Send one UL block (with TLLI since we are in One-Phase Access
2072 contention resoultion) and make sure it is ACKED fine. */
2073 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002074 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2075 more := false, e := true);
2076 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002077 /* 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 +01002078 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2079 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002080 cv := 15,
2081 bsn := ms.ul_tbf.bsn,
2082 blocks := blocks,
2083 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002084 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002085 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002086
2087 /* ACK and check it was received fine */
2088 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2089 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2090 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2091 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002092 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 +02002093
2094 /* Test sending LLC PDUS of incrementing size */
2095 var integer max_size := 49;
2096 for (var integer i := 1; i <= max_size; i := i + 1) {
2097 var integer cv;
2098 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2099 log("Sending DATA.ind with LLC payload size ", i);
2100 if (i < max_size - g_bs_cv_max) {
2101 cv := 15;
2102 } else {
2103 cv := max_size - i;
2104 }
2105
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002106 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2107 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002108 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002109 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2110 more := false, e := true);
2111 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002112 /* 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 +01002113 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2114 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002115 cv := cv,
2116 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002117 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002118 f_ultbf_inc_bsn(ms.ul_tbf);
2119 f_ms_tx_ul_block(ms, ul_data);
2120
2121 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002122 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 +02002123
2124 /* we will receive UL ACK/NACK from time to time, handle it. */
2125 f_rx_rlcmac_dl_block(dl_block, dl_fn);
2126 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
2127 continue;
2128 }
2129 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2130 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2131 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2132 f_shutdown(__BFILE__, __LINE__);
2133 }
2134
2135 log("Rx Packet Uplink ACK / NACK");
2136 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2137 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2138 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2139 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002140
2141 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002142}
2143
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002144function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2145 var octetstring payload;
2146 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002147 var template (value) LlcBlockHdr blk_hdr;
2148 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002149 var integer block_len, max_valid_data_len;
2150 timer T;
2151
2152 block_len := f_rlcmac_cs_mcs2block_len(cs);
2153 /* We need to send with TLLI since we are in One-Phase Access Contenion
2154 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
2155 * indicator, -1 for spare bits octet at the end */
2156 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2157 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 +07002158 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2159 more := false, e := true);
2160 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002161 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2162 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002163 cv := cv,
2164 bsn := ms.ul_tbf.bsn,
2165 blocks := blocks,
2166 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002167 f_ultbf_inc_bsn(ms.ul_tbf);
2168 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2169
2170 T.start(0.5);
2171 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002172 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002173 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2174 f_shutdown(__BFILE__, __LINE__);
2175 }
2176 [] T.timeout {
2177 setverdict(pass);
2178 }
2179 }
2180}
2181/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2182 blocks intentionally contain last byte of data placed in last byte of RLC
2183 containing padding/spare bits, which is incorrect. Spare bits exist and are
2184 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2185 discounting padding in octet" */
2186testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2187 var GprsMS ms;
2188 var integer block_len, max_valid_data_len;
2189
2190 /* Initialize NS/BSSGP side */
2191 f_init_bssgp();
2192 /* Initialize GPRS MS side */
2193 f_init_gprs_ms();
2194 ms := g_ms[0]; /* We only use first MS in this test */
2195
2196 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002197 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002198
2199 /* Establish BSSGP connection to the PCU */
2200 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002201 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002202
2203 /* Establish an Uplink TBF */
2204 f_ms_establish_ul_tbf(ms);
2205
2206 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2207 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2208 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2209
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002210 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002211}
2212
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002213/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2214 * answered, so TBFs for uplink and later for downlink are created.
2215 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002216private 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 +02002217 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002218 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002219 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002220 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002221 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002222
2223 /* Initialize NS/BSSGP side */
2224 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002225 /* Initialize GPRS MS side */
2226 f_init_gprs_ms();
2227 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002228
2229 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002230 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002231
2232 /* Establish BSSGP connection to the PCU */
2233 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002234 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002235
2236 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002237 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002238
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002239 /* Send one UL block (with TLLI since we are in One-Phase Access
2240 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002241 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 +02002242 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2243 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002244 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002245
2246 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002247 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002248
2249 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002250 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2251 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002252
2253 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2254 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002255 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002256
2257 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002258 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2259 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2260 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002261
2262 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002263}
2264
2265/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2266 * answered, so TBFs for uplink and later for downlink are created.
2267 */
2268testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002269 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002270 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002271}
2272
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002273/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2274 * answered, so TBFs for uplink and later for downlink are created.
2275 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002276private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2277 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002278 template (present) CodingScheme exp_ul_cs_mcs := ?,
2279 template (present) CodingScheme exp_dl_cs_mcs := ?)
2280runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002281 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002282 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002283 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002284 var uint32_t sched_fn;
2285 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002286 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002287 var GprsMS ms;
2288
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002289 /* Initialize NS/BSSGP side */
2290 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002291 /* Initialize GPRS MS side */
2292 f_init_gprs_ms();
2293 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002294
2295 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002296 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002297
2298 /* Establish BSSGP connection to the PCU */
2299 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002300 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002301
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002302 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2303 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 +02002304
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002305 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2306 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 +02002307 f_shutdown(__BFILE__, __LINE__);
2308 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002309
2310 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2311 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002312 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002313
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002314 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002315 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 +02002316
2317 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002318 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002319
2320 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002321 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002322 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2323 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002324 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002325 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002326 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002327
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002328 /* PCU acks the UL data after having received CV=0) */
2329 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2330
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002331 /* 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 +02002332 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 +02002333
2334 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002335 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2336 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 +02002337 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002338
2339 f_shutdown(__BFILE__, __LINE__, final := true);
2340}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002341
2342testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002343 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2344 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002345
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002346 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 Pedrol42acafc2020-05-14 15:18:38 +02002347}
2348
2349testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002350 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2351 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002352
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002353 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 Pedrol8dd59fb2020-04-29 15:08:16 +02002354}
2355
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002356testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2357 /* Configure PCU to force two phase access */
2358 g_force_two_phase_access := true;
2359
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002360 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002361 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002362
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002363 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 Pedrol0c0bf872020-05-14 15:50:49 +02002364}
2365
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002366/* Test scenario where SGSN wants to send some data against MS and it is
2367 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2368 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002369private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2370 template (present) CodingScheme exp_cs_mcs := ?)
2371runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002372 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002373 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002374 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002375 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002376 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002377
2378 /* Initialize NS/BSSGP side */
2379 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002380 /* Initialize GPRS MS side */
2381 f_init_gprs_ms();
2382 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002383
2384 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002385 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002386
2387 /* Establish BSSGP connection to the PCU */
2388 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002389 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002390
2391 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002392 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2393 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002394
2395 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2396 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002397 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002398
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002399 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002400 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2401 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 +02002402 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002403
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002404 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002405 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002406
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002407 /* Send one UL block (with TLLI since we are in One-Phase Access
2408 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002409 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002410 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2411 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002412 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002413
2414 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002415 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002416
2417 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002418}
2419
2420testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002421 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002422 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2423}
2424
2425/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2426/* information about the MS */
2427testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002428 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002429 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002430}
2431
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002432/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2433 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2434 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2435 * be transferred).
2436 */
2437testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002438 var RlcmacDlBlock dl_block;
2439 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002440 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002441 var octetstring total_payload;
2442 var octetstring payload;
2443 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002444 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002445 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002446 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002447
2448 /* Initialize NS/BSSGP side */
2449 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002450 /* Initialize GPRS MS side */
2451 f_init_gprs_ms();
2452 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002453
2454 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002455 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002456
2457 /* Establish BSSGP connection to the PCU */
2458 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002459 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002460
2461 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002462 f_ms_establish_ul_tbf(ms);
2463 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002464
2465 /* Send one UL block (with TLLI since we are in One-Phase Access
2466 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002467 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 +02002468 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 +02002469
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002470 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2471 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002472 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002473 total_payload := payload;
2474
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002475 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2476
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002477 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002478 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002479 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002480 total_payload := total_payload & payload;
2481
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002482 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002483 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002484 total_payload := total_payload & payload;
2485
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002486 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002487 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 +02002488 total_payload := total_payload & lost_payload;
2489
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002490 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002491 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002492 total_payload := total_payload & payload;
2493
2494 /* 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 +02002495 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002496
2497 /* On CV=0, we'll receive a UL ACK asking about missing block */
2498 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2499 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002500 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2501 tfi := tfi,
2502 cv := 15,
2503 bsn := 3,
2504 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002505 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002506
2507 /* Now final ack is recieved */
2508 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2509 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002510 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002511
2512 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002513 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 +07002514
2515 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002516}
2517
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002518/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2519 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2520 * timeout occurs (specified by sent RRBP on DL block). */
2521testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002522 var RlcmacDlBlock dl_block;
2523 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002524 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002525 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002526
2527 /* Initialize NS/BSSGP side */
2528 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002529 /* Initialize GPRS MS side */
2530 f_init_gprs_ms();
2531 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002532
2533 /* Initialize the PCU interface abstraction */
2534 f_init_raw(testcasename());
2535
2536 /* Establish BSSGP connection to the PCU */
2537 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002538 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002539
2540 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002541 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2542 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002543
2544 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2545 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002546 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002547
2548 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2549 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2550 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002551 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002552
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002553 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2554 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002555 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002556
2557 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002558 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2559 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2560 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002561
2562 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002563}
2564
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002565/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2566testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2567 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2568 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002569 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002570 var RlcmacDlBlock dl_block;
2571 var uint32_t ack_fn;
2572 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002573 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002574 timer T := 5.0;
2575
2576 /* Initialize NS/BSSGP side */
2577 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002578 /* Initialize GPRS MS side */
2579 f_init_gprs_ms();
2580 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002581
2582 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002583 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002584
Daniel Willmann535aea62020-09-21 13:27:08 +02002585 f_statsd_reset();
2586
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002587 /* Establish BSSGP connection to the PCU */
2588 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002589 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002590
2591 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002592 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2593 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002594
2595 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2596 f_sleep(X2002);
2597
2598 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2599 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002600 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002601
2602 /* TDMA frame number on which we are supposed to send the ACK */
2603 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2604
2605 /* SGSN sends more blocks during the indicated RRBP */
2606 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2607 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002608 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002609
2610 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2611
2612 /* Make sure this block has the same TFI as was assigned
2613 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002614 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002615 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2616 dl_block.data.mac_hdr.hdr_ext.tfi);
2617 f_shutdown(__BFILE__, __LINE__);
2618 }
2619
2620 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002621 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002622
2623 /* Break if this is the end of RRBP */
2624 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002625 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002626 break;
2627 }
2628 }
2629
2630 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002631 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 +07002632
2633 /* Make sure that the next block (after the Ack) is dummy */
2634 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2635
Daniel Willmann535aea62020-09-21 13:27:08 +02002636 var StatsDExpects expect := {
2637 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2638 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2639 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2640 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2641 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002642 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002643 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2644 };
2645 f_statsd_expect(expect);
2646
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002647 f_shutdown(__BFILE__, __LINE__, final := true);
2648}
2649
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002650/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2651 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2652 * Check "3GPP TS 44.060" Annex B. */
2653testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2654 var RlcmacDlBlock dl_block;
2655 var octetstring dataA := f_rnd_octstring(20);
2656 var octetstring dataB := f_rnd_octstring(13);
2657 var octetstring dataC := f_rnd_octstring(3);
2658 var octetstring dataD := f_rnd_octstring(12);
2659 var uint32_t sched_fn;
2660 var GprsMS ms;
2661 var template (value) RlcmacUlBlock ul_data;
2662
2663 /* Initialize NS/BSSGP side */
2664 f_init_bssgp();
2665 /* Initialize GPRS MS side */
2666 f_init_gprs_ms();
2667 ms := g_ms[0]; /* We only use first MS in this test */
2668
2669 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002670 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002671
2672 /* Establish BSSGP connection to the PCU */
2673 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002674 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002675
2676 /* Establish an Uplink TBF */
2677 f_ms_establish_ul_tbf(ms);
2678
2679 /* Summary of what's transmitted:
2680 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2681 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2682 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2683 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2684 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2685 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2686 */
2687
2688 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002689 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2690 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002691 cv := 3,
2692 bsn := ms.ul_tbf.bsn,
2693 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2694 tlli := ms.tlli);
2695 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2696 * RLCMAC block being sent. */
2697 ul_data.data.mac_hdr.e := true;
2698 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002699 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002700
2701 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002702 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2703 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002704 cv := 2,
2705 bsn := ms.ul_tbf.bsn,
2706 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2707 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2708 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2709 },
2710 tlli := ms.tlli);
2711 f_ultbf_inc_bsn(ms.ul_tbf);
2712 f_ms_tx_ul_block(ms, ul_data);
2713
2714 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002715 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 +02002716
2717 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002718 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2719 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002720 cv := 1,
2721 bsn := ms.ul_tbf.bsn,
2722 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2723 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2724 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2725 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2726 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2727 },
2728 tlli := ms.tlli);
2729 f_ultbf_inc_bsn(ms.ul_tbf);
2730 f_ms_tx_ul_block(ms, ul_data);
2731
2732 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002733 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2734 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 +02002735
2736 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002737 ul_data := t_RLCMAC_UL_DATA_TLLI(
2738 cs := CS_1,
2739 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002740 cv := 0,
2741 bsn := ms.ul_tbf.bsn,
2742 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2743 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2744 },
2745 tlli := ms.tlli);
2746 f_ultbf_inc_bsn(ms.ul_tbf);
2747 f_ms_tx_ul_block(ms, ul_data);
2748
2749 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002750 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 +02002751
2752 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2753 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2754 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2755
2756 f_shutdown(__BFILE__, __LINE__, final := true);
2757}
2758
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002759/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2760 * ACK/NACK is not answered */
2761testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2762 var RlcmacDlBlock dl_block;
2763 var octetstring data1 := f_rnd_octstring(200);
2764 var octetstring data2 := f_rnd_octstring(10);
2765 var uint32_t dl_fn;
2766 var GprsMS ms;
2767 var template (value) TsTrxBtsNum nr;
2768 var BTS_PDTCH_Block data_msg;
2769
2770 /* Initialize NS/BSSGP side */
2771 f_init_bssgp();
2772 /* Initialize GPRS MS side */
2773 f_init_gprs_ms();
2774 ms := g_ms[0]; /* We only use first MS in this test */
2775
2776 /* Initialize the PCU interface abstraction */
2777 f_init_raw(testcasename())
2778
2779 /* Establish BSSGP connection to the PCU */
2780 f_bssgp_establish();
2781 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2782
2783 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2784 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2785 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2786
2787 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2788 f_sleep(X2002);
2789
2790 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2791 while (true) {
2792 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2793
2794 /* Keep Ack/Nack description updated (except for last BSN) */
2795 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2796
2797 if (f_dl_block_rrbp_valid(dl_block)) {
2798 /* Don't transmit DL ACK here on purpose ignore it */
2799 break;
2800 }
2801 }
2802
2803 /* PCU starts whole process again */
2804 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2805
2806 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2807 f_sleep(X2002);
2808
2809 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
2810 /* DL data), after that we receive only DUMMY blocks so we are done */
2811 var boolean data_received := false;
2812 nr := ts_TsTrxBtsNum;
2813 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2814 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2815 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2816 block_nr := nr.blk_nr));
2817 alt {
2818 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2819 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2820 tr_RLCMAC_DUMMY_CTRL)) { /* done */ }
2821 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2822 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2823 tr_RLCMAC_DATA)) -> value data_msg {
2824 data_received := true;
2825 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
2826 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
2827 log("Received FINAL_ACK");
2828 ms.dl_tbf.acknack_desc.final_ack := '1'B;
2829 }
2830 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
2831 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2832 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
2833 }
2834 nr := ts_TsTrxBtsNum;
2835 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2836 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2837 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2838 block_nr := nr.blk_nr));
2839 repeat;
2840 }
2841 [] BTS.receive {
2842 setverdict(fail, "Unexpected BTS message");
2843 f_shutdown(__BFILE__, __LINE__);
2844 }
2845 }
2846
2847 f_shutdown(__BFILE__, __LINE__, final := true);
2848}
2849
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002850/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
2851testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002852 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002853 var octetstring data := f_rnd_octstring(10);
2854 var PacketDlAssign dl_tbf_ass;
2855 var RlcmacDlBlock dl_block;
2856 var uint32_t poll_fn;
2857 var uint32_t sched_fn;
2858 var GprsMS ms;
2859 timer T := 5.0;
2860
2861 /* Initialize NS/BSSGP side */
2862 f_init_bssgp();
2863 /* Initialize GPRS MS side */
2864 f_init_gprs_ms();
2865 ms := g_ms[0]; /* We only use first MS in this test */
2866
2867 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01002868 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
2869 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002870
2871 /* Initialize the PCU interface abstraction */
2872 f_init_raw(testcasename(), info_ind);
2873
2874 /* Establish BSSGP connection to the PCU */
2875 f_bssgp_establish();
2876 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2877
2878 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
2879 through PDCH (no multiblock assignment possible through PCH) */
2880 f_ms_establish_ul_tbf(ms);
2881
2882 /* Send one UL block (with TLLI since we are in One-Phase Access
2883 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002884 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
2885 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002886 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2887 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2888
2889 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
2890 var MultislotCap_GPRS_BSSGP mscap_gprs := {
2891 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2892 gprsextendeddynalloccap := '0'B
2893 };
2894 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
2895 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2896 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
2897 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
2898 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
2899 f_shutdown(__BFILE__, __LINE__);
2900 }
2901 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2902
2903 f_shutdown(__BFILE__, __LINE__, final := true);
2904}
2905
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002906testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002907 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002908 var RlcmacDlBlock dl_block;
2909 var octetstring data := f_rnd_octstring(10);
2910 var PollFnCtx pollctx;
2911 var uint32_t sched_fn;
2912 var GprsMS ms;
2913
2914 var MultislotCap_GPRS mscap_gprs := {
2915 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2916 gprsextendeddynalloccap := '0'B
2917 };
2918 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
2919
2920
2921 /* Initialize NS/BSSGP side */
2922 f_init_bssgp();
2923 /* Initialize GPRS MS side */
2924 f_init_gprs_ms();
2925 ms := g_ms[0]; /* We only use first MS in this test */
2926
2927 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01002928 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
2929 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002930
2931 /* Initialize the PCU interface abstraction */
2932 f_init_raw(testcasename(), info_ind);
2933
2934 /* Establish BSSGP connection to the PCU */
2935 f_bssgp_establish();
2936 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2937
2938 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
2939 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
2940
2941 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
2942 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
2943
2944 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2945 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
2946 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
2947 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
2948 f_shutdown(__BFILE__, __LINE__);
2949 }
2950 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2951
2952 f_shutdown(__BFILE__, __LINE__, final := true);
2953}
2954
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01002955testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
2956 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
2957 var RlcmacDlBlock dl_block;
2958 var octetstring data := f_rnd_octstring(10);
2959 var PollFnCtx pollctx;
2960 var uint32_t sched_fn;
2961 var GprsMS ms;
2962
2963 var MultislotCap_GPRS mscap_gprs := {
2964 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2965 gprsextendeddynalloccap := '0'B
2966 };
2967 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
2968
2969
2970 /* Initialize NS/BSSGP side */
2971 f_init_bssgp();
2972 /* Initialize GPRS MS side */
2973 f_init_gprs_ms();
2974 ms := g_ms[0]; /* We only use first MS in this test */
2975
2976 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01002977 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
2978 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01002979
2980 /* Initialize the PCU interface abstraction */
2981 f_init_raw(testcasename(), info_ind);
2982
2983 /* Establish BSSGP connection to the PCU */
2984 f_bssgp_establish();
2985 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2986
2987 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
2988 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
2989
2990 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
2991 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
2992 f_shutdown(__BFILE__, __LINE__);
2993 }
2994
2995 f_shutdown(__BFILE__, __LINE__, final := true);
2996}
2997
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002998/* Test scenario where MS wants to request a new TBF once the current one is
2999 * ending, by means of sending a Packet Resource Request on ul slot provided by
3000 * last Pkt Ul ACK's RRBP.
3001 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3002testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003003 var RlcmacDlBlock dl_block;
3004 var octetstring data := f_rnd_octstring(10);
3005 var uint32_t sched_fn;
3006 var uint32_t dl_fn;
3007 var template RlcmacDlBlock acknack_tmpl;
3008 var GprsMS ms;
3009
3010 /* Initialize NS/BSSGP side */
3011 f_init_bssgp();
3012 /* Initialize GPRS MS side */
3013 f_init_gprs_ms();
3014 ms := g_ms[0]; /* We only use first MS in this test */
3015
3016 /* Initialize the PCU interface abstraction */
3017 f_init_raw(testcasename());
3018
3019 /* Establish BSSGP connection to the PCU */
3020 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003021 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003022
3023 /* Establish an Uplink TBF */
3024 f_ms_establish_ul_tbf(ms);
3025
3026 /* Send one UL block (with TLLI since we are in One-Phase Access
3027 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003028 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 +02003029
3030 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003031 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003032
3033 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3034 tr_UlAckNackGprs(ms.tlli,
3035 tr_AckNackDescription(final_ack := '1'B),
3036 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3037 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3038
3039 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3040
3041 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003042 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 +07003043 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003044 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3045 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3046
3047 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3048 and make sure it is ACKED fine */
3049 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
3050
3051 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003052 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003053
3054 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3055 /* ACK the ACK */
3056 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3057
3058 f_shutdown(__BFILE__, __LINE__, final := true);
3059}
3060
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003061/* Test CS paging over the BTS<->PCU socket.
3062 * 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.
3063 * Paging should be send on the PACCH.
3064 *
3065 * 1. Send a Paging Request over PCU socket.
3066 * 2. Send a Ready-To-Send message over PCU socket
3067 * 3. Expect a Paging Frame
3068 */
3069testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003070 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003071 var MobileIdentityLV mi;
3072 var octetstring mi_enc_lv;
3073 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003074 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003075
3076 /* Initialize NS/BSSGP side */
3077 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003078 /* Initialize GPRS MS side */
3079 f_init_gprs_ms();
3080 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003081
3082 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003083 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003084
3085 /* Establish BSSGP connection to the PCU */
3086 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003087 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003088
3089 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003090 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003091
3092 /* build mobile Identity */
3093 mi := valueof(ts_MI_IMSI_LV(imsi));
3094 mi_enc_lv := enc_MobileIdentityLV(mi);
3095 /* Send paging request */
3096 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3097 sapi :=PCU_IF_SAPI_PDTCH));
3098
3099 /* Receive it on BTS side towards MS */
3100 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3101
3102 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003103 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3104 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3105 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3106 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003107
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003108 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003109}
3110
3111/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3112 */
3113private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3114runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003115 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003116 var hexstring imsi := f_gen_imsi(42);
3117 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003118 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003119
3120 /* Initialize NS/BSSGP side */
3121 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003122 /* Initialize GPRS MS side */
3123 f_init_gprs_ms();
3124 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003125
3126 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003127 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003128
3129 /* Establish BSSGP connection to the PCU */
3130 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003131 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003132
3133 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003134 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003135
3136 /* Send paging request with or without TMSI */
3137 if (use_ptmsi) {
3138 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3139 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3140 } else {
3141 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3142 }
3143
3144 /* Receive it on BTS side towards MS */
3145 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3146
3147 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003148 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003149 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003150 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3151 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3152 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003153 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003154 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3155 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3156 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003157 }
3158
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003159 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003160}
3161
3162testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3163 f_tc_paging_cs_from_sgsn(0, true);
3164}
3165
3166testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3167 f_tc_paging_cs_from_sgsn(0);
3168}
3169
3170testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003171 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003172}
3173
3174/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3175 */
3176private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3177runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003178 var integer imsi_suff_tx := 423;
3179 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003180 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003181
3182 /* Initialize NS/BSSGP side */
3183 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003184 /* Initialize GPRS MS side */
3185 f_init_gprs_ms();
3186 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003187
3188 /* Initialize the PCU interface abstraction */
3189 f_init_raw(testcasename());
3190
Oliver Smith61b4e732021-07-22 08:14:29 +02003191 f_statsd_reset();
3192
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003193 /* Establish BSSGP connection to the PCU */
3194 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003195 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003196
3197 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3198 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3199 if (use_ptmsi) {
3200 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3201 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3202 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3203 } else {
3204 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3205 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3206 }
3207
Oliver Smith61b4e732021-07-22 08:14:29 +02003208 if (mp_osmo_pcu_newer_than_0_9_0) {
3209 var StatsDExpects expect := {
Oliver Smith36d95d82021-08-06 22:01:53 +02003210 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3211 /* After the PCU receives the paging request from SGSN,
3212 * and it doesn't have any errors, PCU sends it to the
3213 * BTS to do paging over PCH. */
3214 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
Oliver Smith61b4e732021-07-22 08:14:29 +02003215 };
3216 f_statsd_expect(expect);
3217 }
3218
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003219 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003220}
3221
3222testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3223 f_tc_paging_ps_from_sgsn(0, true);
3224}
3225
3226testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3227 f_tc_paging_ps_from_sgsn(0);
3228}
3229
3230testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003231 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003232}
3233
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003234/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3235testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3236 var RlcmacDlBlock dl_block;
3237 var octetstring data := f_rnd_octstring(10);
3238 var uint32_t sched_fn;
3239 var uint32_t dl_fn;
3240 var GprsMS ms;
3241
3242 /* Initialize NS/BSSGP side */
3243 f_init_bssgp();
3244 /* Initialize GPRS MS side */
3245 f_init_gprs_ms();
3246 ms := g_ms[0]; /* We only use first MS in this test */
3247
3248 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003249 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003250
Daniel Willmann535aea62020-09-21 13:27:08 +02003251 f_statsd_reset();
3252
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003253 /* Establish BSSGP connection to the PCU */
3254 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003255 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003256
3257 /* Establish an Uplink TBF */
3258 f_ms_establish_ul_tbf(ms);
3259
3260 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003261 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 +02003262 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3263 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3264 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3265
3266 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003267 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003268
3269 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3270 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3271 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3272
3273 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3274 f_sleep(X2002);
3275 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3276
3277 /* ACK the DL block */
3278 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3279 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3280 f_dl_block_ack_fn(dl_block, dl_fn));
3281
Daniel Willmann535aea62020-09-21 13:27:08 +02003282 var StatsDExpects expect := {
3283 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3284 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3285 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3286 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003287 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003288 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003289 };
3290 f_statsd_expect(expect);
3291
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003292 f_shutdown(__BFILE__, __LINE__, final := true);
3293}
3294
3295/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3296testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3297 var RlcmacDlBlock dl_block;
3298 var octetstring data := f_rnd_octstring(10);
3299 var uint32_t sched_fn;
3300 var uint32_t dl_fn;
3301 var GprsMS ms;
3302
3303 /* Initialize NS/BSSGP side */
3304 f_init_bssgp();
3305 /* Initialize GPRS MS side */
3306 f_init_gprs_ms();
3307 ms := g_ms[0]; /* We only use first MS in this test */
3308
3309 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003310 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003311
3312 /* Establish BSSGP connection to the PCU */
3313 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003314 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003315
3316 /* Establish an Uplink TBF */
3317 f_ms_establish_ul_tbf(ms);
3318
3319 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003320 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 +02003321 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3322 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3323 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3324
3325 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003326 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003327
3328 /* Now SGSN sends some DL data with an invalid IMSI */
3329 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3330
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003331 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003332
3333 /* TODO: make sure no data is sent over PCU -> MS */
3334
3335 f_shutdown(__BFILE__, __LINE__, final := true);
3336}
3337
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003338private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3339 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3340 var octetstring data := f_rnd_octstring(6);
3341 var RlcmacDlBlock dl_block;
3342 var GprsMS ms;
3343 var uint32_t fn;
3344
3345 /* Initialize NS/BSSGP side */
3346 f_init_bssgp();
3347 /* Initialize GPRS MS side */
3348 f_init_gprs_ms();
3349 ms := g_ms[0]; /* We only use first MS in this test */
3350
3351 /* Initialize the PCU interface abstraction */
3352 f_init_raw(testcasename());
3353
3354 /* Establish BSSGP connection to the PCU */
3355 f_bssgp_establish();
3356 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3357
3358 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3359 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3360 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3361
3362 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3363 f_sleep(X2002);
3364
3365 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3366 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3367
3368 if (ischosen(dl_block.data_egprs)) {
3369 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3370 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3371 f_shutdown(__BFILE__, __LINE__);
3372 }
3373 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3374 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3375 f_shutdown(__BFILE__, __LINE__);
3376 }
3377 if (not match(dl_block.data_egprs.blocks[1].payload,
3378 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3379 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3380 f_shutdown(__BFILE__, __LINE__);
3381 }
3382 } else if (lengthof(dl_block.data.blocks) > 1) {
3383 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3384 f_shutdown(__BFILE__, __LINE__);
3385 }
3386
3387 f_shutdown(__BFILE__, __LINE__, final := true);
3388}
3389
3390/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3391 * containing llc data. See OS#4849 */
3392testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3393 f_tc_dl_data_no_llc_ui_dummy(omit);
3394}
3395
3396/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3397 * containing llc data. See OS#4849 */
3398testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003399 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003400}
3401
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003402private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003403 template GsmRrMessage t_imm_ass := ?,
3404 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003405runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003406 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003407 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003408
3409 ra11 := enc_EGPRSPktChRequest2uint(req);
3410 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
3411
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07003412 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003413 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003414 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003415 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003416 }
3417
3418 setverdict(pass);
3419}
3420
3421testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
3422 var template GsmRrMessage imm_ass;
3423 var template IaRestOctets rest;
3424 var template EgprsUlAss ul_ass;
3425
3426 /* Initialize the PCU interface abstraction */
3427 f_init_raw(testcasename());
3428
3429 var EGPRSPktChRequest req := {
3430 /* NOTE: other fields are set in the loop */
3431 signalling := { tag := '110011'B }
3432 };
3433
3434 for (var integer i := 0; i < 6; i := i + 1) {
3435 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3436 req.signalling.random_bits := ext_ra;
3437
3438 /* For signalling, do we expect Multiblock UL TBF Assignment? */
3439 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3440 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3441 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3442
3443 f_TC_egprs_pkt_chan_req(req, imm_ass);
3444 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003445
3446 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003447}
3448
3449testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
3450 var template GsmRrMessage imm_ass;
3451 var template IaRestOctets rest;
3452 var template EgprsUlAss ul_ass;
3453
3454 /* Initialize the PCU interface abstraction */
3455 f_init_raw(testcasename());
3456
3457 var EGPRSPktChRequest req := {
3458 /* NOTE: other fields are set in the loop */
3459 one_phase := { tag := '0'B }
3460 };
3461
3462 for (var integer i := 0; i < 6; i := i + 1) {
3463 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3464 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
3465 var BIT2 priority := substr(ext_ra, 0, 2);
3466 var BIT3 rand := substr(ext_ra, 2, 3);
3467
3468 req.one_phase.multislot_class := mslot_class;
3469 req.one_phase.priority := priority;
3470 req.one_phase.random_bits := rand;
3471
3472 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
3473 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
3474 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3475 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3476
3477 f_TC_egprs_pkt_chan_req(req, imm_ass);
3478 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003479
3480 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003481}
3482
3483testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
3484 var template GsmRrMessage imm_ass;
3485 var template IaRestOctets rest;
3486 var template EgprsUlAss ul_ass;
3487
3488 /* Initialize the PCU interface abstraction */
3489 f_init_raw(testcasename());
3490
3491 var EGPRSPktChRequest req := {
3492 /* NOTE: other fields are set in the loop */
3493 two_phase := { tag := '110000'B }
3494 };
3495
3496 for (var integer i := 0; i < 6; i := i + 1) {
3497 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3498 var BIT2 priority := substr(ext_ra, 0, 2);
3499 var BIT3 rand := substr(ext_ra, 2, 3);
3500
3501 req.two_phase.priority := priority;
3502 req.two_phase.random_bits := rand;
3503
3504 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
3505 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3506 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3507 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3508
3509 f_TC_egprs_pkt_chan_req(req, imm_ass);
3510 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003511
3512 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003513}
3514
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003515private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
3516 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003517 PCUIF_BurstType bt := BURST_TYPE_1,
3518 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003519runs on RAW_PCU_Test_CT {
3520 var template ReqRefWaitInd tr_ref;
3521 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003522
3523 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
3524 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
3525 ra := bit2int(ra11), is_11bit := 1,
3526 burst_type := bt, fn := fn,
3527 arfcn := 871));
3528
3529 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07003530 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003531
3532 /* Just to have a short-name reference to the actual message */
3533 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
3534
3535 /* Make sure that Request Reference list contains at least one entry
3536 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003537 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07003538 if (not match(iar.payload, { *, tr_ref, * })) {
3539 setverdict(fail, "Request Reference list does not match");
3540 f_shutdown(__BFILE__, __LINE__);
3541 }
3542
3543 /* Match Feature Indicator (must indicate PS domain) */
3544 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
3545 setverdict(fail, "Feature Indicator does not match");
3546 f_shutdown(__BFILE__, __LINE__);
3547 }
3548
3549 /* Match IAR Rest Octets */
3550 if (not match(iar.rest_octets, rest)) {
3551 setverdict(fail, "IAR Rest Octets does not match: ",
3552 iar.rest_octets, " vs expected ", rest);
3553 f_shutdown(__BFILE__, __LINE__);
3554 }
3555
3556 setverdict(pass);
3557}
3558
3559/* Verify the contents of RR Immediate Assignment Reject message and its
3560 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
3561testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
3562 var template IARRestOctets rest;
3563 var BIT5 ext_ra;
3564
3565 /* Initialize the PCU interface abstraction */
3566 f_init_raw(testcasename());
3567
3568 for (var integer i := 0; i < 6; i := i + 1) {
3569 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
3570 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
3571
3572 /* Intentionally incorrect message (see table 11.2.5a.2) */
3573 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
3574 }
3575
3576 f_shutdown(__BFILE__, __LINE__, final := true);
3577}
3578
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07003579/* At the moment, the IUT does not support any emergency services. Make sure
3580 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
3581testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
3582 var template IARRestOctets rest;
3583 var BIT5 ext_ra;
3584 var BIT11 ra11;
3585
3586 /* Initialize the PCU interface abstraction */
3587 f_init_raw(testcasename());
3588
3589 var EGPRSPktChRequest req := {
3590 /* NOTE: other fields are set in the loop */
3591 emergency := { tag := '110111'B }
3592 };
3593
3594 for (var integer i := 0; i < 6; i := i + 1) {
3595 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
3596 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
3597
3598 req.emergency.random_bits := ext_ra;
3599 ra11 := enc_EGPRSPktChRequest2bits(req);
3600
3601 /* Intentionally incorrect message (see table 11.2.5a.2) */
3602 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
3603 }
3604
3605 f_shutdown(__BFILE__, __LINE__, final := true);
3606}
3607
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07003608/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
3609testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01003610 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07003611 var template IARRestOctets rest;
3612 var BIT11 ra11;
3613
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01003614 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003615 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07003616
3617 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003618 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
3619 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01003620
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07003621 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01003622 f_init_raw(testcasename(), info_ind);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07003623
3624 var EGPRSPktChRequest req := {
3625 one_phase := {
3626 tag := '0'B,
3627 multislot_class := '10101'B,
3628 priority := '01'B,
3629 random_bits := '101'B
3630 }
3631 };
3632
3633 /* We send 7 requests, the IUT gives us all available USFs (0..6).
3634 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
3635 for (var integer i := 0; i < 7; i := i + 1) {
3636 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
3637 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
3638 }
3639
3640 ra11 := enc_EGPRSPktChRequest2bits(req);
3641 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
3642
3643 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02003644 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07003645
3646 f_shutdown(__BFILE__, __LINE__, final := true);
3647}
3648
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003649/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07003650private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003651return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07003652 /* Pick a random MA length in range 2 .. max_ma_len */
3653 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
3654
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003655 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
3656 hsn := f_rnd_int(63),
3657 maio := f_rnd_int(63),
3658 ma := f_rnd_bitstring(ma_len));
3659}
3660
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003661private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
3662 in GsmRrMessage rr_msg)
3663{
3664 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003665 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003666
3667 var template PacketChannelDescription tr_pkt_chan_desc := {
3668 channel_Type_spare := ?,
3669 tn := ?,
3670 tsc := ts.tsc,
3671 presence := '1'B,
3672 zero := omit,
3673 one := {
3674 maio := ts.maio,
3675 hsn := ts.hsn
3676 }
3677 };
3678
3679 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
3680 setverdict(fail, "Packet Channel Description does not match: ",
3681 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
3682 }
3683
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07003684 /* Mobile Allocation is expected to be octet-aligned */
3685 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
3686 var template MobileAllocationLV tr_ma := {
3687 len := ma_oct_len, /* in bytes */
3688 ma := substr(ts.ma, 0, ma_oct_len * 8)
3689 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003690
3691 if (not match(ia.mobile_allocation, tr_ma)) {
3692 setverdict(fail, "Mobile Allocation does not match: ",
3693 ia.mobile_allocation, " vs ", tr_ma);
3694 }
3695
3696 setverdict(pass);
3697}
3698
3699/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
3700testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003701 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003702 var GprsMS ms := valueof(t_GprsMS_def);
3703
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003704 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003705 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003706
3707 /* Initialize the PCU interface abstraction */
3708 f_init_raw(testcasename(), info_ind);
3709
3710 /* EGPRS Packet Channel Request (cause=Signalling) */
3711 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
3712
3713 /* Establish an Uplink EGPRS TBF */
3714 f_ms_establish_ul_tbf(ms);
3715
3716 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
3717 f_shutdown(__BFILE__, __LINE__, final := true);
3718}
3719
3720/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
3721testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003722 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003723 var GprsMS ms := valueof(t_GprsMS_def);
3724
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003725 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003726 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003727
3728 /* Initialize the PCU interface abstraction */
3729 f_init_raw(testcasename(), info_ind);
3730
3731 /* Establish an Uplink TBF */
3732 f_ms_establish_ul_tbf(ms);
3733
3734 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
3735 f_shutdown(__BFILE__, __LINE__, final := true);
3736}
3737
3738/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
3739testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003740 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003741 var GprsMS ms := valueof(t_GprsMS_def);
3742
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003743 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003744 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003745
3746 /* Initialize NS/BSSGP side */
3747 f_init_bssgp();
3748
3749 /* Initialize the PCU interface abstraction */
3750 f_init_raw(testcasename(), info_ind);
3751
3752 /* Establish BSSGP connection to the PCU */
3753 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003754 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003755
3756 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3757 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
3758 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3759
3760 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
3761 f_shutdown(__BFILE__, __LINE__, final := true);
3762}
3763
3764private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
3765 in FrequencyParameters fp)
3766{
3767 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003768 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003769
3770 /* Table 12.8.1: Frequency Parameters information elements */
3771 var template FrequencyParameters tr_fp := {
3772 tsc := ts.tsc,
3773 presence := '10'B, /* Direct encoding 1 */
3774 arfcn := omit,
3775 indirect := omit,
3776 direct1 := {
3777 maio := ts.maio,
3778 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
3779 mobile_allocation := {
3780 hsn := ts.hsn,
3781 rfl_number_list_present := '0'B,
3782 rfl_number_list := omit,
3783 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07003784 ma_length := ts.ma_bit_len,
3785 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003786 }
3787 },
3788 direct2 := omit
3789 };
3790
3791 if (not match(fp, tr_fp)) {
3792 setverdict(fail, "Frequency Parameters IE does not match: ",
3793 fp, " vs ", tr_fp);
3794 }
3795
3796 setverdict(pass);
3797}
3798
3799/* Make sure that Packet Uplink Assignment contains hopping parameters */
3800testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003801 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003802 var GprsMS ms := valueof(t_GprsMS_def);
3803 var uint32_t poll_fn;
3804
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003805 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003806 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003807
3808 /* Initialize the PCU interface abstraction */
3809 f_init_raw(testcasename(), info_ind);
3810
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003811 /* Single block (two phase) packet access */
3812 var uint16_t ra := bit2int(chan_req_sb);
3813 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
3814
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003815 /* Establish an Uplink TBF */
3816 f_ms_establish_ul_tbf(ms);
3817
3818 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003819 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
3820 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003821
3822 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01003823 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
3824 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003825
3826 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
3827 var template (omit) FrequencyParameters fp;
3828 if (ua.is_egprs == '1'B) {
3829 fp := ua.egprs.freq_par;
3830 } else {
3831 fp := ua.gprs.freq_par;
3832 }
3833
3834 /* This is an optional IE, so it's worth to check its presence */
3835 if (istemplatekind(fp, "omit")) {
3836 setverdict(fail, "Frequency Parameters IE is not present");
3837 f_shutdown(__BFILE__, __LINE__);
3838 }
3839
3840 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
3841 f_shutdown(__BFILE__, __LINE__, final := true);
3842}
3843
3844/* Make sure that Packet Downlink Assignment contains hopping parameters */
3845testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003846 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003847 var octetstring data := f_rnd_octstring(10);
3848 var GprsMS ms := valueof(t_GprsMS_def);
3849 var RlcmacDlBlock dl_block;
3850 var uint32_t poll_fn;
3851
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003852 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003853 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003854
3855 /* Initialize NS/BSSGP side */
3856 f_init_bssgp();
3857
3858 /* Initialize the PCU interface abstraction */
3859 f_init_raw(testcasename(), info_ind);
3860
3861 /* Establish BSSGP connection to the PCU */
3862 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003863 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003864
3865 /* Establish an Uplink TBF */
3866 f_ms_establish_ul_tbf(ms);
3867
3868 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003869 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 +07003870
3871 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3872 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
3873 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
3874
3875 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
3876 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3877
3878 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01003879 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
3880 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003881
3882 /* This is an optional IE, so it's worth to check its presence */
3883 if (not ispresent(da.freq_par)) {
3884 setverdict(fail, "Frequency Parameters IE is not present");
3885 f_shutdown(__BFILE__, __LINE__);
3886 }
3887
3888 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
3889 f_shutdown(__BFILE__, __LINE__, final := true);
3890}
3891
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07003892/* Check if the IUT handles subsequent INFO.ind messages */
3893testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01003894 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01003895 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07003896
3897 /* Initialize the PCU interface abstraction */
3898 f_init_raw(testcasename(), info_ind);
3899
3900 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
3901 for (var integer i := 0; i < 16; i := i + 1) {
3902 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01003903 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07003904 }
3905
3906 f_shutdown(__BFILE__, __LINE__, final := true);
3907}
3908
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003909/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
3910testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
3911 var PCUIF_info_ind info_ind;
3912 var integer i;
3913 const integer num_ms := 8;
3914
3915 /* Initialize NS/BSSGP side */
3916 f_init_bssgp();
3917 /* Initialize GPRS MS side */
3918 f_init_gprs_ms(num_ms);
3919
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003920 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003921 /* Only the 3 first TRX are enabled. The enabled ones all have same
3922 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003923 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
3924 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
3925 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
3926 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003927
3928 /* Initialize the PCU interface abstraction */
3929 f_init_raw(testcasename(), info_ind);
3930
3931 /* Establish BSSGP connection to the PCU */
3932 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07003933 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003934
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07003935 /* Establish an Uplink TBF for each GprsMS instance */
3936 f_multi_ms_establish_tbf(do_activate := false);
3937
3938 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003939 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003940 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01003941 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003942 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003943 f_shutdown(__BFILE__, __LINE__);
3944 }
3945 }
3946
3947 f_shutdown(__BFILE__, __LINE__, final := true);
3948}
3949
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003950/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
3951 * downgraded to CS1-4 so that GPRS can read the USF).
3952 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
3953 */
3954testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
3955 var PCUIF_info_ind info_ind;
3956 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
3957 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003958 var uint32_t sched_fn, dl_fn, ack_fn;
3959 var octetstring data := f_rnd_octstring(10);
3960 var RlcmacDlBlock dl_block;
3961 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01003962 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003963 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
3964 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
3965
3966 /* Initialize NS/BSSGP side */
3967 f_init_bssgp();
3968 /* Initialize GPRS MS side */
3969 f_init_gprs_ms(num_ms);
3970
3971 info_ind := valueof(ts_PCUIF_INFO_default);
3972 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003973 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
3974 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003975
3976 /* Initialize the PCU interface abstraction */
3977 f_init_raw(testcasename(), info_ind);
3978
3979 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
3980 g_mcs_initial_dl := 5;
3981 g_mcs_max_dl := 5;
3982 f_pcuvty_set_allowed_cs_mcs();
3983
3984 /* Establish BSSGP connection to the PCU */
3985 f_bssgp_establish();
3986 f_multi_ms_bssgp_register();
3987
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003988 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003989 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 +01003990 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
3991 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
3992 f_shutdown(__BFILE__, __LINE__);
3993 }
3994 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3995 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
3996
3997 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003998 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 +01003999 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4000 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4001 f_shutdown(__BFILE__, __LINE__);
4002 }
4003 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4004 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4005
4006 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4007 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4008 f_sleep(0.1);
4009 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4010 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4011 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4012 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4013 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4014 /* ACK the DL block */
4015 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4016 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4017 f_dl_block_ack_fn(dl_block, dl_fn));
4018
4019 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4020 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4021 f_sleep(0.1);
4022 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4023 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4024 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4025 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4026 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4027 /* ACK the DL block */
4028 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4029 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4030 f_dl_block_ack_fn(dl_block, dl_fn));
4031
4032 data := f_rnd_octstring(1400);
4033 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4034 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4035
4036 for (var integer i := 0; i < 800; i := i + 1) {
4037 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4038
4039 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
4040 /* No more data to receive, done */
4041 break;
4042 }
4043
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004044 usf_ms := -1;
4045
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004046 if (ischosen(dl_block.ctrl)) {
4047 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4048 f_shutdown(__BFILE__, __LINE__);
4049 } else if (ischosen(dl_block.data_egprs)) {
4050 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4051 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4052 f_shutdown(__BFILE__, __LINE__);
4053 }
4054 tgt_ms := 1;
4055 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4056 if (dl_block.data_egprs.mcs > MCS_4) {
4057 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4058 f_shutdown(__BFILE__, __LINE__);
4059 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004060 usf_ms := 0;
4061 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004062 } else {
4063 if (dl_block.data_egprs.mcs <= MCS_4) {
4064 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4065 f_shutdown(__BFILE__, __LINE__);
4066 }
4067 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004068 usf_ms := 1;
4069 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004070 }
4071 }
4072 } else {
4073 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4074 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4075 f_shutdown(__BFILE__, __LINE__);
4076 }
4077 tgt_ms := 0;
4078 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 +01004079 usf_ms := 0;
4080 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004081 } 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 +01004082 usf_ms := 1;
4083 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004084 }
4085 }
4086
4087 /* Keep Ack/Nack description updated */
4088 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4089
4090 /* TDMA frame number on which we are supposed to send the ACK */
4091 if (f_dl_block_rrbp_valid(dl_block)) {
4092 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4093 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);
4094 if (tx_data_remain != 0) {
4095 /* Submit more data from time to time to keep the TBF ongoing */
4096 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4097 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4098 tx_data_remain := tx_data_remain - 1;
4099 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004100 } else if (tx_data_remain != 0) {
4101 /* keep sending UL blocks when requested by USF to avoid
4102 * UL TBF timeout and hence stop receival of USFs */
4103 if (usf_ms != -1) {
4104 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4105 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004106 }
4107 }
4108
4109 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 +01004110 /* He we check that DL blocks scheduled at GPRS can still request UL
4111 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4112 * condition also ensures the downgrade to <=MCS4 condition is tested
4113 * above */
4114 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4115 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004116 f_shutdown(__BFILE__, __LINE__);
4117 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004118 /* Here check for some level of fairness between them (at least ~40%): */
4119 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4120 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4121 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4122 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4123 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4124 f_shutdown(__BFILE__, __LINE__);
4125 }
4126 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4127 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4128 f_shutdown(__BFILE__, __LINE__);
4129 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004130
4131 f_shutdown(__BFILE__, __LINE__, final := true);
4132}
4133
4134
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004135private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4136 boolean exp_imsi, boolean exp_tmsi)
4137runs on RAW_PCU_Test_CT {
4138 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4139 var integer pending := lengthof(g_ms);
4140 var RlcmacDlBlock dl_block;
4141 var boolean f1, f2;
4142
4143 while (pending > 0) {
4144 var uint32_t poll_fn;
4145
4146 /* Obtain a Downlink block and make sure it is a paging request */
4147 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4148 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4149 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4150 break;
4151 }
4152
4153 /* This should not happen in general, but who knows... */
4154 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4155 if (not ispresent(req.repeated_pageinfo)) {
4156 setverdict(fail, "Repeated Page Info IE is absent?!?");
4157 break;
4158 }
4159
4160 /* A single message may contain several MIs depending on their type */
4161 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4162 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4163 ps_domain := false);
4164 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4165 ps_domain := false);
4166 if (not f1 and not f2)
4167 { continue; }
4168
4169 /* Detect duplicate MIs */
4170 if (mask[i] == '1'B) {
4171 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4172 continue;
4173 }
4174
4175 mask[i] := '1'B;
4176 }
4177
4178 pending := pending - lengthof(req.repeated_pageinfo);
4179 }
4180
4181 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4182 if (mask[i] != '1'B) {
4183 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
4184 log("===== mask := ", mask);
4185 }
4186 }
4187
4188 /* All messages must have been received by now, expect a dummy block */
4189 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
4190}
4191
4192private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
4193runs on RAW_PCU_Test_CT {
4194 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4195 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4196
4197 /* Initialize NS/BSSGP side */
4198 f_init_bssgp();
4199
4200 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004201 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004202
4203 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
4204 f_init_gprs_ms(7 * 8);
4205
4206 /* Initialize the PCU interface abstraction */
4207 f_init_raw(testcasename(), info_ind);
4208
4209 /* Establish BSSGP connection to the PCU */
4210 f_bssgp_establish();
4211 f_multi_ms_bssgp_register();
4212
4213 /* Establish an Uplink TBF for each GprsMS instance */
4214 f_multi_ms_establish_tbf(do_activate := true);
4215}
4216
4217testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
4218 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4219
4220 /* Common part: send INFO.ind, establish TBFs... */
4221 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4222
4223 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
4224 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4225 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4226 }
4227
4228 /* FIXME: work around a race condition between PCUIF and BSSGP */
4229 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4230
4231 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4232 * The IUT is expected to page on all PDCH slots of all transceivers. */
4233 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4234 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4235 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
4236 }
4237
4238 f_shutdown(__BFILE__, __LINE__, final := true);
4239}
4240
4241testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
4242 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4243
4244 /* Common part: send INFO.ind, establish TBFs... */
4245 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4246
4247 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
4248 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4249 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4250 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4251 }
4252
4253 /* FIXME: work around a race condition between PCUIF and BSSGP */
4254 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4255
4256 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4257 * The IUT is expected to page on all PDCH slots of all transceivers. */
4258 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4259 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4260 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
4261 }
4262
4263 f_shutdown(__BFILE__, __LINE__, final := true);
4264}
4265
4266testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
4267 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4268
4269 /* Common part: send INFO.ind, establish TBFs... */
4270 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4271
4272 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
4273 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4274 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4275 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
4276 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4277 } else {
4278 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4279 }
4280 }
4281
4282 /* FIXME: work around a race condition between PCUIF and BSSGP */
4283 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4284
4285 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4286 * The IUT is expected to page on all PDCH slots of all transceivers. */
4287 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4288 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4289 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
4290 }
4291
4292 f_shutdown(__BFILE__, __LINE__, final := true);
4293}
4294
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004295private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004296runs on RAW_PCU_Test_CT return RlcmacDlBlock {
4297 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004298 var integer i := 0;
4299 while (true) {
4300 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4301 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
4302 break;
4303 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004304 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004305 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4306 f_shutdown(__BFILE__, __LINE__);
4307 }
4308 i := i + 1;
4309 }
4310 return dl_block;
4311}
4312
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004313private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
4314runs on RAW_PCU_Test_CT {
4315 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),
4316 info_ind.lac),
4317 info_ind.rac),
4318 info_ind.cell_id));
4319 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4320 423),
4321 2),
4322 5));
4323 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4324 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4325 var template (value) RAN_Information_RIM_Container res_cont :=
4326 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
4327 ts_RIM_Sequence_Number(2),
4328 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
4329 ts_RIM_Protocol_Version_Number(1),
4330 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
4331 omit);
4332 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4333 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4334 res_cont));
4335}
4336
4337altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
4338runs on RAW_PCU_Test_CT {
4339 /* RIM procedure: */
4340 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),
4341 info_ind.lac),
4342 info_ind.rac),
4343 info_ind.cell_id));
4344 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4345 423),
4346 2),
4347 5));
4348 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4349 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4350 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4351 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4352 tr_RAN_Information_Request_RIM_Container)) {
4353 if (do_answer) {
4354 f_outbound_nacc_rim_tx_resp(info_ind);
4355 }
4356 if (do_repeat) {
4357 repeat;
4358 }
4359 }
4360}
4361
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004362/* Start NACC from MS side */
4363private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004364 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
4365 boolean skip_final_ctrl_ack := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004366runs on RAW_PCU_Test_CT {
4367 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4368 var RlcmacDlBlock dl_block;
4369 var uint32_t sched_fn;
4370 var GsmArfcn req_arfcn := 862;
4371 var uint6_t req_bsic := 43;
4372
4373 /* Start NACC from MS side */
4374 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4375 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4376
4377 if (exp_rac_ci_query == true) {
4378 /* osmo-pcu should now ask for resolution: */
4379 f_ipa_ctrl_wait_link_up();
4380 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4381 int2str(info_ind.lac) & "." &
4382 int2str(info_ind.cell_id) & "." &
4383 int2str(req_arfcn) & "." &
4384 int2str(req_bsic);
4385 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4386 }
4387
4388 if (exp_si_query == true) {
4389 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004390 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004391 }
4392
4393 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004394 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004395
4396 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
4397 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4398 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4399 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4400 f_shutdown(__BFILE__, __LINE__);
4401 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004402 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004403 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004404 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4405 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4406 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004407}
4408
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004409/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
4410testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004411 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004412 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004413 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004414
4415 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4416 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4417
4418 /* Initialize NS/BSSGP side */
4419 f_init_bssgp();
4420 /* Initialize GPRS MS side */
4421 f_init_gprs_ms();
4422 ms := g_ms[0]; /* We only use first MS in this test */
4423
4424 /* Initialize the PCU interface abstraction */
4425 f_init_raw(testcasename(), info_ind);
4426
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004427 /* Make sure we are not affected by full cache from previous tests */
4428 f_pcuvty_flush_neigh_caches();
4429
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004430 /* Establish BSSGP connection to the PCU */
4431 f_bssgp_establish();
4432 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4433
4434 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004435 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 +01004436 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4437 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4438
4439 /* Start NACC from MS side */
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004440 f_outbound_nacc_success(ms, info_ind);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004441
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004442 f_shutdown(__BFILE__, __LINE__, final := true);
4443}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004444
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004445/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
4446testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
4447 var PollFnCtx pollctx;
4448 var GprsMS ms;
4449 var RlcmacDlBlock dl_block;
4450 var uint32_t sched_fn;
4451 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004452
4453 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4454 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4455
4456 /* Initialize NS/BSSGP side */
4457 f_init_bssgp();
4458 /* Initialize GPRS MS side */
4459 f_init_gprs_ms();
4460 ms := g_ms[0]; /* We only use first MS in this test */
4461
4462 /* Initialize the PCU interface abstraction */
4463 f_init_raw(testcasename(), info_ind);
4464
4465 /* Make sure we are not affected by full cache from previous tests */
4466 f_pcuvty_flush_neigh_caches();
4467
4468 /* Establish BSSGP connection to the PCU */
4469 f_bssgp_establish();
4470 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4471
4472 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004473 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 +01004474 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4475 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4476
4477 /* Start NACC from MS side, avoid sending final CTRL ACK */
4478 f_outbound_nacc_success(ms, info_ind, skip_final_ctrl_ack := true);
4479
4480 /* Wait until we receive something non-dummy */
4481 dl_block := f_skip_dummy(0, sched_fn);
4482 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
4483 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4484 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4485 }
4486 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4487 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4488 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4489 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4490 }
4491
4492 f_shutdown(__BFILE__, __LINE__, final := true);
4493}
4494
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004495/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
4496testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
4497 var PollFnCtx pollctx;
4498 var GprsMS ms;
4499 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004500 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004501
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004502 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4503 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004504
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004505 /* Initialize NS/BSSGP side */
4506 f_init_bssgp();
4507 /* Initialize GPRS MS side */
4508 f_init_gprs_ms();
4509 ms := g_ms[0]; /* We only use first MS in this test */
4510
4511 /* Initialize the PCU interface abstraction */
4512 f_init_raw(testcasename(), info_ind);
4513
4514 /* Make sure we are not affected by full cache from previous tests */
4515 f_pcuvty_flush_neigh_caches();
4516 /* Set timeout values for caches so that entries will be in cache during second try */
4517 f_pcuvty_set_neigh_caches(10, 10);
4518
4519 /* Establish BSSGP connection to the PCU */
4520 f_bssgp_establish();
4521 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4522
4523 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004524 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 +01004525 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4526 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4527
4528 /* Start NACC from MS side */
4529 f_outbound_nacc_success(ms, info_ind);
4530
4531 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
4532 f_outbound_nacc_success(ms, info_ind, false, false);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004533
4534 f_shutdown(__BFILE__, __LINE__, final := true);
4535}
4536
Pau Espin Pedrol85366682021-01-27 19:04:54 +01004537/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
4538 * TS 44.060 sec 8.8) twice, the second time after caches timed out
4539 */
4540testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
4541 var PollFnCtx pollctx;
4542 var GprsMS ms;
4543 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01004544 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4545
4546 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4547 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4548
4549 /* Initialize NS/BSSGP side */
4550 f_init_bssgp();
4551 /* Initialize GPRS MS side */
4552 f_init_gprs_ms();
4553 ms := g_ms[0]; /* We only use first MS in this test */
4554
4555 /* Initialize the PCU interface abstraction */
4556 f_init_raw(testcasename(), info_ind);
4557
4558 /* Make sure we are not affected by full cache from previous tests */
4559 f_pcuvty_flush_neigh_caches();
4560 /* Set timeout values for caches so that entries will be erased before the second try */
4561 f_pcuvty_set_neigh_caches(1, 1);
4562
4563 /* Establish BSSGP connection to the PCU */
4564 f_bssgp_establish();
4565 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4566
4567 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004568 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 +01004569 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4570 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4571
4572 /* Start NACC from MS side */
4573 f_outbound_nacc_success(ms, info_ind);
4574
4575 /* CTRL client should have disconnected from us */
4576 f_ipa_ctrl_wait_link_down();
4577 /* wait for cache entries to time out */
4578 f_sleep(2.0);
4579 /* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
4580 f_outbound_nacc_success(ms, info_ind);
4581
4582 f_shutdown(__BFILE__, __LINE__, final := true);
4583}
4584
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004585/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01004586testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
4587 var RlcmacDlBlock dl_block;
4588 var PollFnCtx pollctx;
4589 var uint32_t sched_fn;
4590 var GprsMS ms;
4591 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4592 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01004593 var GsmArfcn req_arfcn := 862;
4594 var uint6_t req_bsic := 43;
4595
4596 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
4597 * resolution CTRL port, to trigger Conn Refused by socket:
4598 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4599 */
4600
4601 /* Initialize NS/BSSGP side */
4602 f_init_bssgp();
4603 /* Initialize GPRS MS side */
4604 f_init_gprs_ms();
4605 ms := g_ms[0]; /* We only use first MS in this test */
4606
4607 /* Initialize the PCU interface abstraction */
4608 f_init_raw(testcasename(), info_ind);
4609
4610 /* Make sure we are not affected by full cache from previous tests */
4611 f_pcuvty_flush_neigh_caches();
4612
4613 /* Establish BSSGP connection to the PCU */
4614 f_bssgp_establish();
4615 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4616
4617 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004618 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 +01004619 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4620 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4621
4622 /* Start NACC from MS side */
4623 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4624 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4625
4626 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004627 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01004628 /* Make sure it is a Pkt Cell Chg Continue */
4629 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4630 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4631 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004632 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4633 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4634 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4635 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4636 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01004637
4638 f_shutdown(__BFILE__, __LINE__, final := true);
4639}
4640
4641/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004642testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
4643 var RlcmacDlBlock dl_block;
4644 var PollFnCtx pollctx;
4645 var uint32_t sched_fn;
4646 var GprsMS ms;
4647 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4648 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004649 var GsmArfcn req_arfcn := 862;
4650 var uint6_t req_bsic := 43;
4651
4652 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4653 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4654
4655 /* Initialize NS/BSSGP side */
4656 f_init_bssgp();
4657 /* Initialize GPRS MS side */
4658 f_init_gprs_ms();
4659 ms := g_ms[0]; /* We only use first MS in this test */
4660
4661 /* Initialize the PCU interface abstraction */
4662 f_init_raw(testcasename(), info_ind);
4663
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004664 /* Make sure we are not affected by full cache from previous tests */
4665 f_pcuvty_flush_neigh_caches();
4666
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004667 /* Establish BSSGP connection to the PCU */
4668 f_bssgp_establish();
4669 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4670
4671 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004672 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 +01004673 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4674 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4675
4676 /* Start NACC from MS side */
4677 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4678 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4679
4680 /* osmo-pcu should now ask for resolution: */
4681 f_ipa_ctrl_wait_link_up();
4682 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4683 int2str(info_ind.lac) & "." &
4684 int2str(info_ind.cell_id) & "." &
4685 int2str(req_arfcn) & "." &
4686 int2str(req_bsic);
4687 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
4688 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
4689
4690 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004691 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004692 /* Make sure it is a Pkt Cell Chg Continue */
4693 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4694 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4695 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004696 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4697 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4698 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4699 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4700 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004701
4702 f_shutdown(__BFILE__, __LINE__, final := true);
4703}
4704
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004705/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
4706testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
4707 var RlcmacDlBlock dl_block;
4708 var PollFnCtx pollctx;
4709 var uint32_t sched_fn;
4710 var GprsMS ms;
4711 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4712 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004713 var GsmArfcn req_arfcn := 862;
4714 var uint6_t req_bsic := 43;
4715
4716 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4717 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4718
4719 /* Initialize NS/BSSGP side */
4720 f_init_bssgp();
4721 /* Initialize GPRS MS side */
4722 f_init_gprs_ms();
4723 ms := g_ms[0]; /* We only use first MS in this test */
4724
4725 /* Initialize the PCU interface abstraction */
4726 f_init_raw(testcasename(), info_ind);
4727
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004728 /* Make sure we are not affected by full cache from previous tests */
4729 f_pcuvty_flush_neigh_caches();
4730
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004731 /* Establish BSSGP connection to the PCU */
4732 f_bssgp_establish();
4733 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4734
4735 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004736 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 +01004737 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4738 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4739
4740 /* Start NACC from MS side */
4741 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4742 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4743
4744 /* osmo-pcu should now ask for resolution: */
4745 f_ipa_ctrl_wait_link_up();
4746 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4747 int2str(info_ind.lac) & "." &
4748 int2str(info_ind.cell_id) & "." &
4749 int2str(req_arfcn) & "." &
4750 int2str(req_bsic);
4751 /* we receive RAC+CI resolution request and we send incorrectlt formated response */
4752 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
4753
4754 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004755 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004756 /* Make sure it is a Pkt Cell Chg Continue */
4757 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4758 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4759 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004760 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4761 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4762 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4763 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4764 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004765
4766 f_shutdown(__BFILE__, __LINE__, final := true);
4767}
4768
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004769/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
4770testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
4771 var RlcmacDlBlock dl_block;
4772 var PollFnCtx pollctx;
4773 var uint32_t sched_fn;
4774 var GprsMS ms;
4775 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4776 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004777 var GsmArfcn req_arfcn := 862;
4778 var uint6_t req_bsic := 43;
4779 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 */
4780 info_ind.lac),
4781 info_ind.rac),
4782 info_ind.cell_id));
4783 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4784 423),
4785 2),
4786 5));
4787 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
4788 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
4789
4790 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4791 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4792
4793 /* Initialize NS/BSSGP side */
4794 f_init_bssgp();
4795 /* Initialize GPRS MS side */
4796 f_init_gprs_ms();
4797 ms := g_ms[0]; /* We only use first MS in this test */
4798
4799 /* Initialize the PCU interface abstraction */
4800 f_init_raw(testcasename(), info_ind);
4801
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004802 /* Make sure we are not affected by full cache from previous tests */
4803 f_pcuvty_flush_neigh_caches();
4804
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004805 /* Establish BSSGP connection to the PCU */
4806 f_bssgp_establish();
4807 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4808
4809 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004810 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 +01004811 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4812 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4813
4814 /* Start NACC from MS side */
4815 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4816 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4817
4818 /* osmo-pcu should now ask for resolution: */
4819 f_ipa_ctrl_wait_link_up();
4820 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4821 int2str(info_ind.lac) & "." &
4822 int2str(info_ind.cell_id) & "." &
4823 int2str(req_arfcn) & "." &
4824 int2str(req_bsic);
4825 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4826
4827 /* RIM procedure: */
4828 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4829 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4830 tr_RAN_Information_Request_RIM_Container));
4831 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
4832
4833 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004834 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004835 /* Make sure it is a Pkt Cell Chg Continue */
4836 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4837 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4838 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004839 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4840 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4841 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4842 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4843 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004844
4845 f_shutdown(__BFILE__, __LINE__, final := true);
4846}
4847
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004848/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
4849testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
4850 var PollFnCtx pollctx;
4851 var GprsMS ms;
4852 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4853 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4854 var RlcmacDlBlock dl_block;
4855 var uint32_t sched_fn;
4856 var CtrlMessage rx_ctrl;
4857 var GsmArfcn req_arfcn := 862;
4858 var uint6_t req_bsic := 43;
4859
4860 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4861 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4862
4863 /* Initialize NS/BSSGP side */
4864 f_init_bssgp();
4865 /* Initialize GPRS MS side */
4866 f_init_gprs_ms();
4867 ms := g_ms[0]; /* We only use first MS in this test */
4868
4869 /* Initialize the PCU interface abstraction */
4870 f_init_raw(testcasename(), info_ind);
4871
4872 /* Make sure we are not affected by full cache from previous tests */
4873 f_pcuvty_flush_neigh_caches();
4874
4875 /* Establish BSSGP connection to the PCU */
4876 f_bssgp_establish();
4877 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4878
4879 /* Send PACKET RESOURCE REQUEST */
4880 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4881 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4882 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4883
4884 /* Start NACC from MS side */
4885 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4886 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4887
4888 /* osmo-pcu should now ask for resolution: */
4889 f_ipa_ctrl_wait_link_up();
4890 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4891 int2str(info_ind.lac) & "." &
4892 int2str(info_ind.cell_id) & "." &
4893 int2str(req_arfcn) & "." &
4894 int2str(req_bsic);
4895 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
4896 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
4897 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4898 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
4899 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
4900 timer T := 2.0;
4901 T.start;
4902 alt {
4903 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
4904 [] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
4905 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
4906 f_shutdown(__BFILE__, __LINE__);
4907 }
4908 [] T.timeout {
4909 setverdict(pass);
4910 }
4911 }
4912
4913 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004914 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004915
4916 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
4917 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4918 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4919 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4920 f_shutdown(__BFILE__, __LINE__);
4921 }
4922 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4923 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
4924 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
4925 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
4926 }
4927
4928 f_shutdown(__BFILE__, __LINE__, final := true);
4929}
4930
4931/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
4932testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
4933 var PollFnCtx pollctx;
4934 var GprsMS ms;
4935 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4936 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4937 var RlcmacDlBlock dl_block;
4938 var uint32_t sched_fn;
4939 var CtrlMessage rx_ctrl;
4940 var GsmArfcn req_arfcn := 862;
4941 var uint6_t req_bsic := 43;
4942
4943 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4944 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4945
4946 /* Initialize NS/BSSGP side */
4947 f_init_bssgp();
4948 /* Initialize GPRS MS side */
4949 f_init_gprs_ms();
4950 ms := g_ms[0]; /* We only use first MS in this test */
4951
4952 /* Initialize the PCU interface abstraction */
4953 f_init_raw(testcasename(), info_ind);
4954
4955 /* Make sure we are not affected by full cache from previous tests */
4956 f_pcuvty_flush_neigh_caches();
4957
4958 /* Establish BSSGP connection to the PCU */
4959 f_bssgp_establish();
4960 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4961
4962 /* Send PACKET RESOURCE REQUEST */
4963 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
4964 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4965 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4966
4967 /* Start NACC from MS side */
4968 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4969 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4970
4971 /* osmo-pcu should now ask for resolution: */
4972 f_ipa_ctrl_wait_link_up();
4973 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4974 int2str(info_ind.lac) & "." &
4975 int2str(info_ind.cell_id) & "." &
4976 int2str(req_arfcn) & "." &
4977 int2str(req_bsic);
4978 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4979 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
4980 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
4981 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4982 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
4983 f_outbound_nacc_rim_tx_resp(info_ind);
4984 timer T := 1.0;
4985 T.start;
4986 alt {
4987 [] RIM.receive {
4988 setverdict(fail, "Received unexpected RIM message");
4989 f_shutdown(__BFILE__, __LINE__);
4990 }
4991 [] T.timeout {
4992 setverdict(pass);
4993 }
4994 }
4995
4996 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01004997 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004998
4999 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5000 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5001 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5002 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5003 f_shutdown(__BFILE__, __LINE__);
5004 }
5005 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5006 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5007 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5008 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5009 }
5010
5011 f_shutdown(__BFILE__, __LINE__, final := true);
5012}
5013
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005014/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5015testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5016 var PollFnCtx pollctx;
5017 var GprsMS ms;
5018 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5019 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5020 var RlcmacDlBlock dl_block;
5021 var uint32_t sched_fn;
5022 var CtrlMessage rx_ctrl;
5023 var GsmArfcn req_arfcn := 862;
5024 var uint6_t req_bsic := 43;
5025
5026 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5027 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5028
5029 /* Initialize NS/BSSGP side */
5030 f_init_bssgp();
5031 /* Initialize GPRS MS side */
5032 f_init_gprs_ms();
5033 ms := g_ms[0]; /* We only use first MS in this test */
5034
5035 /* Initialize the PCU interface abstraction */
5036 f_init_raw(testcasename(), info_ind);
5037
5038 /* Make sure we are not affected by full cache from previous tests */
5039 f_pcuvty_flush_neigh_caches();
5040
5041 /* Establish BSSGP connection to the PCU */
5042 f_bssgp_establish();
5043 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5044
5045 /* Send PACKET RESOURCE REQUEST */
5046 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5047 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5048 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5049
5050 /* Start NACC from MS side */
5051 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5052 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5053
5054 /* osmo-pcu should now ask for resolution: */
5055 f_ipa_ctrl_wait_link_up();
5056 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5057 int2str(info_ind.lac) & "." &
5058 int2str(info_ind.cell_id) & "." &
5059 int2str(req_arfcn) & "." &
5060 int2str(req_bsic);
5061 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5062 /* RIM procedure: */
5063 as_outbound_nacc_rim_resolve(info_ind);
5064
5065 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5066 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5067 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5068
5069 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5070 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5071
5072 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5073 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5074 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5075 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5076 f_shutdown(__BFILE__, __LINE__);
5077 }
5078 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5079 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5080 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5081 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5082 }
5083}
5084
5085/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5086testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5087 var PollFnCtx pollctx;
5088 var GprsMS ms;
5089 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5090 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5091 var RlcmacDlBlock dl_block;
5092 var uint32_t sched_fn;
5093 var CtrlMessage rx_ctrl;
5094 var GsmArfcn req_arfcn := 862;
5095 var uint6_t req_bsic := 43;
5096
5097 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5098 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5099
5100 /* Initialize NS/BSSGP side */
5101 f_init_bssgp();
5102 /* Initialize GPRS MS side */
5103 f_init_gprs_ms();
5104 ms := g_ms[0]; /* We only use first MS in this test */
5105
5106 /* Initialize the PCU interface abstraction */
5107 f_init_raw(testcasename(), info_ind);
5108
5109 /* Make sure we are not affected by full cache from previous tests */
5110 f_pcuvty_flush_neigh_caches();
5111
5112 /* Establish BSSGP connection to the PCU */
5113 f_bssgp_establish();
5114 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5115
5116 /* Send PACKET RESOURCE REQUEST */
5117 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5118 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5119 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5120
5121 /* Start NACC from MS side */
5122 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5123 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5124
5125 /* osmo-pcu should now ask for resolution: */
5126 f_ipa_ctrl_wait_link_up();
5127 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5128 int2str(info_ind.lac) & "." &
5129 int2str(info_ind.cell_id) & "." &
5130 int2str(req_arfcn) & "." &
5131 int2str(req_bsic);
5132 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5133 /* RIM procedure: */
5134 as_outbound_nacc_rim_resolve(info_ind);
5135
5136 /* Announce SI back to MS, continue NACC procedure */
5137 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5138
5139 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5140 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5141
5142 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5143 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5144 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5145 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5146 f_shutdown(__BFILE__, __LINE__);
5147 }
5148 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5149 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5150 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5151 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5152 }
5153}
5154
5155/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
5156testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
5157 var PollFnCtx pollctx;
5158 var GprsMS ms;
5159 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5160 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5161 var RlcmacDlBlock dl_block;
5162 var uint32_t sched_fn;
5163 var CtrlMessage rx_ctrl;
5164 var GsmArfcn req_arfcn := 862;
5165 var uint6_t req_bsic := 43;
5166
5167 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5168 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5169
5170 /* Initialize NS/BSSGP side */
5171 f_init_bssgp();
5172 /* Initialize GPRS MS side */
5173 f_init_gprs_ms();
5174 ms := g_ms[0]; /* We only use first MS in this test */
5175
5176 /* Initialize the PCU interface abstraction */
5177 f_init_raw(testcasename(), info_ind);
5178
5179 /* Make sure we are not affected by full cache from previous tests */
5180 f_pcuvty_flush_neigh_caches();
5181
5182 /* Establish BSSGP connection to the PCU */
5183 f_bssgp_establish();
5184 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5185
5186 /* Send PACKET RESOURCE REQUEST */
5187 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5188 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5189 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5190
5191 /* Start NACC from MS side */
5192 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5193 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5194
5195 /* osmo-pcu should now ask for resolution: */
5196 f_ipa_ctrl_wait_link_up();
5197 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5198 int2str(info_ind.lac) & "." &
5199 int2str(info_ind.cell_id) & "." &
5200 int2str(req_arfcn) & "." &
5201 int2str(req_bsic);
5202 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5203 /* RIM procedure: */
5204 as_outbound_nacc_rim_resolve(info_ind);
5205
5206 /* Announce SI back to MS, continue NACC procedure */
5207 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5208
5209 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5210 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5211 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5212 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5213 f_shutdown(__BFILE__, __LINE__);
5214 }
5215 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5216 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5217
5218 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5219 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5220 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5221 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5222 }
5223}
5224
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005225/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5226 * while waiting for CTRL resolution */
5227testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
5228 var PollFnCtx pollctx;
5229 var GprsMS ms;
5230 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5231 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5232 var RlcmacDlBlock dl_block;
5233 var uint32_t sched_fn;
5234 var CtrlMessage rx_ctrl;
5235 var GsmArfcn req_arfcn := 862;
5236 var uint6_t req_bsic := 43;
5237
5238 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5239 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5240
5241 /* Initialize NS/BSSGP side */
5242 f_init_bssgp();
5243 /* Initialize GPRS MS side */
5244 f_init_gprs_ms();
5245 ms := g_ms[0]; /* We only use first MS in this test */
5246
5247 /* Initialize the PCU interface abstraction */
5248 f_init_raw(testcasename(), info_ind);
5249
5250 /* Make sure we are not affected by full cache from previous tests */
5251 f_pcuvty_flush_neigh_caches();
5252
5253 /* Establish BSSGP connection to the PCU */
5254 f_bssgp_establish();
5255 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5256
5257 /* Send PACKET RESOURCE REQUEST */
5258 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5259 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5260 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5261
5262 /* Start NACC from MS side */
5263 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5264 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5265
5266 /* osmo-pcu should now ask for resolution: */
5267 f_ipa_ctrl_wait_link_up();
5268 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5269 int2str(info_ind.lac) & "." &
5270 int2str(info_ind.cell_id) & "." &
5271 int2str(req_arfcn) & "." &
5272 int2str(req_bsic);
5273 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5274 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
5275 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5276 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5277 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5278 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5279 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
5280 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5281 int2str(info_ind.lac) & "." &
5282 int2str(info_ind.cell_id) & "." &
5283 int2str(req_arfcn + 1) & "." &
5284 int2str(req_bsic + 1);
5285 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5286
5287 /* And finally everything continues as usual with RIN procedure */
5288 as_outbound_nacc_rim_resolve(info_ind);
5289
5290 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005291 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005292
5293 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5294 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5295 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5296 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5297 f_shutdown(__BFILE__, __LINE__);
5298 }
5299 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5300 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5301 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5302 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5303 }
5304
5305 f_shutdown(__BFILE__, __LINE__, final := true);
5306}
5307
5308/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5309 * while waiting for SI resolution */
5310testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
5311 var PollFnCtx pollctx;
5312 var GprsMS ms;
5313 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5314 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5315 var RlcmacDlBlock dl_block;
5316 var uint32_t sched_fn;
5317 var CtrlMessage rx_ctrl;
5318 var GsmArfcn req_arfcn := 862;
5319 var uint6_t req_bsic := 43;
5320
5321 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5322 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5323
5324 /* Initialize NS/BSSGP side */
5325 f_init_bssgp();
5326 /* Initialize GPRS MS side */
5327 f_init_gprs_ms();
5328 ms := g_ms[0]; /* We only use first MS in this test */
5329
5330 /* Initialize the PCU interface abstraction */
5331 f_init_raw(testcasename(), info_ind);
5332
5333 /* Make sure we are not affected by full cache from previous tests */
5334 f_pcuvty_flush_neigh_caches();
5335
5336 /* Establish BSSGP connection to the PCU */
5337 f_bssgp_establish();
5338 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5339
5340 /* Send PACKET RESOURCE REQUEST */
5341 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5342 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5343 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5344
5345 /* Start NACC from MS side */
5346 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5347 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5348
5349 /* osmo-pcu should now ask for resolution: */
5350 f_ipa_ctrl_wait_link_up();
5351 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5352 int2str(info_ind.lac) & "." &
5353 int2str(info_ind.cell_id) & "." &
5354 int2str(req_arfcn) & "." &
5355 int2str(req_bsic);
5356 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5357 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5358 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
5359 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5360 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5361 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5362 f_outbound_nacc_rim_tx_resp(info_ind);
5363
5364 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
5365 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5366 int2str(info_ind.lac) & "." &
5367 int2str(info_ind.cell_id) & "." &
5368 int2str(req_arfcn + 1) & "." &
5369 int2str(req_bsic + 1);
5370 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5371
5372 /* And finally everything continues as usual with RIN procedure */
5373 as_outbound_nacc_rim_resolve(info_ind);
5374
5375 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005376 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005377
5378 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5379 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5380 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5381 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5382 f_shutdown(__BFILE__, __LINE__);
5383 }
5384 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5385 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5386 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5387 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5388 }
5389
5390 f_shutdown(__BFILE__, __LINE__, final := true);
5391}
5392
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01005393/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5394 * while sending Pkt Neigh Data Change */
5395testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
5396 var PollFnCtx pollctx;
5397 var GprsMS ms;
5398 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5399 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5400 var RlcmacDlBlock dl_block;
5401 var uint32_t sched_fn;
5402 var CtrlMessage rx_ctrl;
5403 var GsmArfcn req_arfcn := 862;
5404 var uint6_t req_bsic := 43;
5405
5406 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5407 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5408
5409 /* Initialize NS/BSSGP side */
5410 f_init_bssgp();
5411 /* Initialize GPRS MS side */
5412 f_init_gprs_ms();
5413 ms := g_ms[0]; /* We only use first MS in this test */
5414
5415 /* Initialize the PCU interface abstraction */
5416 f_init_raw(testcasename(), info_ind);
5417
5418 /* Make sure we are not affected by full cache from previous tests */
5419 f_pcuvty_flush_neigh_caches();
5420
5421 /* Establish BSSGP connection to the PCU */
5422 f_bssgp_establish();
5423 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5424
5425 /* Send PACKET RESOURCE REQUEST */
5426 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5427 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5428 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5429
5430 /* Start NACC from MS side */
5431 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5432 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5433
5434 /* osmo-pcu should now ask for resolution: */
5435 f_ipa_ctrl_wait_link_up();
5436 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5437 int2str(info_ind.lac) & "." &
5438 int2str(info_ind.cell_id) & "." &
5439 int2str(req_arfcn) & "." &
5440 int2str(req_bsic);
5441 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5442 /* RIM procedure: */
5443 as_outbound_nacc_rim_resolve(info_ind);
5444
5445 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
5446 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5447 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5448 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5449
5450 /* It should trigger RAC_CI resolution to start again: */
5451 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5452 int2str(info_ind.lac) & "." &
5453 int2str(info_ind.cell_id) & "." &
5454 int2str(req_arfcn + 1) & "." &
5455 int2str(req_bsic + 1);
5456 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5457 /* RIM procedure: */
5458 as_outbound_nacc_rim_resolve(info_ind);
5459 /* Transmit SI back to MS */
5460 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5461
5462 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5463 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5464 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5465 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5466 f_shutdown(__BFILE__, __LINE__);
5467 }
5468 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5469 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5470 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5471 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5472 }
5473}
5474
5475/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
5476testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
5477 var PollFnCtx pollctx;
5478 var GprsMS ms;
5479 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5480 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5481 var RlcmacDlBlock dl_block;
5482 var uint32_t sched_fn;
5483 var CtrlMessage rx_ctrl;
5484 var GsmArfcn req_arfcn := 862;
5485 var uint6_t req_bsic := 43;
5486
5487 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5488 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5489
5490 /* Initialize NS/BSSGP side */
5491 f_init_bssgp();
5492 /* Initialize GPRS MS side */
5493 f_init_gprs_ms();
5494 ms := g_ms[0]; /* We only use first MS in this test */
5495
5496 /* Initialize the PCU interface abstraction */
5497 f_init_raw(testcasename(), info_ind);
5498
5499 /* Make sure we are not affected by full cache from previous tests */
5500 f_pcuvty_flush_neigh_caches();
5501
5502 /* Establish BSSGP connection to the PCU */
5503 f_bssgp_establish();
5504 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5505
5506 /* Send PACKET RESOURCE REQUEST */
5507 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5508 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5509 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5510
5511 /* Start NACC from MS side */
5512 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5513 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5514
5515 /* osmo-pcu should now ask for resolution: */
5516 f_ipa_ctrl_wait_link_up();
5517 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5518 int2str(info_ind.lac) & "." &
5519 int2str(info_ind.cell_id) & "." &
5520 int2str(req_arfcn) & "." &
5521 int2str(req_bsic);
5522 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5523 /* RIM procedure: */
5524 as_outbound_nacc_rim_resolve(info_ind);
5525
5526 /* Announce SI back to MS, continue NACC procedure */
5527 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5528
5529 /* trigger a Pkt Cell Change Notif with different tgt cell */
5530 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5531 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5532
5533 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
5534 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
5535
5536 /* It should trigger RAC_CI resolution to start again: */
5537 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5538 int2str(info_ind.lac) & "." &
5539 int2str(info_ind.cell_id) & "." &
5540 int2str(req_arfcn + 1) & "." &
5541 int2str(req_bsic + 1);
5542 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5543 /* RIM procedure: */
5544 as_outbound_nacc_rim_resolve(info_ind);
5545 /* Transmit SI back to MS */
5546 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5547
5548 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5549 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5550 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5551 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5552 f_shutdown(__BFILE__, __LINE__);
5553 }
5554 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5555 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5556 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5557 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5558 }
5559}
5560
5561/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
5562testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
5563 var PollFnCtx pollctx;
5564 var GprsMS ms;
5565 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5566 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5567 var RlcmacDlBlock dl_block;
5568 var uint32_t sched_fn;
5569 var CtrlMessage rx_ctrl;
5570 var GsmArfcn req_arfcn := 862;
5571 var uint6_t req_bsic := 43;
5572
5573 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5574 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5575
5576 /* Initialize NS/BSSGP side */
5577 f_init_bssgp();
5578 /* Initialize GPRS MS side */
5579 f_init_gprs_ms();
5580 ms := g_ms[0]; /* We only use first MS in this test */
5581
5582 /* Initialize the PCU interface abstraction */
5583 f_init_raw(testcasename(), info_ind);
5584
5585 /* Make sure we are not affected by full cache from previous tests */
5586 f_pcuvty_flush_neigh_caches();
5587
5588 /* Establish BSSGP connection to the PCU */
5589 f_bssgp_establish();
5590 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5591
5592 /* Send PACKET RESOURCE REQUEST */
5593 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5594 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5595 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5596
5597 /* Start NACC from MS side */
5598 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5599 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5600
5601 /* osmo-pcu should now ask for resolution: */
5602 f_ipa_ctrl_wait_link_up();
5603 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5604 int2str(info_ind.lac) & "." &
5605 int2str(info_ind.cell_id) & "." &
5606 int2str(req_arfcn) & "." &
5607 int2str(req_bsic);
5608 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5609 /* RIM procedure: */
5610 as_outbound_nacc_rim_resolve(info_ind);
5611
5612 /* Announce SI back to MS, continue NACC procedure */
5613 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5614
5615 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5616 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5617 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5618 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5619 f_shutdown(__BFILE__, __LINE__);
5620 }
5621
5622 /* trigger a Pkt Cell Change Notif with different tgt cell */
5623 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5624 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5625
5626 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5627 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5628 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5629 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5630 }
5631 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
5632 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
5633
5634 /* It should trigger RAC_CI resolution to start again: */
5635 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5636 int2str(info_ind.lac) & "." &
5637 int2str(info_ind.cell_id) & "." &
5638 int2str(req_arfcn + 1) & "." &
5639 int2str(req_bsic + 1);
5640 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5641 /* RIM procedure: */
5642 as_outbound_nacc_rim_resolve(info_ind);
5643 /* Transmit SI back to MS */
5644 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5645
5646 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5647 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5648 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5649 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5650 f_shutdown(__BFILE__, __LINE__);
5651 }
5652 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5653 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5654 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5655 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5656 }
5657}
5658
Pau Espin Pedrol13035772021-02-18 16:07:06 +01005659/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
5660testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
5661 var PollFnCtx pollctx;
5662 var GprsMS ms;
5663 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5664 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5665 var RlcmacDlBlock dl_block;
5666 var uint32_t sched_fn, dl_fn;
5667 var CtrlMessage rx_ctrl;
5668 var GsmArfcn req_arfcn := 862;
5669 var uint6_t req_bsic := 43;
5670 var octetstring data := f_rnd_octstring(10);
5671
5672 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5673 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5674
5675 /* Initialize NS/BSSGP side */
5676 f_init_bssgp();
5677 /* Initialize GPRS MS side */
5678 f_init_gprs_ms();
5679 ms := g_ms[0]; /* We only use first MS in this test */
5680
5681 /* Initialize the PCU interface abstraction */
5682 f_init_raw(testcasename(), info_ind);
5683
5684 /* Make sure we are not affected by full cache from previous tests */
5685 f_pcuvty_flush_neigh_caches();
5686
5687 /* Establish BSSGP connection to the PCU */
5688 f_bssgp_establish();
5689 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5690
5691 /* Send PACKET RESOURCE REQUEST */
5692 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5693 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5694 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5695
5696 /* Start NACC from MS side */
5697 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5698 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5699
5700 /* osmo-pcu should now ask for resolution: */
5701 f_ipa_ctrl_wait_link_up();
5702 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5703 int2str(info_ind.lac) & "." &
5704 int2str(info_ind.cell_id) & "." &
5705 int2str(req_arfcn) & "." &
5706 int2str(req_bsic);
5707 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
5708 /* RIM procedure: */
5709 as_outbound_nacc_rim_resolve(info_ind);
5710
5711 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
5712 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
5713 f_sleep(0.1);
5714 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
5715 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
5716
5717 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
5718 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5719 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
5720 * Data with unassigned DL TBF in line above): */
5721 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5722 /* Continue receiving Pkt Cell Neighbor Data */
5723 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5724
5725 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5726 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5727 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5728 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5729 f_shutdown(__BFILE__, __LINE__);
5730 }
5731 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5732 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5733 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5734 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5735 }
5736
5737 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
5738 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
5739 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
5740 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
5741 f_dl_block_ack_fn(dl_block, dl_fn));
5742}
5743
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005744
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005745function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
5746runs on RAW_PCU_Test_CT
5747{
5748 var template (value) RAN_Information_Request_RIM_Container req_cont;
5749 var template (value) PDU_BSSGP bssgp_rim_pdu;
5750 var template PDU_BSSGP bssgp_rim_pdu_expect;
5751 var template RAN_Information_RIM_Container rim_cont_expect;
5752 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005753
5754 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01005755 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 +01005756 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01005757 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 +01005758 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02005759 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);
5760 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005761 f_sleep(1.0);
5762
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005763 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005764
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005765 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5766 ts_RIM_Sequence_Number(1),
5767 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5768 ts_RIM_Protocol_Version_Number(1),
5769 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
5770 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005771 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
5772 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005773
5774 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
5775 tr_RIM_Sequence_Number(1),
5776 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5777 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01005778 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 +01005779 omit);
5780
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005781 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
5782 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005783 rim_cont_expect);
5784 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005785 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005786 T.start;
5787 alt {
5788 [] RIM.receive(bssgp_rim_pdu_expect) { }
5789 [] RIM.receive {
5790 setverdict(fail, "Unexpected BSSGP RIM PDU received");
5791 }
5792 [] T.timeout {
5793 setverdict(fail, "No BSSGP RIM PDU received");
5794 mtc.stop;
5795 }
5796 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02005797}
5798/* Send a RIM RAN info request to the PCU and verify the response, we expect
5799 * getting the system information back which we have transfered to the PCU via
5800 * PCUIF on startup. */
5801testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
5802 /* Initialize NS/BSSGP side */
5803 f_init_bssgp();
5804
5805 /* Initialize the PCU interface abstraction */
5806 f_init_raw(testcasename());
5807
5808 /* Establish BSSGP connection to the PCU */
5809 f_bssgp_establish();
5810
5811 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
5812 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
5813
5814 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5815 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
5816
5817 f_shutdown(__BFILE__, __LINE__, final := true);
5818}
5819
5820/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
5821 * Routing information, to verify PCU handles that kind of address just fine
5822 */
5823testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
5824 /* Initialize NS/BSSGP side */
5825 f_init_bssgp();
5826
5827 /* Initialize the PCU interface abstraction */
5828 f_init_raw(testcasename());
5829
5830 /* Establish BSSGP connection to the PCU */
5831 f_bssgp_establish();
5832
5833 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
5834 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
5835
5836 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
5837 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005838
5839 f_shutdown(__BFILE__, __LINE__, final := true);
5840}
5841
5842/* Same as above, but in this case we simulate the rare case in which the PCU
5843 * has no system information available. We expect getting a response back but
5844 * with no system information inside. */
5845testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01005846 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005847 var PCUIF_Message pcu_msg;
5848 timer T := 2.0;
5849
5850 /* Initialize NS/BSSGP side */
5851 f_init_bssgp();
5852
5853 /* Initialize the PCU interface abstraction */
5854 f_init_raw(testcasename(), info_ind);
5855
5856 /* Establish BSSGP connection to the PCU */
5857 f_bssgp_establish();
5858
5859 /* Clear sysinfo from the PCU */
5860 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);
5861 BTS.send(si1_data_ind);
5862 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);
5863 BTS.send(si3_data_ind);
5864 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);
5865 BTS.send(si16_data_ind);
5866 f_sleep(1.0);
5867
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01005868 var RIM_Routing_Address dst_addr;
5869 var RIM_Routing_Address src_addr;
5870 var template (value) RAN_Information_Request_RIM_Container req_cont;
5871 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005872 var template PDU_BSSGP bssgp_rim_pdu_expect;
5873 var template RAN_Information_RIM_Container rim_cont_expect;
5874
5875 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 +01005876 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
5877 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01005878
5879 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
5880 ts_RIM_Sequence_Number(1),
5881 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5882 ts_RIM_Protocol_Version_Number(1),
5883 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
5884 omit);
5885 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5886 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5887 req_cont);
5888
5889
5890 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
5891 tr_RIM_Sequence_Number(1),
5892 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
5893 tr_RIM_Protocol_Version_Number(1),
5894 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
5895 omit);
5896
5897 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5898 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5899 rim_cont_expect);
5900 RIM.send(bssgp_rim_pdu);
5901 T.start;
5902 alt {
5903 [] RIM.receive(bssgp_rim_pdu_expect) { }
5904 [] RIM.receive {
5905 setverdict(fail, "Unexpected BSSGP RIM PDU received");
5906 }
5907 [] T.timeout {
5908 setverdict(fail, "No BSSGP RIM PDU received");
5909 mtc.stop;
5910 }
5911 }
5912
5913 f_shutdown(__BFILE__, __LINE__, final := true);
5914}
5915
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005916control {
5917 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01005918 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005919 execute( TC_ta_ptcch_idle() );
5920 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02005921 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005922 execute( TC_ta_idle_dl_tbf_ass() );
5923 execute( TC_ta_ptcch_ul_multi_tbf() );
5924 execute( TC_cs_lqual_ul_tbf() );
5925 execute( TC_cs_initial_ul() );
5926 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01005927 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01005928 execute( TC_cs_max_dl() );
5929 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01005930 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01005931 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01005932 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01005933 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02005934 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01005935 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02005936 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01005937 execute( TC_x2031_t3191() );
5938 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005939 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01005940 execute( TC_n3105_max_t3195() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02005941 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02005942 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02005943 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005944 execute( TC_mo_ping_pong() );
5945 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02005946 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005947 execute( TC_mt_ping_pong() );
5948 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02005949 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005950 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07005951 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02005952 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01005953 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005954 execute( TC_paging_cs_from_bts() );
5955 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
5956 execute( TC_paging_cs_from_sgsn_sign() );
5957 execute( TC_paging_cs_from_sgsn_ptp() );
5958 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
5959 execute( TC_paging_ps_from_sgsn_sign() );
5960 execute( TC_paging_ps_from_sgsn_ptp() );
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07005961 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
5962 execute( TC_paging_cs_multi_ms_imsi() );
5963 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02005964 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
5965 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01005966 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
5967 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02005968
5969 /* EGPRS specific test cases */
5970 execute( TC_egprs_pkt_chan_req_signalling() );
5971 execute( TC_egprs_pkt_chan_req_one_phase() );
5972 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07005973 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07005974 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07005975 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02005976
5977 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07005978
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01005979 /* Immediate Assignment on AGCH/PCH */
5980 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
5981 execute( TC_pcuif_fh_imm_ass_ul() );
5982 execute( TC_pcuif_fh_imm_ass_dl() );
5983 /* Packet Uplink/Downlink Assignment on PACCH */
5984 execute( TC_pcuif_fh_pkt_ass_ul() );
5985 execute( TC_pcuif_fh_pkt_ass_dl() );
5986 execute( TC_multitrx_multims_alloc() );
5987 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
5988 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
5989 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
5990
Pau Espin Pedrole1303052020-11-16 11:13:51 +01005991 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07005992
5993 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005994 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005995 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005996 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005997 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005998 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005999 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01006000 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006001 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006002 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
6003 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006004 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
6005 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
6006 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006007 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
6008 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006009 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
6010 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
6011 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006012 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006013
6014 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006015 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006016 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006017}
6018
Harald Weltea419df22019-03-21 17:23:04 +01006019}