blob: 8012daa14436de2d952d37c0064ba6daccd3d1cc [file] [log] [blame]
Harald Weltea0895f92018-03-08 11:51:23 +01001module PCU_Tests {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002
3/* "RAW" PCU tests: Talk directly to the PCU socket of OsmoPCU on the one hand side (emulating
4 the BTS/BSC side PCU socket server) and the Gb interface on the other hand side. No NS/BSSGP
5 Emulation is used; rather, we simply use the NS_CodecPort to implement both standard and non-
6 standard procedures on the NS and BSSGP level. The goal of these tests is to test exactly
7 those NS and BSSGP implementations on the BSS (PCU) side. */
8
9/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +070010 * (C) 2019-2020 Vadim Yanitskiy <axilirator@gmail.com>
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020011 * All rights reserved.
12 *
13 * Released under the terms of GNU General Public License, Version 2 or
14 * (at your option) any later version.
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18
19friend module PCU_Tests_NS;
20
21import from General_Types all;
22import from Osmocom_Types all;
23import from GSM_Types all;
24import from GSM_RR_Types all;
25
26import from Osmocom_VTY_Functions all;
27import from TELNETasp_PortType all;
28
29import from MobileL3_GMM_SM_Types all;
30import from RLCMAC_CSN1_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020031import from RLCMAC_CSN1_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020032import from RLCMAC_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020033import from RLCMAC_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020034
35import from MobileL3_CommonIE_Types all;
36import from L3_Templates all;
37
38import from NS_Types all;
39import from BSSGP_Types all;
40import from Osmocom_Gb_Types all;
41
42import from BSSGP_Emulation all; /* BssgpConfig */
43import from NS_Emulation all; /* NSConfiguration */
44
45import from UD_Types all;
46import from PCUIF_Types all;
47import from PCUIF_CodecPort all;
48import from PCUIF_Components all;
49import from IPL4asp_Types all;
50import from Native_Functions all;
51import from SGSN_Components all;
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +020052import from GPRS_Components all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020053
Daniel Willmann535aea62020-09-21 13:27:08 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010059import from IPA_Emulation all;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +010060import from Osmocom_CTRL_Types all;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010061import from Osmocom_CTRL_Adapter all;
62import from Osmocom_CTRL_Functions all;
63
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020064modulepar {
65 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
66
67 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Daniel Willmann535aea62020-09-21 13:27:08 +020068
69 charstring mp_pcu_statsd_ip := "127.0.0.1";
70 integer mp_pcu_statsd_port := 8125;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010071
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +020072 charstring mp_ctrl_neigh_ip := ""; /* Use new PCUIF over IPA multiplex for Neigh Addr Resolution */
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010073 integer mp_ctrl_neigh_port := 4248;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020074}
75
76
77/* 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 +010078friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
79:= {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070080 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010081 flags := flags,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +010082 trx := ts_PCUIF_InfoTrxs_def(GPRS_Components.mp_base_arfcn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020083 bsic := 7,
84 mcc := 262,
85 mnc := 42,
86 mnc_3_digits := 0,
87 lac := 13135,
88 rac := 0,
89 nsei := mp_nsconfig.nsei,
90 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
91 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
92 cell_id := 20960,
93 repeat_time := 5 * 50,
94 repeat_count := 3,
Harald Welte5339b2e2020-10-04 22:52:56 +020095 bvci := mp_gb_cfg.bvc[0].bvci,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020096 t3142 := 20,
97 t3169 := 5,
98 t3191 := 5,
99 t3193_10ms := 160,
100 t3195 := 5,
Pau Espin Pedrol76de1662021-03-01 17:40:58 +0100101 n3101 := 10,
102 n3103 := 4,
103 n3105 := 8,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200104 cv_countdown := 15,
105 dl_tbf_ext := 250 * 10, /* ms */
106 ul_tbf_ext := 250 * 10, /* ms */
107 initial_cs := 2,
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100108 initial_mcs := 1,
Harald Welte90f19742020-11-06 19:34:40 +0100109 nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
110 local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
111 remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +0100112 remote_addr := f_PCUIF_RemoteAddr(
Harald Welte90f19742020-11-06 19:34:40 +0100113 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 +0200114}
115
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100116/* Passed in RAN-INFO message from emulated neighbor using RIM */
117const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
118const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
119const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
120const octetstring si_default := si1_default & si3_default & si13_default;
121
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +0100122const MultislotCap_GPRS mscap_gprs_def := {
123 gprsmultislotclass := '00011'B,
124 gprsextendeddynalloccap := '0'B
125};
126const MultislotCap_EGPRS mscap_egprs_def := {
127 egprsmultislotclass := '00011'B,
128 egprsextendeddynalloccap := '0'B
129};
130template (value) MSRadioAccessCapabilityV ms_racap_gprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, omit) };
131template (value) MSRadioAccessCapabilityV ms_racap_egprs_def := { ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs_def, mscap_egprs_def) };
132
133const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs_def := {
134 gprsmultislotclass := '00011'B,
135 gprsextendeddynalloccap := '0'B
136};
137const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs_def := {
138 egprsmultislotclass := '00011'B,
139 egprsextendeddynalloccap := '0'B
140};
141template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, omit)) };
142template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs_def := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs_def, bssgp_mscap_egprs_def)) };
143
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200144type record lqual_range {
145 /* component reference to the IPA_Client component used for RSL */
146 uint8_t low,
147 uint8_t high
148}
149
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100150type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700151 /* PCU interface abstraction component */
152 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700153
Daniel Willmann535aea62020-09-21 13:27:08 +0200154 /* StatsD */
155 var StatsD_Checker_CT vc_STATSD;
156
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200157 /* Connection to the PCUIF component */
158 port RAW_PCU_MSG_PT PCUIF;
159 /* VTY connection to the PCU */
160 port TELNETasp_PT PCUVTY;
161
162 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
163 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
164 {low := 5, high := 8},
165 {low := 7, high := 13},
166 {low := 12,high := 35}};
167 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
168 {low := 5, high := 8},
169 {low := 7, high := 13},
170 {low := 12,high := 15},
171 {low := 14, high := 17},
172 {low := 16, high := 18},
173 {low := 17,high := 20},
174 {low := 19, high := 24},
175 {low := 23,high := 35}};
176 var uint8_t g_cs_initial_dl := 1;
177 var uint8_t g_cs_initial_ul := 1;
178 var uint8_t g_mcs_initial_dl := 1;
179 var uint8_t g_mcs_initial_ul := 1;
180 var uint8_t g_cs_max_dl := 4;
181 var uint8_t g_cs_max_ul := 4;
182 var uint8_t g_mcs_max_dl := 9;
183 var uint8_t g_mcs_max_ul := 9;
184
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200185 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200186
187 /* Guard timeout */
188 timer g_T_guard := 60.0;
189};
190
191private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
192 [] g_T_guard.timeout {
193 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700194 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200195 }
196}
197
198private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
199 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
200 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
201
202 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
203 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
204}
205
206private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
207 var charstring cmd;
208
209 cmd := "cs link-quality-ranges" &
210 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
211 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
212 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
213 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
214 f_vty_config2(PCUVTY, {"pcu"}, cmd);
215
216 cmd := "mcs link-quality-ranges" &
217 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
218 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
219 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
220 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
221 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
222 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
223 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
224 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
225 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
226 f_vty_config2(PCUVTY, {"pcu"}, cmd);
227}
228
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100229private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
230 f_pcuvty_set_neigh_caches(0, 0);
231}
232
233private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
234runs on RAW_PCU_Test_CT {
235 if (neigh_cache_secs == -1) {
236 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
237 } else {
238 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
239 }
240 if (si_cache_secs == -1) {
241 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
242 } else {
243 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
244 }
245}
246
Pau Espin Pedrole8a94442021-11-15 17:05:46 +0100247private function f_pcuvty_set_timer(integer t, integer val)
248runs on RAW_PCU_Test_CT {
249 if (t >= 0) {
250 f_vty_config2(PCUVTY, {"pcu"}, "timer T" & int2str(t) & " " & int2str(val));
251 } else {
252 f_vty_config2(PCUVTY, {"pcu"}, "timer X" & int2str(t * -1) & " " & int2str(val));
253 }
254}
255
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100256private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200257 map(self:PCUVTY, system:PCUVTY);
258 f_vty_set_prompts(PCUVTY);
259 f_vty_transceive(PCUVTY, "enable");
260
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100261 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
262 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200263 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
264 } else {
265 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
266 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200267
268 if (g_force_two_phase_access) {
269 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
270 } else {
271 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
272 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200273}
274
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200275function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200276runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200277 /* Start the guard timer */
278 g_T_guard.start;
279 activate(as_Tguard_RAW());
280
281 /* Init PCU interface component */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100282 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF") alive;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200283 connect(vc_PCUIF:MTC, self:PCUIF);
284 map(vc_PCUIF:PCU, system:PCU);
285
286 /* Create one BTS component (we may want more some day) */
Pau Espin Pedrol835fd302022-02-22 17:04:06 +0100287 vc_BTS := RAW_PCU_BTS_CT.create("BTS") alive;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200288 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
289 connect(vc_BTS:TC, self:BTS);
290
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100291 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200292
Daniel Willmann535aea62020-09-21 13:27:08 +0200293 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
294 /* This is normally done in the ConnHdlr component, but here
295 * the Test_CT doubles as ConnHdlr */
296 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
297
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200298 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100299 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind), true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200300
301 /* Wait until the BTS is ready (SI13 negotiated) */
302 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
303}
304
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700305/* Register TLLI of each allocated GprsMS instance */
306private function f_multi_ms_bssgp_register()
307runs on RAW_PCU_Test_CT {
308 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
309 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
310 }
311}
312
313/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
314private function f_multi_ms_establish_tbf(boolean do_activate := false)
315runs on RAW_PCU_Test_CT {
316 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
317 /* Establish an Uplink TBF */
318 f_ms_establish_ul_tbf(g_ms[i]);
319
320 /* Send a random block, so this TBF becomes "active" */
321 if (do_activate) {
322 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +0100323 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700324 var octetstring dummy := f_rnd_octstring(12);
325 var RlcmacDlBlock dl_block;
326 var uint32_t poll_fn;
327
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200328 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 +0700329 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
330 }
331 }
332}
333
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100334private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
335 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
336runs on RAW_PCU_Test_CT return PollFnCtx {
337 var PollFnCtx pollctx;
338
339 /* Single block (two phase) packet access */
340 var uint16_t ra := bit2int(chan_req_sb);
341 if (g_force_two_phase_access) {
342 /* If 2phase access is enforced by the network, then let's
343 * request a One phase packet access, we'll receive a single block
344 * anyway
345 */
346 ra := bit2int(chan_req_def);
347 }
348
349 /* Establish an Uplink TBF */
350 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
351 f_ms_establish_ul_tbf(ms);
352
353 /* Make sure we've got an Uplink TBF assignment */
354 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
355 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
356 f_shutdown(__BFILE__, __LINE__);
357 }
358
359 /* Send PACKET RESOURCE REQUEST
360 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
361 */
362 if (istemplatekind(pkt_res_req, "omit")) {
363 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
364 }
365
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200366 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 +0100367 /* Store 1st UlTBF context before receiving next one, will
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100368 * overwrite the TS allocation on MS with info from new UL TBF:
369 */
370 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
371 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
372 return pollctx;
373}
374
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200375testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200376 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100377 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200378 timer T;
379
380 /* Initialize NS/BSSGP side */
381 f_init_bssgp();
382
383 /* Initialize the PCU interface abstraction */
384 f_init_raw(testcasename());
385
386 /* Establish BSSGP connection to the PCU */
387 f_bssgp_establish();
388
389 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
390
391 T.start(2.0);
392 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100393 [] 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 +0200394 setverdict(pass);
395 }
396 [] T.timeout {
397 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
398 }
399 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700400
401 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200402}
403
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100404/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
405testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
406 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200407 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100408 var RlcmacDlBlock dl_block;
409 var octetstring data := f_rnd_octstring(10);
410 var uint32_t sched_fn;
411 var uint32_t dl_fn;
412 var GprsMS ms;
413 timer T;
414
415 /* Initialize NS/BSSGP side */
416 f_init_bssgp();
417 /* Initialize GPRS MS side */
418 f_init_gprs_ms();
419 ms := g_ms[0]; /* We only use first MS in this test */
420
421 /* Initialize the PCU interface abstraction */
422 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
423
424 /* Establish BSSGP connection to the PCU */
425 f_bssgp_establish();
426 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
427
428 /* Establish an Uplink TBF */
429 f_ms_establish_ul_tbf(ms);
430
431 /* Send one UL block (with TLLI since we are in One-Phase Access
432 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +0200433 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 +0100434 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
435 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
436 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
437
438 /* UL block should be received in SGSN */
439 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
440
441 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
442 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
443 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
444
445 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
446 f_sleep(X2002);
447 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
448
449 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
450 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
451
452 T.start(2.0);
453 alt {
454 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
455 setverdict(pass);
456 }
457 [] T.timeout {
458 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
459 f_shutdown(__BFILE__, __LINE__);
460 }
461 }
462
463 /* Make sure we don't receive data for that TBF since it was released
464 * before. Also check our TBF is not polled for UL. */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200465 f_pcuif_rx_data_req_pdtch(data_msg);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100466 if (data_msg.dl_block == omit) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200467 /* IDLE block, expected on new PCU versions */
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200468 } else {
469 setverdict(fail, "Unexpected dl_block", data_msg.dl_block);
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100470 f_shutdown(__BFILE__, __LINE__);
471 }
472
473 /* New data arrives, PCU should page the MS since no TBF active exists: */
474 /* Send some more data, it will never reach the MS */
475 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
476 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
477
478 f_shutdown(__BFILE__, __LINE__, final := true);
479}
480
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200481/* Test of correct Timing Advance at the time of TBF establishment
482 * (derived from timing offset of the Access Burst). */
483testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200484 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200485
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200486 /* Initialize GPRS MS side */
487 f_init_gprs_ms();
488 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200489 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100490 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200491
492 /* We cannot send too many TBF requests in a short time because
493 * at some point the PCU will fail to allocate a new TBF. */
494 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
495 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200496 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700497 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200498
499 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200500 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700501 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200502 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700503 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700504 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200505 }
506 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700507
508 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200509}
510
Vadim Yanitskiy866f8702021-05-26 14:50:27 +0200511/* Verify Timing Advance value indicated in Packet Uplink ACK/NACK message
512 * sent in response to the first Uplink block after resource allocation. */
513testcase TC_ta_ul_ack_nack_first_block() runs on RAW_PCU_Test_CT {
514 var GprsMS ms := valueof(t_GprsMS_def);
515 var PacketUlAckNack ul_ack_nack;
516 var PacketTimingAdvance pkt_ta;
517 var RlcmacDlBlock dl_block;
518 var uint32_t sched_fn;
519
520 /* Initialize NS/BSSGP side */
521 f_init_bssgp();
522
523 /* Initialize the PCU interface abstraction */
524 f_init_raw(testcasename());
525
526 /* Establish BSSGP connection to the PCU */
527 f_bssgp_establish();
528 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
529
530 /* Establish an Uplink TBF */
531 f_ms_establish_ul_tbf(ms);
532
533 /* In a busy network, there can be a significant delay between resource
534 * allocation (Packet Uplink Assignment above) and the actual time when
535 * the MS is allowed to transmit the first Uplink data block. */
536
537 /* Simulate a delay > 0 */
538 ms.ta := 2;
539
540 /* We're in One-Phase Access contention resoultion, include TLLI */
541 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
542 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
543
544 ul_ack_nack := dl_block.ctrl.payload.u.ul_ack_nack;
545 if (ispresent(ul_ack_nack.gprs.pkt_ta)) {
546 pkt_ta := ul_ack_nack.gprs.pkt_ta;
547 } else if (ispresent(ul_ack_nack.egprs.pkt_ta)) {
548 pkt_ta := ul_ack_nack.egprs.pkt_ta;
549 } else {
550 setverdict(fail, "PacketTimingAdvance IE is not present");
551 f_shutdown(__BFILE__, __LINE__);
552 }
553
554 if (not ispresent(pkt_ta.val)) {
555 setverdict(fail, "Timing Advance value is not present");
556 f_shutdown(__BFILE__, __LINE__);
557 } else if (pkt_ta.val != ms.ta) {
558 setverdict(fail, "Timing Advance mismatch: expected ",
559 ms.ta, ", but received ", pkt_ta.val);
560 f_shutdown(__BFILE__, __LINE__);
561 }
562}
563
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200564/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
565 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
566 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
567 * no active TBF exists at the moment of establishment (idle mode). */
568testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100569 var GprsMS ms := valueof(t_GprsMS_def);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200570
571 /* Initialize NS/BSSGP side */
572 f_init_bssgp();
573
574 /* Initialize the PCU interface abstraction */
575 f_init_raw(testcasename());
576
577 /* Establish BSSGP connection to the PCU */
578 f_bssgp_establish();
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100579 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200580
581 /* SGSN sends some DL data, PCU will initiate Packet Downlink
582 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100583 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(10)));
584 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200585
586 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
587 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
588 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy37f33332021-02-21 00:04:23 +0100589 if (ms.dl_tbf.rr_imm_ass.payload.imm_ass.timing_advance != 0) {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700590 setverdict(fail, "Timing Advance value doesn't match");
591 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700592
593 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200594}
595
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200596/* Verify that the PCU generates idle blocks in PTCCH/D
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200597 * while neither Uplink nor Downlink TBF is established. */
598testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100599 var BTS_PTCCH_Block pcu_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200600 timer T;
601
602 /* Initialize the PCU interface abstraction */
603 f_init_raw(testcasename());
604
605 /* Sent an RTS.req for PTCCH/D */
606 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
607 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
608 arfcn := 871, block_nr := 0));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100609
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200610 T.start(5.0);
611 alt {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200612 [] BTS.receive(tr_PCUIF_DATA_PTCCH(0,
613 tr_PCUIF_DATA(0, 7, sapi := PCU_IF_SAPI_PTCCH),
614 omit)) {
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200615 }
616 [] as_rx_ptcch(pcu_msg, tr_PTCCHDownlinkMsg) {
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +0100617 setverdict(fail, "Expected IDLE block instead of PTCCH/D block");
618 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol332aba82021-09-22 14:50:35 +0200619 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200620 [] BTS.receive(PCUIF_Message:?) { repeat; }
621 [] T.timeout {
622 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700623 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200624 }
625 }
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +0100626 log("Decoded PTCCH/D message: ", pcu_msg.dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700627
628 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200629}
630
631/* Test of correct Timing Advance during an active Uplink TBF.
632 *
633 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
634 * are not continuous and there can be long time gaps between them. This happens
635 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
636 * significantly change between such rare Uplink transmissions, so GPRS introduces
637 * additional mechanisms to control Timing Advance, and thus reduce interference
638 * between neighboring TDMA time-slots.
639 *
640 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
641 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
642 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
643 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
644 * among with the initial Timing Advance value. And here PTCCH comes to play.
645 *
646 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
647 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
648 * continuously. To ensure continuous measurements of the signal propagation
649 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
650 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
651 *
652 * The purpose of this test case is to verify the assignment of Timing Advance
653 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
654 * first establishes several Uplink TBFs, but does not transmit any Uplink
655 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
656 * indications to the PCU, checking the correctness of two received PTCCH/D
657 * messages (period of PTCCH/D is two multi-frames).
658 */
659
660/* List of ToA values for Access Bursts to be sent on PTCCH/U,
661 * each ToA (Timing of Arrival) value is in units of 1/4 of
662 * a symbol (i.e. 1 symbol is 4 QTA units). */
663type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
664const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
665 0, 0, 0, 0,
666 0, 0, 0, 0,
667 0, 0, 0, 0,
668 0, 0, 0, 0
669};
670
671private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
672 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
673runs on RAW_PCU_Test_CT {
674 var RAW_PCU_Event event;
675 var integer ss;
676
677 /* Send Access Bursts on PTCCH/U for every TA Index */
678 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
679 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700680 if (ss < 0) { /* Shall not happen */
681 f_shutdown(__BFILE__, __LINE__);
682 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200683
684 log("Sending an Access Burst on PTCCH/U",
685 ", sub-slot=", ss, " (TAI)",
686 ", fn=", event.data.tdma_fn,
687 ", ToA=", toa_map[ss], " (QTA)");
688 /* TODO: do we care about RA and burst format? */
689 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
690 ra := oct2int('3A'O),
691 is_11bit := 0,
692 burst_type := BURST_TYPE_0,
693 fn := event.data.tdma_fn,
694 arfcn := 871,
695 qta := toa_map[ss],
696 sapi := PCU_IF_SAPI_PTCCH));
697 repeat;
698 }
699}
700
701private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
702 template PTCCHDownlinkMsg t_ta_msg)
703runs on RAW_PCU_Test_CT {
704 var PTCCHDownlinkMsg ta_msg;
705 var PCUIF_Message pcu_msg;
706 timer T;
707
708 /* First, send an RTS.req for the upcoming PTCCH/D block */
709 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
710 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
711 arfcn := 871, block_nr := 0));
712 T.start(2.0);
713 alt {
714 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
715 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
716 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
717 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
718 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
719 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
720 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
721 log("Rx PTCCH/D message: ", ta_msg);
722
723 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700724 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200725 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
726 }
727 }
728 [] BTS.receive { repeat; }
729 [] T.timeout {
730 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200731 }
732 }
733}
734
735testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
736 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200737 var GprsMS ms;
738
739 /* Initialize GPRS MS side */
740 f_init_gprs_ms();
741 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200742
743 /* Initialize the PCU interface abstraction */
744 f_init_raw(testcasename());
745
746 /* Enable forwarding of PTCCH/U TDMA events to us */
747 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
748
749 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
750 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200751 /* Establish an Uplink TBF */
752 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200753
754 /* We expect incremental TFI/USF assignment (dynamic allocation) */
755 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200756 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200757 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700758 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200759 }
760
761 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200762 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200763 setverdict(fail, "Failed to match Timing Advance Index for #", i);
764 /* Keep going, the current OsmoPCU does not assign TA Index */
765 }
766 }
767
768 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
769 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
770 for (var integer i := 0; i < 7; i := i + 1) {
771 /* ToA in units of 1/4 of a symbol */
772 toa_map[i] := (i + 1) * 7 * 4;
773 }
774
775 /* Now we have all 7 TBFs established in one-phase access mode,
776 * however we will not be sending any data on them. Instead, we
777 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
778 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
779 *
780 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
781 * time-slots, so at the moment of scheduling a PTCCH/D block
782 * the PCU has odd number of PTCCH/U Access Bursts received. */
783 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
784 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
785 /* Other values are not known (yet) */
786 tai3_ta := ?));
787 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
788 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
789 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
790 /* Other values are out of our interest */
791 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700792
793 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200794}
795
796/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
797 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
798 *
799 * NOTE: the ranges are intentionally overlapping because OsmoPCU
800 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
801private template integer CS1_lqual_dB_range := (-infinity .. 6);
802private template integer CS2_lqual_dB_range := (5 .. 8);
803private template integer CS3_lqual_dB_range := (7 .. 13);
804private template integer CS4_lqual_dB_range := (12 .. infinity);
805
806testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200807 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200808 var GprsMS ms;
809 var uint32_t unused_fn, sched_fn;
810 var uint4_t cv;
811
812 /* Initialize GPRS MS side */
813 f_init_gprs_ms();
814 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200815
816 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100817 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200818
819 f_pcuvty_set_allowed_cs_mcs();
820 f_pcuvty_set_link_quality_ranges();
821
822 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200823 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200824
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200825
826 /* The actual / old link quality values. We need to keep track of the old
827 * (basically previous) link quality value, because OsmoPCU actually
828 * changes the coding scheme if not only the actual, but also the old
829 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200831 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200832
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200833 /* Send one UL block (with TLLI since we are in One-Phase Access
834 contention resoultion) and make sure it is ACKED fine. */
835 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
836 /* 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 +0200837 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 +0200838 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
839 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
840 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200841
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200842 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
843 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200844 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 lqual_old := ms.lqual_cb;
846 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200847
848 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200849 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
850 if (i > g_bs_cv_max) {
851 cv := 15;
852 } else {
853 cv := i;
854 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200855
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200856 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
857
858 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
859 f_rx_rlcmac_dl_block(dl_block, unused_fn);
860 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
861 continue;
862 }
863 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
864 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
865 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
866 f_shutdown(__BFILE__, __LINE__);
867 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200868
869 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
870 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
871
872 /* Match the received Channel Coding Command. Since we are increasing
873 * the link quality value on each iteration and not decreasing, there
874 * is no need to check the both old and current link quality values. */
875 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200876 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200877 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
878 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
879 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
880 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
881 }
882
883 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
884 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200885 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200886 }
887 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700888
889 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200890}
891
892/* Test the max UL CS set by VTY works fine */
893testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200894 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200895 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200896 var uint32_t unused_fn, sched_fn;
897 var GprsMS ms;
898
899 /* Initialize GPRS MS side */
900 f_init_gprs_ms();
901 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200902
903 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100904 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200905
906 /* Set initial UL CS to 3 */
907 g_cs_initial_ul := 3;
908 f_pcuvty_set_allowed_cs_mcs();
909 f_pcuvty_set_link_quality_ranges();
910
911 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200912 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200913
914 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200915 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200916
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200917 /* Send one UL block (with TLLI since we are in One-Phase Access
918 contention resoultion) and make sure it is ACKED fine. */
919 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
920 /* 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 +0200921 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 +0200922 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
923 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
924 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200925
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200926 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
927 while (true) {
928 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
929 f_rx_rlcmac_dl_block(dl_block, unused_fn);
930 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
931 continue;
932 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200933
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200934 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
935 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
936 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
937 f_shutdown(__BFILE__, __LINE__);
938 break;
939 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200940
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200941 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200942 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200943 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200944 if (last_ch_coding != CH_CODING_CS3) {
945 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200946 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200947 }
948
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200949 /* Remaining UL blocks are used to make sure regardless of initial
950 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200951 /* 0 dB, make sure we downgrade CS */
952 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200953 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200954 f_ms_tx_ul_data_block_multi(ms, 5);
955 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
956 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
957 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200958
959 if (last_ch_coding != CH_CODING_CS1) {
960 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200961 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200962 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700963
964 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200965}
966
967/* Test the max UL CS set by VTY works fine */
968testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200969 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200970 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200971 var uint32_t unused_fn, sched_fn;
972 var GprsMS ms;
973
974 /* Initialize GPRS MS side */
975 f_init_gprs_ms();
976 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200977
978 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100979 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200980
981 /* Set maximum allowed UL CS to 3 */
982 g_cs_max_ul := 3;
983 f_pcuvty_set_allowed_cs_mcs();
984 f_pcuvty_set_link_quality_ranges();
985
986 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200987 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200988
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200989 /* Send one UL block (with TLLI since we are in One-Phase Access
990 contention resoultion) and make sure it is ACKED fine. */
991 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
992 /* 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 +0200993 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 +0200994 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
995 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
996 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200997
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200998 ms.lqual_cb := 40*10; /* 40 dB */
999 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001000
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001001 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1002 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001003
1004 if (last_ch_coding != CH_CODING_CS3) {
1005 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +02001006 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001007 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001008
1009 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001010}
1011
Pau Espin Pedrol75122592020-11-03 15:22:59 +01001012/* Test the initial DL CS set by VTY works fine */
1013testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
1014 var octetstring data := f_rnd_octstring(10);
1015 var CodingScheme exp_dl_cs_mcs;
1016 var RlcmacDlBlock dl_block;
1017 var uint32_t poll_fn;
1018 var GprsMS ms;
1019
1020 /* Initialize NS/BSSGP side */
1021 f_init_bssgp();
1022 /* Initialize GPRS MS side */
1023 f_init_gprs_ms();
1024 ms := g_ms[0]; /* We only use first MS in this test */
1025
1026 /* Initialize the PCU interface abstraction */
1027 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1028
1029 /* Set initial allowed DL CS to 3 */
1030 g_cs_initial_dl := 3;
1031 exp_dl_cs_mcs := CS_3;
1032 /* Set maximum allowed UL CS to 4 */
1033 g_cs_max_dl := 4;
1034 f_pcuvty_set_allowed_cs_mcs();
1035 f_pcuvty_set_link_quality_ranges();
1036
1037 /* Establish BSSGP connection to the PCU */
1038 f_bssgp_establish();
1039 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1040
1041 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1042 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1043 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1044
1045 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1046 f_sleep(X2002);
1047 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1048
1049 /* ACK the DL block */
1050 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1051 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1052 f_dl_block_ack_fn(dl_block, poll_fn));
1053
1054 f_shutdown(__BFILE__, __LINE__, final := true);
1055}
1056
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001057/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001058function 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 +01001059 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001060 var RlcmacDlBlock prev_dl_block, dl_block;
1061 var uint32_t ack_fn;
1062 var uint32_t fn;
1063 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001064 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001065 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001066 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
1067 var integer bsn_mod;
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01001068 var template (present) CodingScheme exp_tmp_csmcs;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001069
1070 if (using_egprs) {
1071 exp_tmp_csmcs := mcs_egprs_any;
1072 bsn_mod := 2048;
1073 } else {
1074 exp_tmp_csmcs := cs_gprs_any;
1075 bsn_mod := 128;
1076 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001077
1078 /* Establish BSSGP connection to the PCU */
1079 f_bssgp_establish();
1080
1081 ms := g_ms[0]; /* We only use first MS in this test */
1082 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1083
1084 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001085 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001086 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1087
1088 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1089 f_sleep(X2002);
1090
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001091 for (var integer i := 0; i < 800; i := i + 1) {
1092 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001093 f_rx_rlcmac_dl_block(dl_block, fn);
1094
1095 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
1096 /* No more data to receive, done */
1097 break;
1098 }
1099
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001100 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001101
1102 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001103 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001104
1105 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001106 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001107 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001108 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 +01001109 if (tx_data_remain != 0) {
1110 /* Submit more data from time to time to keep the TBF ongoing */
1111 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1112 tx_data_remain := tx_data_remain - 1;
1113 }
1114 }
1115 prev_dl_block := dl_block;
1116 }
1117
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001118 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1119 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001120
1121
1122 f_shutdown(__BFILE__, __LINE__, final := true);
1123}
1124
1125/* Verify DL CS above "cs max" set by VTY is never used */
1126testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1127 /* Initialize NS/BSSGP side */
1128 f_init_bssgp();
1129 /* Initialize GPRS MS side */
1130 f_init_gprs_ms();
1131
1132 /* Initialize the PCU interface abstraction */
1133 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1134
1135 /* Set maximum allowed DL CS to 3 */
1136 g_cs_initial_dl := 1;
1137 g_cs_max_dl := 3;
1138 f_pcuvty_set_allowed_cs_mcs();
1139 f_pcuvty_set_link_quality_ranges();
1140
1141 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1142}
1143
1144/* Check DL CS4 is used in good link conditions if allowed by config */
1145testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1146 /* Initialize NS/BSSGP side */
1147 f_init_bssgp();
1148 /* Initialize GPRS MS side */
1149 f_init_gprs_ms();
1150
1151 /* Initialize the PCU interface abstraction */
1152 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1153
1154 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1155 g_cs_initial_dl := 1;
1156 g_cs_max_dl := 4;
1157 f_pcuvty_set_allowed_cs_mcs();
1158 f_pcuvty_set_link_quality_ranges();
1159
1160 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1161}
1162
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001163/* Test the initial UL MCS set by VTY works fine */
1164testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1165 var RlcmacDlBlock dl_block;
1166 var PollFnCtx pollctx;
1167 var EgprsChCodingCommand last_ch_coding;
1168 var uint32_t unused_fn, sched_fn;
1169 var GprsMS ms;
1170 var CodingScheme exp_ul_mcs;
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001171
1172 /* Initialize GPRS MS side */
1173 f_init_gprs_ms();
1174 ms := g_ms[0]; /* We only use first MS in this test */
1175
1176 /* Initialize the PCU interface abstraction */
1177 f_init_raw(testcasename());
1178
1179 /* Set initial UL MCS to 3 */
1180 g_mcs_initial_ul := 3;
1181 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1182 f_pcuvty_set_allowed_cs_mcs();
1183 f_pcuvty_set_link_quality_ranges();
1184
1185 /* Take lqual (dB->cB) so that we stay in that MCS */
1186 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1187
1188 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001189 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 +01001190
1191 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1192 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1193 f_shutdown(__BFILE__, __LINE__);
1194 }
1195
1196 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1197 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1198
1199 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1200 while (true) {
1201 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1202 f_rx_rlcmac_dl_block(dl_block, unused_fn);
1203 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1204 continue;
1205 }
1206
1207 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1208 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1209 f_shutdown(__BFILE__, __LINE__);
1210 break;
1211 }
1212
1213 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1214 break;
1215 }
1216 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1217 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1218 f_shutdown(__BFILE__, __LINE__);
1219 }
1220
1221 /* Remaining UL blocks are used to make sure regardless of initial
1222 * lqual, we can go lower at any time
1223 * 0 dB, make sure we downgrade MCS */
1224 ms.lqual_cb := 0;
1225 /* 5 UL blocks, check we are in same initial MCS: */
1226 f_ms_tx_ul_data_block_multi(ms, 5);
1227 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1228 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1229 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1230
1231 if (last_ch_coding != CH_CODING_MCS1) {
1232 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1233 f_shutdown(__BFILE__, __LINE__);
1234 }
1235
1236 f_shutdown(__BFILE__, __LINE__, final := true);
1237}
1238
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001239/* Test the maximum UL MCS set by VTY works fine */
1240testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1241 var RlcmacDlBlock dl_block;
1242 var EgprsChCodingCommand last_ch_coding;
1243 var PollFnCtx pollctx;
1244 var uint32_t unused_fn, sched_fn;
1245 var GprsMS ms;
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001246
1247 /* Initialize GPRS MS side */
1248 f_init_gprs_ms();
1249 ms := g_ms[0]; /* We only use first MS in this test */
1250
1251 /* Initialize the PCU interface abstraction */
1252 f_init_raw(testcasename());
1253
1254 /* Set maximum allowed UL MCS to 5 */
1255 g_mcs_max_ul := 5;
1256 f_pcuvty_set_allowed_cs_mcs();
1257 f_pcuvty_set_link_quality_ranges();
1258
1259 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001260 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 +01001261 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1262 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1263
1264 ms.lqual_cb := 40*10; /* 40 dB */
1265 f_ms_tx_ul_data_block_multi(ms, 16);
1266
1267 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1268 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1269
1270 if (last_ch_coding != CH_CODING_MCS5) {
1271 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1272 f_shutdown(__BFILE__, __LINE__);
1273 }
1274
1275 f_shutdown(__BFILE__, __LINE__, final := true);
1276}
1277
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001278/* Test the initial DL CS set by VTY works fine */
1279testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1280 var octetstring data := f_rnd_octstring(10);
1281 var CodingScheme exp_dl_cs_mcs;
1282 var RlcmacDlBlock dl_block;
1283 var uint32_t poll_fn;
1284 var GprsMS ms;
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001285
1286 /* Initialize NS/BSSGP side */
1287 f_init_bssgp();
1288 /* Initialize GPRS MS side */
1289 f_init_gprs_ms();
1290 ms := g_ms[0]; /* We only use first MS in this test */
1291
1292 /* Initialize the PCU interface abstraction */
1293 f_init_raw(testcasename());
1294
1295 /* Set initial allowed DL MCS to 3 */
1296 g_mcs_initial_dl := 3;
1297 exp_dl_cs_mcs := MCS_3;
1298 /* Set maximum allowed DL MCS to 4 */
1299 g_mcs_max_dl := 4;
1300 f_pcuvty_set_allowed_cs_mcs();
1301 f_pcuvty_set_link_quality_ranges();
1302
1303 /* Establish BSSGP connection to the PCU */
1304 f_bssgp_establish();
1305 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1306
1307 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001308 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs_def));
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001309 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1310
1311 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1312 f_sleep(X2002);
1313 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1314
1315 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001316 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1317 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 +01001318 f_dl_block_ack_fn(dl_block, poll_fn));
1319
1320 f_shutdown(__BFILE__, __LINE__, final := true);
1321}
1322
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001323/* Verify DL MCS above "mcs max" set by VTY is never used */
1324testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1325 /* Initialize NS/BSSGP side */
1326 f_init_bssgp();
1327 /* Initialize GPRS MS side */
1328 f_init_gprs_ms();
1329
1330 /* Initialize the PCU interface abstraction */
1331 f_init_raw(testcasename());
1332
1333 /* Set maximum allowed DL CS to 3 */
1334 g_mcs_initial_dl := 1;
1335 g_mcs_max_dl := 3;
1336 f_pcuvty_set_allowed_cs_mcs();
1337 f_pcuvty_set_link_quality_ranges();
1338
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01001339 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 +01001340}
1341
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001342/* Verify PCU drops TBF after some time of inactivity. */
1343testcase TC_t3141() runs on RAW_PCU_Test_CT {
1344 var PCUIF_info_ind info_ind;
1345 var template (value) TsTrxBtsNum nr;
1346 var BTS_PDTCH_Block data_msg;
1347 var GprsMS ms;
1348 var uint3_t rx_usf;
1349 timer T_3141 := 1.0;
1350 var boolean ul_tbf_usf_req := false;
1351
1352 /* Initialize NS/BSSGP side */
1353 f_init_bssgp();
1354 /* Initialize GPRS MS side */
1355 f_init_gprs_ms();
1356 ms := g_ms[0]; /* We only use first MS in this test */
1357
1358 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1359 /* Only use 1 PDCH to simplify test: */
1360 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
1361 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
1362 /* Initialize the PCU interface abstraction */
1363 f_init_raw(testcasename(), info_ind);
1364
1365 f_vty_config2(PCUVTY, {"pcu"}, "timer T3141 1");
1366
1367 /* Establish BSSGP connection to the PCU */
1368 f_bssgp_establish();
1369 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1370
1371 /* Establish a one-phase access Uplink TBF */
1372 f_ms_establish_ul_tbf(ms);
1373
1374 T_3141.start;
1375
1376 /* Now we wait for PCU to transmit our USF */
1377 nr := ts_TsTrxBtsNum;
1378 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1379 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1380 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1381 block_nr := nr.blk_nr));
1382
1383 alt {
1384 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1385 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1386 ?)) -> value data_msg {
1387 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1388 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1389 f_shutdown(__BFILE__, __LINE__);
1390 }
1391
1392 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1393 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1394 /* PCU requests our USF, transmit WITHOUT tlli to avoid contention resolution success */
1395 ul_tbf_usf_req := true;
1396 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))
1397 } else if (rx_usf == USF_UNUSED) {
1398 if (data_msg.raw.fn >= ms.ul_tbf.start_time_fn) {
1399 if (ul_tbf_usf_req) {
1400 /* TBF was dropped by T3141, success */
1401 setverdict(pass);
1402 break;
1403 } else {
1404 log("PCU never requested USF, unexpected");
1405 f_shutdown(__BFILE__, __LINE__);
1406 }
1407 } /* else: Keep waiting for TBF to be active by network */
1408 } else {
1409 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1410 f_shutdown(__BFILE__, __LINE__);
1411 }
1412
1413 /* Make sure we don't receive a Ul ACK/NACK with TLLI set: */
1414 if (match(data_msg.dl_block,
1415 tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1416 tr_UlAckNackGprs(tlli := ?,
1417 acknack_desc := ?,
1418 rel99 := *))))
1419 {
1420 log("Received UL ACK/NACK with TLLI set");
1421 f_shutdown(__BFILE__, __LINE__);
1422 }
1423
1424 nr := ts_TsTrxBtsNum;
1425 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1426 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1427 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1428 block_nr := nr.blk_nr));
1429 repeat;
1430 }
Pau Espin Pedrole5fe6e72022-02-22 15:15:00 +01001431 [ul_tbf_usf_req] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1432 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1433 omit)) {
1434 /* TBF was dropped by T3141, and PCU answered with an IDLE block to
1435 our last RTS.req because there's no longer any MS listening on
1436 the TS. */
1437 setverdict(pass);
1438 break;
1439 }
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02001440 [] T_3141.timeout {
1441 log("T_3141 expired but TBF is still active, unexpected");
1442 f_shutdown(__BFILE__, __LINE__);
1443 }
1444 [] BTS.receive {
1445 /* We should never receive non-dummy messages, aka UL ACK/NACK,
1446 * because we never sent the TLLI to the PCU */
1447 setverdict(fail, "Unexpected BTS message");
1448 f_shutdown(__BFILE__, __LINE__);
1449 }
1450 }
1451
1452 f_shutdown(__BFILE__, __LINE__, final := true);
1453}
1454
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001455/* Validate what happens when RACH to get UL TBF and then PCU receives no UL
1456 * data. It should end up in N3101 reaching N3101_MAX and finally triggering
1457 * T3169. See OS#5033 */
1458testcase TC_n3101_max_t3169() runs on RAW_PCU_Test_CT {
1459 var PCUIF_info_ind info_ind;
1460 var template (value) TsTrxBtsNum nr;
1461 var BTS_PDTCH_Block data_msg;
1462 var GprsMS ms;
1463 var uint3_t rx_usf;
1464 const integer N3101_MAX := 9; /* N3101 shall be greater than 8 */
1465 var integer n3101 := 0;
1466 timer T_3169 := 1.0;
1467
1468 /* Initialize NS/BSSGP side */
1469 f_init_bssgp();
1470 /* Initialize GPRS MS side */
1471 f_init_gprs_ms();
1472 ms := g_ms[0]; /* We only use first MS in this test */
1473
1474 /* Initialize the PCU interface abstraction */
1475 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1476 info_ind.n3101 := N3101_MAX;
1477 info_ind.t3169 := 1;
1478 f_init_raw(testcasename(), info_ind);
1479
1480 /* Establish BSSGP connection to the PCU */
1481 f_bssgp_establish();
1482 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1483
1484 /* Establish UL TBF */
1485 f_ms_establish_ul_tbf(ms);
1486
1487 /* Now we wait for PCU to transmit our USF */
1488 nr := ts_TsTrxBtsNum;
1489 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1490 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1491 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1492 block_nr := nr.blk_nr));
1493
1494 alt {
1495 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1496 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1497 ?)) -> value data_msg {
1498 if (ms.ul_tbf.usf[valueof(nr.ts_nr)] == USF_UNUSED) {
1499 setverdict(fail, "Unexpected ts_nr ", valueof(nr.ts_nr), " without USF allocated");
1500 f_shutdown(__BFILE__, __LINE__);
1501 }
1502
1503 rx_usf := f_rlcmac_dl_block_get_usf(data_msg.dl_block);
1504 if (rx_usf == ms.ul_tbf.usf[valueof(nr.ts_nr)]) {
1505 log("PCU requests our USF ", rx_usf, ", n3101=", n3101);
1506 n3101 := n3101 + 1;
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001507 if (n3101 > N3101_MAX + 1) { //+1: DL<->UL FN offset
1508 setverdict(fail, "Reached ", n3101, " > ", N3101_MAX + 1, " (N3101_MAX+1) and PCU still sends us USFs");
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001509 f_shutdown(__BFILE__, __LINE__);
1510 }
Pau Espin Pedrol73c5d372021-03-24 18:48:24 +01001511 } else if (rx_usf == USF_UNUSED and n3101 == N3101_MAX + 1) {
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001512 /* If we already received USFs for us and we don't receive them anymore, that means the TBF entered T3169 */
1513 log("PCU stopped requesting USF ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1514 if (not T_3169.running) {
1515 log("T3169 started");
1516 T_3169.start;
1517 }
1518 } else if(rx_usf == USF_UNUSED and n3101 > 0) {
1519 setverdict(fail, "PCU stopped requesting USFs too early: ", n3101, " < ", N3101_MAX, " (N3101_MAX)");
1520 f_shutdown(__BFILE__, __LINE__);
1521 } else {
1522 log("PCU requests ", rx_usf, ", we have ", ms.ul_tbf.usf[valueof(nr.ts_nr)]);
1523 }
1524 nr := ts_TsTrxBtsNum;
1525 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1526 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1527 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1528 block_nr := nr.blk_nr));
1529 repeat;
1530 }
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001531 /* We may already receive empty (idle) blocks before our own TTCN3 timer
1532 * triggers due to the TBF being released. Keep going until our T_3169 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001533 [n3101 == N3101_MAX + 1] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01001534 [] T_3169.timeout {
1535 log("T_3169 expired");
1536 /* Done in alt */
1537 }
1538 [] BTS.receive {
1539 setverdict(fail, "Unexpected BTS message");
1540 f_shutdown(__BFILE__, __LINE__);
1541 }
1542 }
1543
1544 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1545 /* USFs as per previous TBF since they were freed at expiration time: */
1546 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1547 var uint5_t old_tfi := ms.ul_tbf.tfi;
1548 f_ms_establish_ul_tbf(ms);
1549 if (old_tfi != ms.ul_tbf.tfi) {
1550 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1551 f_shutdown(__BFILE__, __LINE__);
1552 }
1553 for (var integer i := 0; i < 8; i := i +1) {
1554 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1555 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1556 f_shutdown(__BFILE__, __LINE__);
1557 }
1558 }
1559
1560 f_shutdown(__BFILE__, __LINE__, final := true);
1561}
1562
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001563
1564/* Verify after N3103_MAX is reached, T3169 is started and upon timeout TBF is
1565 freed and no longer available. Trigger it by sending a few UL blocks CTRL ACKING
1566 the final UL ACK sent at us. */
1567testcase TC_n3103_max_t3169() runs on RAW_PCU_Test_CT {
1568 var PCUIF_info_ind info_ind;
1569 var BTS_PDTCH_Block data_msg;
1570 var RlcmacDlBlock dl_block;
1571 var uint32_t sched_fn;
1572 var template (value) TsTrxBtsNum nr;
1573 var template RlcmacDlBlock exp_ul_ack;
1574 var template UlAckNackGprs exp_ul_ack_sub;
1575 var GprsMS ms;
1576 const integer N3103_MAX := 2; /* N3103 is usually somewhere 2-5 */
1577 var integer N3103 := 0;
1578 timer T_3169 := 1.0;
1579
1580 /* Initialize GPRS MS side */
1581 f_init_gprs_ms();
1582 ms := g_ms[0]; /* We only use first MS in this test */
1583
1584 /* Initialize the PCU interface abstraction */
1585 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1586 info_ind.n3103 := N3103_MAX;
1587 info_ind.t3169 := 1;
1588 f_init_raw(testcasename(), info_ind);
1589
1590 /* Establish an Uplink TBF */
1591 f_ms_establish_ul_tbf(ms);
1592
Pau Espin Pedrol93ae4522021-05-11 15:58:26 +02001593 f_ms_tx_ul_data_block_multi(ms, 5, with_tlli := true);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001594 exp_ul_ack_sub := tr_UlAckNackGprs(*, tr_AckNackDescription('1'B), *);
1595 exp_ul_ack := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi, exp_ul_ack_sub);
1596
1597 nr := ts_TsTrxBtsNum;
1598 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1599 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1600 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1601 block_nr := nr.blk_nr));
1602 alt {
1603 [N3103 < N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1604 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1605 exp_ul_ack)) -> value data_msg {
1606 if (not f_dl_block_rrbp_valid(data_msg.dl_block)) {
1607 setverdict(fail, "Unexpected DL BLOCK has no RRBP: ", data_msg.dl_block);
1608 f_shutdown(__BFILE__, __LINE__);
1609 }
1610
1611 nr := ts_TsTrxBtsNum;
1612 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1613 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1614 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1615 block_nr := nr.blk_nr));
1616 N3103 := N3103 + 1;
1617 if (N3103 == N3103_MAX) {
1618 /* At this point in time (N3103_MAX reached), PCU is
1619 * moving the TBF to RELEASE state so no data/ctrl for
1620 * it is tx'ed, hence the dummy blocks: */
1621 T_3169.start;
1622 }
1623 repeat;
1624 }
1625 [N3103 >= N3103_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1626 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1627 exp_ul_ack)) -> value data_msg {
1628 setverdict(fail, "Unexpected UL ACK/NACK after reaching N3103_MAX");
1629 f_shutdown(__BFILE__, __LINE__);
1630 }
1631 [] as_ms_rx_ignore_dummy(ms, nr);
Pau Espin Pedrol907ba202021-11-12 17:25:24 +01001632 [] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02001633 [T_3169.running] T_3169.timeout {
1634 log("T_3169 timeout");
1635 /* Done in alt, wait for pending RTS initiated previously in
1636 * above case before continuing (expect /* Dummy block): */
1637 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1638 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1639 tr_RLCMAC_DUMMY_CTRL));
1640 }
1641 [] BTS.receive {
1642 setverdict(fail, "Unexpected BTS message");
1643 f_shutdown(__BFILE__, __LINE__);
1644 }
1645 }
1646
1647 /* Now that T3169 has expired, establishing a Ul TBF should provide same
1648 * USFs as per previous TBF since they were freed at expiration time: */
1649 var uint3_t old_usf[8] := ms.ul_tbf.usf;
1650 var uint5_t old_tfi := ms.ul_tbf.tfi;
1651 f_ms_establish_ul_tbf(ms);
1652 if (old_tfi != ms.ul_tbf.tfi) {
1653 setverdict(fail, "Unexpected TFI change: ", ms.ul_tbf.tfi, " vs exp ", old_tfi);
1654 f_shutdown(__BFILE__, __LINE__);
1655 }
1656 for (var integer i := 0; i < 8; i := i +1) {
1657 if (ms.ul_tbf.usf[i] != old_usf[i]) {
1658 setverdict(fail, "Unexpected USF change: ", ms.ul_tbf.usf[i], " vs exp ", old_usf[i]);
1659 f_shutdown(__BFILE__, __LINE__);
1660 }
1661 }
1662
1663 f_shutdown(__BFILE__, __LINE__, final := true);
1664}
1665
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01001666/* Verify that a Downlink TBF is kept available until T3191 fires, at which
1667 * point the TBF is no longer available. In order to get to start of T3191, we
1668 * have to wait for x2031 since that marks the IDLE TBF time, that is, the delay
1669 * until TBF release procedure starts after draining DL queue. */
1670testcase TC_x2031_t3191() runs on RAW_PCU_Test_CT {
1671 var PCUIF_info_ind info_ind;
1672 var RlcmacDlBlock dl_block;
1673 var octetstring data1 := f_rnd_octstring(200);
1674 var octetstring data2 := f_rnd_octstring(10);
1675 var uint32_t dl_fn;
1676 var template (value) TsTrxBtsNum nr;
1677 var BTS_PDTCH_Block data_msg;
1678 var GprsMS ms;
1679
1680 /* Initialize NS/BSSGP side */
1681 f_init_bssgp();
1682 /* Initialize GPRS MS side */
1683 f_init_gprs_ms();
1684 ms := g_ms[0]; /* We only use first MS in this test */
1685
1686 /* Initialize the PCU interface abstraction */
1687 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1688 /* Set timer to 1 sec (default 5) to speedup test: */
1689 info_ind.t3191 := 1;
1690 f_init_raw(testcasename(), info_ind);
1691
1692 /* Establish BSSGP connection to the PCU */
1693 f_bssgp_establish();
1694 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1695
1696 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1697 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1698 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1699
1700 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1701 f_sleep(X2002);
1702
1703 while (true) {
1704 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1705
1706 /* Keep Ack/Nack description updated (except for last BSN) */
1707 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1708
1709 if (f_dl_block_rrbp_valid(dl_block)) {
1710 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1711 f_dl_block_ack_fn(dl_block, dl_fn));
1712 break;
1713 }
1714 }
1715
1716 /* Now we wait for IDLE TBF timer (X2031) to time out and receive a FINAL ACK */
1717 nr := ts_TsTrxBtsNum;
1718 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1719 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1720 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1721 block_nr := nr.blk_nr));
1722 alt {
1723 [] as_ms_rx_ignore_dummy(ms, nr);
1724 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1725 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1726 ?)) -> value data_msg {
1727 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
1728 log("Received FINAL_ACK");
1729 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1730 break;
1731 }
1732 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1733 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1734 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1735 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
1736 }
1737 nr := ts_TsTrxBtsNum;
1738 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1739 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1740 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1741 block_nr := nr.blk_nr));
1742 repeat;
1743 }
1744 [] BTS.receive {
1745 setverdict(fail, "Unexpected BTS message");
1746 f_shutdown(__BFILE__, __LINE__);
1747 }
1748 }
1749
1750 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1751 to time out. We simply sleep instead of requesting blocks because
1752 otherwise retransmissions would keep restarting the timer. */
1753 f_sleep(int2float(info_ind.t3191));
1754
1755 /* The TBF should be freed now, so new data should trigger an Assignment: */
1756 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1757 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1758
1759 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1760 f_sleep(X2002);
1761 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1762 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1763 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1764 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1765 f_dl_block_ack_fn(dl_block, dl_fn));
1766
1767 f_shutdown(__BFILE__, __LINE__, final := true);
1768}
1769
1770/* Same as TC_zero_x2031_t3191, but this time without x2031 (immediate FINAL_ACK). */
1771testcase TC_zero_x2031_t3191() runs on RAW_PCU_Test_CT {
1772 var PCUIF_info_ind info_ind;
1773 var RlcmacDlBlock dl_block;
1774 var octetstring data1 := f_rnd_octstring(1400);
1775 var octetstring data2 := f_rnd_octstring(10);
1776 var uint32_t dl_fn;
1777 var GprsMS ms;
1778
1779 /* Initialize NS/BSSGP side */
1780 f_init_bssgp();
1781 /* Initialize GPRS MS side */
1782 f_init_gprs_ms();
1783 ms := g_ms[0]; /* We only use first MS in this test */
1784
1785 /* Initialize the PCU interface abstraction */
1786 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1787 /* Set timer to 1 sec (default 5) to speedup test: */
1788 info_ind.t3191 := 1;
1789 f_init_raw(testcasename(), info_ind);
1790
1791 f_vty_config2(PCUVTY, {"pcu"}, "timer X2031 0");
1792
1793 /* Establish BSSGP connection to the PCU */
1794 f_bssgp_establish();
1795 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1796
1797 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1798 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1799 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1800
1801 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1802 f_sleep(X2002);
1803
1804 /* Send enough DL data to at least be able to DL ACK once (excl the
1805 * FINAL_ACK one), so that PCU sees we are listening in PDCH and avoids
1806 * other code paths like trying to Imm Assign on CCCH again, etc.. */
1807 while (true) {
1808 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
1809
1810 if (dl_block.data.mac_hdr.hdr_ext.fbi) {
1811 log("Received FINAL_ACK");
1812 ms.dl_tbf.acknack_desc.final_ack := '1'B;
1813 break;
1814 }
1815
1816 /* Keep Ack/Nack description updated (except for last BSN) */
1817 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
1818
1819 if (f_dl_block_rrbp_valid(dl_block)) {
1820 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1821 f_dl_block_ack_fn(dl_block, dl_fn));
1822 }
1823 }
1824
1825 /* Avoid ACKing the last RLC data block on purpose here, wait for t3191
1826 to time out. We simply sleep instead of requesting blocks because
1827 otherwise retransmissions would keep restarting the timer. */
1828 f_sleep(int2float(info_ind.t3191));
1829
1830 /* The TBF should be freed now, so new data should trigger an Assignment: */
1831 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
1832 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1833
1834 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1835 f_sleep(X2002);
1836 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1837 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
1838 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1839 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1840 f_dl_block_ack_fn(dl_block, dl_fn));
1841
1842 f_shutdown(__BFILE__, __LINE__, final := true);
1843}
1844
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001845/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1846 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1847 * T3193) after DL TBF release */
1848testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001849 var RlcmacDlBlock dl_block;
1850 var octetstring data := f_rnd_octstring(10);
1851 var boolean ok;
1852 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001853 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001854 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001855 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1856
1857 /* Initialize NS/BSSGP side */
1858 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001859 /* Initialize GPRS MS side */
1860 f_init_gprs_ms();
1861 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001862
1863 /* Initialize the PCU interface abstraction */
1864 f_init_raw(testcasename());
1865
1866 /* Establish BSSGP connection to the PCU */
1867 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001868 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001869
1870 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001871 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1872 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001873
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001874 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1875 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001876 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001877
1878 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001879 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1880 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1881 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001882
1883 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001884 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001885 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001886 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001887 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001888
1889 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001890
1891 /* 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 +07001892 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001893 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1894 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1895 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001896
1897 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001898}
1899
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001900/* Verify after N3105_MAX is reached, T3195 is started and upon timeout TBF is
1901 freed and no longer available. Trigger it by sending DL blocks and never DL
1902 ACKing the data (which are requested through RRBP) */
1903testcase TC_n3105_max_t3195() runs on RAW_PCU_Test_CT {
1904 var PCUIF_info_ind info_ind;
1905 var RlcmacDlBlock dl_block;
1906 var octetstring data1 := f_rnd_octstring(1000);
1907 var octetstring data2 := f_rnd_octstring(10);
1908 var uint32_t dl_fn;
1909 var template (value) TsTrxBtsNum nr;
1910 var BTS_PDTCH_Block data_msg;
1911 var GprsMS ms;
1912 const integer N3105_MAX := 2;
1913 var integer N3105 := 0;
1914 timer T_3195 := 1.0;
1915 var integer num_poll_recv := 0;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001916 var template RlcmacDlBlock dl_block_exp;
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001917
1918 /* Initialize NS/BSSGP side */
1919 f_init_bssgp();
1920 /* Initialize GPRS MS side */
1921 f_init_gprs_ms();
1922 ms := g_ms[0]; /* We only use first MS in this test */
1923
1924 /* Initialize the PCU interface abstraction */
1925 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1926 /* Speedup test: */
1927 info_ind.n3105 := N3105_MAX;
1928 info_ind.t3195 := 1;
1929 f_init_raw(testcasename(), info_ind);
1930
1931 /* Disable "MS delay release" timer, to avoid old DL data kept in cached
1932 * MS and retransmitted after the TBF is released and later on created
1933 * (because the MS is reused) */
1934 f_vty_config2(PCUVTY, {"pcu"}, "timer X2030 0");
1935
1936 /* Establish BSSGP connection to the PCU */
1937 f_bssgp_establish();
1938 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1939
1940 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1941 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1942 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1943
1944 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1945 f_sleep(X2002);
1946
1947 /* Now we go on receiving DL data and not answering RRBP: */
1948 nr := ts_TsTrxBtsNum;
1949 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1950 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1951 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1952 block_nr := nr.blk_nr));
1953 alt {
1954 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1955 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1956 tr_RLCMAC_DATA)) -> value data_msg {
1957 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
1958 if (num_poll_recv == 0) {
1959 /* ACK first one so PCU detects we are there and doesn't retransmit Imm Ass */
1960 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
1961 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1962 f_dl_block_ack_fn(data_msg.dl_block, data_msg.raw.fn));
1963 } else {
1964 log("Ignoring RRBP ", num_poll_recv);
1965 N3105 := N3105 + 1;
1966 }
1967 num_poll_recv := num_poll_recv + 1;
1968 }
1969
1970 nr := ts_TsTrxBtsNum;
1971 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1972 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1973 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1974 block_nr := nr.blk_nr));
1975 repeat;
1976 }
1977 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02001978 * RELEASE state so no data for it is tx'ed, hence the dummy/idle blocks:
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001979 */
1980 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
1981 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
1982 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
1983 if (not T_3195.running) {
1984 T_3195.start;
1985 /* We even send some new data, nothing should be sent to MS */
1986 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
1987 }
1988 nr := ts_TsTrxBtsNum;
1989 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
1990 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
1991 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
1992 block_nr := nr.blk_nr));
1993 repeat;
1994 }
Pau Espin Pedrol518e82f2021-11-12 17:24:33 +01001995 /* We may already receive idle blocks before our own TTCN3 timer
1996 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01001997 [N3105 == N3105_MAX] as_pcuif_rx_ignore_empty(nr);
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02001998 [T_3195.running] T_3195.timeout {
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01001999 log("T_3195 timeout");
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002000 /* Done in alt, wait for pending RTS initiated previously in
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002001 * above case before continuing (expect empty block): */
2002 dl_block_exp := omit;
Pau Espin Pedrolbf8c71f2021-04-20 12:23:28 +02002003 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2004 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02002005 dl_block_exp));
2006 }
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01002007 [] BTS.receive {
2008 setverdict(fail, "Unexpected BTS message");
2009 f_shutdown(__BFILE__, __LINE__);
2010 }
2011 }
2012
2013 /* after T_3195 timeout, TBF is released */
2014 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data2));
2015 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2016
2017 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2018 f_sleep(X2002);
2019 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data2, 0);
2020
2021 /* ACK the DL block */
2022 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2023 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2024 f_dl_block_ack_fn(dl_block, dl_fn));
2025
2026 f_shutdown(__BFILE__, __LINE__, final := true);
2027}
2028
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01002029/* Verify configured T3172 is properly transmitted as WAIT_INDICATION in Pkt Access Reject in PACCH. */
2030function f_TC_t3172(integer t3172_ms, BIT1 wait_ind_size) runs on RAW_PCU_Test_CT {
2031 var PCUIF_info_ind info_ind;
2032 var template IARRestOctets rest;
2033 var BIT11 ra11;
2034 var GprsMS ms;
2035 var octetstring data := f_rnd_octstring(10);
2036 var RlcmacDlBlock dl_block;
2037 var template RlcmacDlBlock rej_tmpl;
2038 var uint32_t dl_fn;
2039 var uint32_t sched_fn;
2040 var uint8_t wait_ind_val;
2041
2042 /* Initialize NS/BSSGP side */
2043 f_init_bssgp();
2044 /* Initialize GPRS MS side */
2045 f_init_gprs_ms();
2046 ms := g_ms[0]; /* We only use first MS in this test */
2047
2048 info_ind := valueof(ts_PCUIF_INFO_default);
2049
2050 /* Only the first TRX is enabled. */
2051 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2052 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
2053
2054 /* Initialize the PCU interface abstraction */
2055 f_init_raw(testcasename(), info_ind);
2056
2057 f_pcuvty_set_timer(3172, t3172_ms);
2058
2059 /* Establish BSSGP connection to the PCU */
2060 f_bssgp_establish();
2061 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2062
2063 var EGPRSPktChRequest req := {
2064 one_phase := {
2065 tag := '0'B,
2066 multislot_class := '10101'B,
2067 priority := '01'B,
2068 random_bits := '101'B
2069 }
2070 };
2071
2072 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
2073 for (var integer i := 0; i < 7; i := i + 1) {
2074 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2075 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2076 }
2077
2078 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2079 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2080 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2081
2082 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2083 f_sleep(X2002);
2084 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2085
2086 /* ACK the DL block */
2087 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2088 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc, false, ts_ChannelReqDescription()),
2089 f_dl_block_ack_fn(dl_block, dl_fn));
2090
2091 /* Since all USF are taken, we should receive a Reject: */
2092
2093 if (wait_ind_size == '0'B) {
2094 wait_ind_val := t3172_ms / 1000;
2095 } else {
2096 wait_ind_val := t3172_ms / 20;
2097 }
2098 rej_tmpl := tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_ACC_REJ(
2099 tr_PacketAccessRejectStruct_TLLI(ms.tlli,
2100 wait_ind_val,
2101 wait_ind_size)));
2102 template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum;
2103 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2104 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2105 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2106 block_nr := nr.blk_nr));
2107 alt {
2108 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2109 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2110 rej_tmpl));
2111 [] BTS.receive {
2112 setverdict(fail, "Unexpected BTS message");
2113 f_shutdown(__BFILE__, __LINE__);
2114 }
2115 }
2116 f_shutdown(__BFILE__, __LINE__, final := true);
2117}
2118testcase TC_t3172_wait_ind_size0() runs on RAW_PCU_Test_CT {
2119 /* size=0 means value is provided in seconds. Due to value being 8
2120 * bit, in the 20ms step case (size=1) the maximum value possible is 20 * 255
2121 * = 5100. Hence, values above it should use size=0 to be able to
2122 * provide values in range. Let's use 6 seconds, 6000ms
2123 */
2124 f_TC_t3172(6000, '0'B);
2125}
2126testcase TC_t3172_wait_ind_size1() runs on RAW_PCU_Test_CT {
2127 f_TC_t3172(3000, '1'B);
2128}
2129
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002130/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
2131testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002132 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002133 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002134 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002135 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002136
2137 /* Initialize NS/BSSGP side */
2138 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002139 /* Initialize GPRS MS side */
2140 f_init_gprs_ms();
2141 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002142
2143 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002144 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002145
2146 /* Establish BSSGP connection to the PCU */
2147 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002148 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002149
2150 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002151 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002152
2153 /* Send one UL block (with TLLI since we are in One-Phase Access
2154 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002155 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002156 /* 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 +02002157 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 +02002158 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2159 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002160 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002161
2162 /* Send enough blocks to test whole procedure: Until Nth block
2163 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
2164 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002165 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002166 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2167 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002168 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002169
2170 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002171 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 +07002172
2173 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002174}
2175
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002176/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
2177testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
2178 var RlcmacDlBlock dl_block;
2179 var uint32_t dl_fn, sched_fn;
2180 var octetstring payload;
2181 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002182 var template (value) LlcBlockHdr blk_hdr;
2183 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002184 var integer blk_len;
2185 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002186 var GprsMS ms;
2187
2188 /* Initialize NS/BSSGP side */
2189 f_init_bssgp();
2190 /* Initialize GPRS MS side */
2191 f_init_gprs_ms();
2192 ms := g_ms[0]; /* We only use first MS in this test */
2193
2194 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002195 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002196
2197 /* Establish BSSGP connection to the PCU */
2198 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002199 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002200
2201 /* Establish an Uplink TBF */
2202 f_ms_establish_ul_tbf(ms);
2203
2204 /* Send one UL block (with TLLI since we are in One-Phase Access
2205 contention resoultion) and make sure it is ACKED fine. */
2206 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002207 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2208 more := false, e := true);
2209 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002210 /* 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 +01002211 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
2212 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002213 cv := 15,
2214 bsn := ms.ul_tbf.bsn,
2215 blocks := blocks,
2216 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002217 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002218 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002219
2220 /* ACK and check it was received fine */
2221 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2222 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2223 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2224 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002225 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 +02002226
2227 /* Test sending LLC PDUS of incrementing size */
2228 var integer max_size := 49;
2229 for (var integer i := 1; i <= max_size; i := i + 1) {
2230 var integer cv;
2231 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
2232 log("Sending DATA.ind with LLC payload size ", i);
2233 if (i < max_size - g_bs_cv_max) {
2234 cv := 15;
2235 } else {
2236 cv := max_size - i;
2237 }
2238
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002239 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
2240 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002241 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002242 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2243 more := false, e := true);
2244 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002245 /* 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 +01002246 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
2247 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002248 cv := cv,
2249 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002250 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002251 f_ultbf_inc_bsn(ms.ul_tbf);
2252 f_ms_tx_ul_block(ms, ul_data);
2253
2254 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002255 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 +02002256
2257 /* we will receive UL ACK/NACK from time to time, handle it. */
2258 f_rx_rlcmac_dl_block(dl_block, dl_fn);
2259 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
2260 continue;
2261 }
2262 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
2263 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
2264 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
2265 f_shutdown(__BFILE__, __LINE__);
2266 }
2267
2268 log("Rx Packet Uplink ACK / NACK");
2269 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
2270 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2271 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2272 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002273
2274 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002275}
2276
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002277function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
2278 var octetstring payload;
2279 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002280 var template (value) LlcBlockHdr blk_hdr;
2281 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002282 var integer block_len, max_valid_data_len;
2283 timer T;
2284
2285 block_len := f_rlcmac_cs_mcs2block_len(cs);
2286 /* We need to send with TLLI since we are in One-Phase Access Contenion
2287 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
2288 * indicator, -1 for spare bits octet at the end */
2289 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
2290 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 +07002291 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
2292 more := false, e := true);
2293 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002294 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
2295 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07002296 cv := cv,
2297 bsn := ms.ul_tbf.bsn,
2298 blocks := blocks,
2299 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002300 f_ultbf_inc_bsn(ms.ul_tbf);
2301 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
2302
2303 T.start(0.5);
2304 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02002305 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002306 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
2307 f_shutdown(__BFILE__, __LINE__);
2308 }
2309 [] T.timeout {
2310 setverdict(pass);
2311 }
2312 }
2313}
2314/* Verify PCU finds out incorrectly formated RLC block and discards it. This
2315 blocks intentionally contain last byte of data placed in last byte of RLC
2316 containing padding/spare bits, which is incorrect. Spare bits exist and are
2317 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
2318 discounting padding in octet" */
2319testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
2320 var GprsMS ms;
2321 var integer block_len, max_valid_data_len;
2322
2323 /* Initialize NS/BSSGP side */
2324 f_init_bssgp();
2325 /* Initialize GPRS MS side */
2326 f_init_gprs_ms();
2327 ms := g_ms[0]; /* We only use first MS in this test */
2328
2329 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002330 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002331
2332 /* Establish BSSGP connection to the PCU */
2333 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002334 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002335
2336 /* Establish an Uplink TBF */
2337 f_ms_establish_ul_tbf(ms);
2338
2339 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
2340 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
2341 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
2342
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07002343 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002344}
2345
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002346/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2347 * answered, so TBFs for uplink and later for downlink are created.
2348 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002349private 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 +02002350 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002351 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002352 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002353 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002354 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002355
2356 /* Initialize NS/BSSGP side */
2357 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002358 /* Initialize GPRS MS side */
2359 f_init_gprs_ms();
2360 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002361
2362 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002363 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002364
2365 /* Establish BSSGP connection to the PCU */
2366 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002367 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002368
2369 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002370 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002371
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002372 /* Send one UL block (with TLLI since we are in One-Phase Access
2373 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002374 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 +02002375 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2376 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002377 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002378
2379 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002380 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002381
2382 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002383 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2384 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002385
2386 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2387 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002388 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002389
2390 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002391 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2392 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2393 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002394
2395 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002396}
2397
2398/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2399 * answered, so TBFs for uplink and later for downlink are created.
2400 */
2401testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002402 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002403 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002404}
2405
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002406/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
2407 * answered, so TBFs for uplink and later for downlink are created.
2408 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002409private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
2410 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002411 template (present) CodingScheme exp_ul_cs_mcs := ?,
2412 template (present) CodingScheme exp_dl_cs_mcs := ?)
2413runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002414 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002415 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002416 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002417 var uint32_t sched_fn;
2418 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002419 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002420 var GprsMS ms;
2421
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002422 /* Initialize NS/BSSGP side */
2423 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002424 /* Initialize GPRS MS side */
2425 f_init_gprs_ms();
2426 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002427
2428 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002429 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002430
2431 /* Establish BSSGP connection to the PCU */
2432 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002433 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002434
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002435 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
2436 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 +02002437
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002438 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
2439 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 +02002440 f_shutdown(__BFILE__, __LINE__);
2441 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002442
2443 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2444 and make sure it is ACKED fine */
Pau Espin Pedrolfdbce842021-03-03 11:43:40 +01002445 f_ms_tx_ul_data_block_multi(ms, 1);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002446
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002447 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002448 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 +02002449
2450 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002451 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002452
2453 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002454 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Pau Espin Pedrolddd6c3f2021-03-03 12:01:20 +01002455 /* Sleep a bit to make sure PCU received the DL data and hence it will be prioritized by scheduler: */
2456 f_sleep(0.5);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002457 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002458 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002459 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002460
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02002461 /* PCU acks the UL data after having received CV=0) */
2462 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
2463
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002464 /* 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 +02002465 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 +02002466
2467 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002468 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2469 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 +02002470 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02002471
2472 f_shutdown(__BFILE__, __LINE__, final := true);
2473}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002474
2475testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002476 var template (present) CodingScheme exp_ul_cs_mcs := cs_gprs_any;
2477 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002478
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002479 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01002480
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002481 var StatsDExpects expect := {
2482 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2483 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2484 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2485 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2486 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2487 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2488 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2489 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2490 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2491 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2492 };
2493 f_statsd_expect(expect);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002494}
2495
2496testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002497 var template (present) CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
2498 var template (present) CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002499
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002500 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_default, ms_racap_egprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002501
2502 var StatsDExpects expect := {
2503 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2504 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2505 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
2506 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 1, max := 1 },
2507 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2508 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2509 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2510 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2511 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2512 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2513 };
2514 f_statsd_expect(expect);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002515}
2516
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002517testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
2518 /* Configure PCU to force two phase access */
2519 g_force_two_phase_access := true;
2520
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002521 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002522 var template (present) CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002523
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002524 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap_gprs_def, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01002525
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01002526 var StatsDExpects expect := {
2527 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
2528 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
2529 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
2530 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
2531 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
2532 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
2533 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 1, max := 1 },
2534 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
2535 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
2536 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
2537 };
2538 f_statsd_expect(expect);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002539}
2540
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002541/* Test scenario where SGSN wants to send some data against MS and it is
2542 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
2543 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07002544private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
2545 template (present) CodingScheme exp_cs_mcs := ?)
2546runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002547 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002548 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002549 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002550 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002551 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002552
2553 /* Initialize NS/BSSGP side */
2554 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002555 /* Initialize GPRS MS side */
2556 f_init_gprs_ms();
2557 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002558
2559 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002560 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002561
2562 /* Establish BSSGP connection to the PCU */
2563 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002564 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002565
2566 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002567 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2568 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002569
2570 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2571 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002572 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002573
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002574 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01002575 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
2576 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 +02002577 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002578
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02002579 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07002580 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002581
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02002582 /* Send one UL block (with TLLI since we are in One-Phase Access
2583 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002584 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002585 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2586 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002587 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002588
2589 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002590 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002591
2592 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002593}
2594
2595testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002596 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002597 f_TC_mt_ping_pong(omit, exp_cs_mcs);
2598}
2599
2600/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
2601/* information about the MS */
2602testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01002603 var template (present) CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01002604 f_TC_mt_ping_pong(bssgp_ms_racap_gprs_def, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002605}
2606
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002607/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
2608 * TBF, it will request retransmission through UL ACK/NACK (with missing block
2609 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
2610 * be transferred).
2611 */
2612testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002613 var RlcmacDlBlock dl_block;
2614 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002615 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002616 var octetstring total_payload;
2617 var octetstring payload;
2618 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002619 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002620 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002621 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002622
2623 /* Initialize NS/BSSGP side */
2624 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002625 /* Initialize GPRS MS side */
2626 f_init_gprs_ms();
2627 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002628
2629 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002630 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002631
2632 /* Establish BSSGP connection to the PCU */
2633 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002634 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002635
2636 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002637 f_ms_establish_ul_tbf(ms);
2638 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002639
2640 /* Send one UL block (with TLLI since we are in One-Phase Access
2641 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002642 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 +02002643 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 +02002644
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002645 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2646 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002647 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002648 total_payload := payload;
2649
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002650 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
2651
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002652 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002653 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002654 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002655 total_payload := total_payload & payload;
2656
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002657 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002658 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002659 total_payload := total_payload & payload;
2660
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002661 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002662 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 +02002663 total_payload := total_payload & lost_payload;
2664
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002665 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002666 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002667 total_payload := total_payload & payload;
2668
2669 /* 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 +02002670 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002671
2672 /* On CV=0, we'll receive a UL ACK asking about missing block */
2673 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2674 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002675 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
2676 tfi := tfi,
2677 cv := 15,
2678 bsn := 3,
2679 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002680 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002681
2682 /* Now final ack is recieved */
2683 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2684 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002685 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002686
2687 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02002688 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 +07002689
2690 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002691}
2692
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002693/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
2694 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
2695 * timeout occurs (specified by sent RRBP on DL block). */
2696testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002697 var RlcmacDlBlock dl_block;
2698 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002699 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002700 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002701
2702 /* Initialize NS/BSSGP side */
2703 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002704 /* Initialize GPRS MS side */
2705 f_init_gprs_ms();
2706 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002707
2708 /* Initialize the PCU interface abstraction */
2709 f_init_raw(testcasename());
2710
2711 /* Establish BSSGP connection to the PCU */
2712 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002713 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002714
2715 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002716 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2717 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002718
2719 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2720 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002721 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002722
2723 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
2724 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
2725 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002726 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002727
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002728 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2729 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07002730 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002731
2732 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002733 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2734 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2735 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002736
2737 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002738}
2739
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002740/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
2741testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
2742 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2743 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002744 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002745 var RlcmacDlBlock dl_block;
2746 var uint32_t ack_fn;
2747 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002748 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002749 timer T := 5.0;
2750
2751 /* Initialize NS/BSSGP side */
2752 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002753 /* Initialize GPRS MS side */
2754 f_init_gprs_ms();
2755 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002756
2757 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002758 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002759
Daniel Willmann535aea62020-09-21 13:27:08 +02002760 f_statsd_reset();
2761
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002762 /* Establish BSSGP connection to the PCU */
2763 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002764 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002765
2766 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002767 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2768 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002769
2770 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2771 f_sleep(X2002);
2772
2773 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2774 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002775 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002776
2777 /* TDMA frame number on which we are supposed to send the ACK */
2778 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2779
2780 /* SGSN sends more blocks during the indicated RRBP */
2781 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2782 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002783 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002784
2785 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2786
2787 /* Make sure this block has the same TFI as was assigned
2788 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002789 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002790 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2791 dl_block.data.mac_hdr.hdr_ext.tfi);
2792 f_shutdown(__BFILE__, __LINE__);
2793 }
2794
2795 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002796 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002797
2798 /* Break if this is the end of RRBP */
2799 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002800 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002801 break;
2802 }
2803 }
2804
2805 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002806 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 +07002807
2808 /* Make sure that the next block (after the Ack) is dummy */
2809 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2810
Daniel Willmann535aea62020-09-21 13:27:08 +02002811 var StatsDExpects expect := {
2812 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2813 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2814 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2815 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2816 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002817 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002818 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2819 };
2820 f_statsd_expect(expect);
2821
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002822 f_shutdown(__BFILE__, __LINE__, final := true);
2823}
2824
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002825/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2826 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2827 * Check "3GPP TS 44.060" Annex B. */
2828testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2829 var RlcmacDlBlock dl_block;
2830 var octetstring dataA := f_rnd_octstring(20);
2831 var octetstring dataB := f_rnd_octstring(13);
2832 var octetstring dataC := f_rnd_octstring(3);
2833 var octetstring dataD := f_rnd_octstring(12);
2834 var uint32_t sched_fn;
2835 var GprsMS ms;
2836 var template (value) RlcmacUlBlock ul_data;
2837
2838 /* Initialize NS/BSSGP side */
2839 f_init_bssgp();
2840 /* Initialize GPRS MS side */
2841 f_init_gprs_ms();
2842 ms := g_ms[0]; /* We only use first MS in this test */
2843
2844 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002845 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002846
2847 /* Establish BSSGP connection to the PCU */
2848 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002849 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002850
2851 /* Establish an Uplink TBF */
2852 f_ms_establish_ul_tbf(ms);
2853
2854 /* Summary of what's transmitted:
2855 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2856 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2857 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2858 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2859 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2860 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2861 */
2862
2863 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002864 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2865 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002866 cv := 3,
2867 bsn := ms.ul_tbf.bsn,
2868 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2869 tlli := ms.tlli);
2870 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2871 * RLCMAC block being sent. */
2872 ul_data.data.mac_hdr.e := true;
2873 f_ultbf_inc_bsn(ms.ul_tbf);
Pau Espin Pedroldee55702021-04-23 21:08:22 +02002874 f_ms_tx_ul_block(ms, ul_data, ms.ul_tbf.start_time_fn);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002875
2876 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002877 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2878 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002879 cv := 2,
2880 bsn := ms.ul_tbf.bsn,
2881 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2882 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2883 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2884 },
2885 tlli := ms.tlli);
2886 f_ultbf_inc_bsn(ms.ul_tbf);
2887 f_ms_tx_ul_block(ms, ul_data);
2888
2889 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002890 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 +02002891
2892 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002893 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2894 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002895 cv := 1,
2896 bsn := ms.ul_tbf.bsn,
2897 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2898 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2899 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2900 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2901 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2902 },
2903 tlli := ms.tlli);
2904 f_ultbf_inc_bsn(ms.ul_tbf);
2905 f_ms_tx_ul_block(ms, ul_data);
2906
2907 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002908 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2909 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 +02002910
2911 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002912 ul_data := t_RLCMAC_UL_DATA_TLLI(
2913 cs := CS_1,
2914 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002915 cv := 0,
2916 bsn := ms.ul_tbf.bsn,
2917 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2918 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2919 },
2920 tlli := ms.tlli);
2921 f_ultbf_inc_bsn(ms.ul_tbf);
2922 f_ms_tx_ul_block(ms, ul_data);
2923
2924 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002925 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 +02002926
2927 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2928 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2929 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2930
2931 f_shutdown(__BFILE__, __LINE__, final := true);
2932}
2933
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01002934/* Validate an Imm Assignment is retransmitted if first RRBP requesting DL
2935 * ACK/NACK is not answered */
2936testcase TC_dl_no_ack_retrans_imm_ass() runs on RAW_PCU_Test_CT {
2937 var RlcmacDlBlock dl_block;
2938 var octetstring data1 := f_rnd_octstring(200);
2939 var octetstring data2 := f_rnd_octstring(10);
2940 var uint32_t dl_fn;
2941 var GprsMS ms;
2942 var template (value) TsTrxBtsNum nr;
2943 var BTS_PDTCH_Block data_msg;
2944
2945 /* Initialize NS/BSSGP side */
2946 f_init_bssgp();
2947 /* Initialize GPRS MS side */
2948 f_init_gprs_ms();
2949 ms := g_ms[0]; /* We only use first MS in this test */
2950
2951 /* Initialize the PCU interface abstraction */
2952 f_init_raw(testcasename())
2953
2954 /* Establish BSSGP connection to the PCU */
2955 f_bssgp_establish();
2956 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2957
2958 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2959 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data1));
2960 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2961
2962 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2963 f_sleep(X2002);
2964
2965 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued DL data) */
2966 while (true) {
2967 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
2968
2969 /* Keep Ack/Nack description updated (except for last BSN) */
2970 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
2971
2972 if (f_dl_block_rrbp_valid(dl_block)) {
2973 /* Don't transmit DL ACK here on purpose ignore it */
2974 break;
2975 }
2976 }
2977
2978 /* PCU starts whole process again */
2979 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2980
2981 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2982 f_sleep(X2002);
2983
2984 /* Recv DL data until receiving RRBP to DL ACK (because it's last queued
2985 /* DL data), after that we receive only DUMMY blocks so we are done */
2986 var boolean data_received := false;
2987 nr := ts_TsTrxBtsNum;
2988 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
2989 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
2990 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
2991 block_nr := nr.blk_nr));
2992 alt {
2993 [data_received] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2994 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2995 tr_RLCMAC_DUMMY_CTRL)) { /* done */ }
2996 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
2997 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
2998 tr_RLCMAC_DATA)) -> value data_msg {
2999 data_received := true;
3000 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, data_msg.dl_block);
3001 if (data_msg.dl_block.data.mac_hdr.hdr_ext.fbi) {
3002 log("Received FINAL_ACK");
3003 ms.dl_tbf.acknack_desc.final_ack := '1'B;
3004 }
3005 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3006 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3007 f_dl_block_ack_fn(dl_block, data_msg.raw.fn));
3008 }
3009 nr := ts_TsTrxBtsNum;
3010 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3011 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3012 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3013 block_nr := nr.blk_nr));
3014 repeat;
3015 }
3016 [] BTS.receive {
3017 setverdict(fail, "Unexpected BTS message");
3018 f_shutdown(__BFILE__, __LINE__);
3019 }
3020 }
3021
3022 f_shutdown(__BFILE__, __LINE__, final := true);
3023}
3024
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02003025/* OS#5508: Verify scheduling of LLC frames with SAPI=1 (GMM) takes precedence
3026 * over SAPI2/7/8 which in turn take prececende over others */
3027testcase TC_dl_llc_sapi_priority() runs on RAW_PCU_Test_CT {
3028 var octetstring data_sapi1 := f_pad_oct('01'O, 19, 'ff'O);
3029 var octetstring data_sapi2 := f_pad_oct('02'O, 19, 'ff'O);
3030 var octetstring data_sapi7 := f_pad_oct('07'O, 19, 'ff'O);
3031 var octetstring data_sapi8 := f_pad_oct('08'O, 19, 'ff'O);
3032 var octetstring data_sapi_other := f_pad_oct('03'O, 19, 'ff'O);
3033 var RlcmacDlBlock dl_block;
3034 var uint32_t dl_fn;
3035 var GprsMS ms;
3036 var integer state := 1;
3037
3038 /* Initialize NS/BSSGP side */
3039 f_init_bssgp();
3040 /* Initialize GPRS MS side */
3041 f_init_gprs_ms();
3042 ms := g_ms[0]; /* We only use first MS in this test */
3043
3044 /* Initialize the PCU interface abstraction */
3045 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3046
3047 /* Lock to CS1 to keep same DL RLCMAC data block size: */
3048 g_cs_initial_dl := 1;
3049 g_mcs_max_dl := 1;
3050 f_pcuvty_set_allowed_cs_mcs();
3051
3052 /* Establish BSSGP connection to the PCU */
3053 f_bssgp_establish();
3054 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3055
3056 /* SGSN sends some low prio DL data, PCU will page on CCCH (PCH) */
3057 for (var integer i := 0; i < 10; i := i + 1) {
3058 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi_other));
3059 }
3060 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi2));
3061 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi7));
3062 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi8));
3063 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data_sapi1));
3064 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3065
3066 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3067 f_sleep(X2002);
3068
3069 while (state != 0) {
3070 var OCT1 rx_sapi;
3071 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, ?, ?);
3072 rx_sapi := dl_block.data.blocks[0].payload[0];
3073
3074 select (state) {
3075 case(1) { /* We expect the first GMM LLC frame here (SAPI=1, highest prio) */
3076 if (rx_sapi != '01'O) {
3077 setverdict(fail, "Wrong prio: Expected LLC SAPI 1 (GMM) but got ", rx_sapi);
3078 f_shutdown(__BFILE__, __LINE__);
3079 }
3080 state := 2;
3081 }
3082 case(2) { /* We expect the second LLC frame here (SAPI=2, middle prio) */
3083 if (rx_sapi != '02'O) {
3084 setverdict(fail, "Wrong prio: Expected LLC SAPI 2 but got ", rx_sapi);
3085 f_shutdown(__BFILE__, __LINE__);
3086 }
3087 state := 7;
3088 }
3089 case(7) { /* We expect the third LLC frame here (SAPI=7, middle prio) */
3090 if (rx_sapi != '07'O) {
3091 setverdict(fail, "Wrong prio: Expected LLC SAPI 7 but got ", rx_sapi);
3092 f_shutdown(__BFILE__, __LINE__);
3093 }
3094 state := 8;
3095 }
3096 case(8) { /* We expect the fourth LLC frame here (SAPI=8, middle prio) */
3097 if (rx_sapi != '08'O) {
3098 setverdict(fail, "Wrong prio: Expected LLC SAPI 8 but got ", rx_sapi);
3099 f_shutdown(__BFILE__, __LINE__);
3100 }
3101 state := 3;
3102 }
3103 case(3) { /* We expect the other LLC frame here (SAPI=3, lower prio) */
3104 if (rx_sapi != '03'O) {
3105 setverdict(fail, "Wrong prio: Expected LLC SAPI 3 but got ", rx_sapi);
3106 f_shutdown(__BFILE__, __LINE__);
3107 }
3108 state := 0; /* Done, break */
3109 }
3110 }
3111 /* Keep Ack/Nack description updated (except for last BSN) */
3112 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
3113
3114 if (f_dl_block_rrbp_valid(dl_block)) {
3115 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3116 f_dl_block_ack_fn(dl_block, dl_fn));
3117 }
3118 }
3119
3120 f_shutdown(__BFILE__, __LINE__, final := true);
3121}
3122
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003123/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
3124testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003125 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003126 var octetstring data := f_rnd_octstring(10);
3127 var PacketDlAssign dl_tbf_ass;
3128 var RlcmacDlBlock dl_block;
3129 var uint32_t poll_fn;
3130 var uint32_t sched_fn;
3131 var GprsMS ms;
3132 timer T := 5.0;
3133
3134 /* Initialize NS/BSSGP side */
3135 f_init_bssgp();
3136 /* Initialize GPRS MS side */
3137 f_init_gprs_ms();
3138 ms := g_ms[0]; /* We only use first MS in this test */
3139
3140 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003141 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3142 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003143
3144 /* Initialize the PCU interface abstraction */
3145 f_init_raw(testcasename(), info_ind);
3146
3147 /* Establish BSSGP connection to the PCU */
3148 f_bssgp_establish();
3149 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3150
3151 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
3152 through PDCH (no multiblock assignment possible through PCH) */
3153 f_ms_establish_ul_tbf(ms);
3154
3155 /* Send one UL block (with TLLI since we are in One-Phase Access
3156 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003157 f_ms_tx_ul_data_block(ms, data, with_tlli := true, fn := ms.ul_tbf.start_time_fn,
3158 nr := f_ms_tx_TsTrxBtsNum(ms));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01003159 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3160 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3161
3162 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
3163 var MultislotCap_GPRS_BSSGP mscap_gprs := {
3164 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3165 gprsextendeddynalloccap := '0'B
3166 };
3167 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
3168 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3169 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3170 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3171 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3172 f_shutdown(__BFILE__, __LINE__);
3173 }
3174 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3175
3176 f_shutdown(__BFILE__, __LINE__, final := true);
3177}
3178
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003179testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003180 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003181 var RlcmacDlBlock dl_block;
3182 var octetstring data := f_rnd_octstring(10);
3183 var PollFnCtx pollctx;
3184 var uint32_t sched_fn;
3185 var GprsMS ms;
3186
3187 var MultislotCap_GPRS mscap_gprs := {
3188 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3189 gprsextendeddynalloccap := '0'B
3190 };
3191 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3192
3193
3194 /* Initialize NS/BSSGP side */
3195 f_init_bssgp();
3196 /* Initialize GPRS MS side */
3197 f_init_gprs_ms();
3198 ms := g_ms[0]; /* We only use first MS in this test */
3199
3200 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003201 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3202 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01003203
3204 /* Initialize the PCU interface abstraction */
3205 f_init_raw(testcasename(), info_ind);
3206
3207 /* Establish BSSGP connection to the PCU */
3208 f_bssgp_establish();
3209 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3210
3211 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3212 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3213
3214 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3215 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3216
3217 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3218 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
3219 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
3220 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
3221 f_shutdown(__BFILE__, __LINE__);
3222 }
3223 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
3224
3225 f_shutdown(__BFILE__, __LINE__, final := true);
3226}
3227
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003228testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
3229 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3230 var RlcmacDlBlock dl_block;
3231 var octetstring data := f_rnd_octstring(10);
3232 var PollFnCtx pollctx;
3233 var uint32_t sched_fn;
3234 var GprsMS ms;
3235
3236 var MultislotCap_GPRS mscap_gprs := {
3237 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
3238 gprsextendeddynalloccap := '0'B
3239 };
3240 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3241
3242
3243 /* Initialize NS/BSSGP side */
3244 f_init_bssgp();
3245 /* Initialize GPRS MS side */
3246 f_init_gprs_ms();
3247 ms := g_ms[0]; /* We only use first MS in this test */
3248
3249 /* Only 1 TRX with 8 PDCH */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01003250 f_PCUIF_PDCHMask_set(info_ind, '11111111'B, 0);
3251 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01003252
3253 /* Initialize the PCU interface abstraction */
3254 f_init_raw(testcasename(), info_ind);
3255
3256 /* Establish BSSGP connection to the PCU */
3257 f_bssgp_establish();
3258 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3259
3260 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
3261 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3262
3263 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
3264 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
3265 f_shutdown(__BFILE__, __LINE__);
3266 }
3267
3268 f_shutdown(__BFILE__, __LINE__, final := true);
3269}
3270
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003271/* Test scenario where MS wants to request a new TBF once the current one is
3272 * ending, by means of sending a Packet Resource Request on ul slot provided by
3273 * last Pkt Ul ACK's RRBP.
3274 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3275testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003276 var RlcmacDlBlock dl_block;
3277 var octetstring data := f_rnd_octstring(10);
3278 var uint32_t sched_fn;
3279 var uint32_t dl_fn;
3280 var template RlcmacDlBlock acknack_tmpl;
3281 var GprsMS ms;
3282
3283 /* Initialize NS/BSSGP side */
3284 f_init_bssgp();
3285 /* Initialize GPRS MS side */
3286 f_init_gprs_ms();
3287 ms := g_ms[0]; /* We only use first MS in this test */
3288
3289 /* Initialize the PCU interface abstraction */
3290 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003291 f_statsd_reset();
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003292
3293 /* Establish BSSGP connection to the PCU */
3294 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003295 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003296
3297 /* Establish an Uplink TBF */
3298 f_ms_establish_ul_tbf(ms);
3299
3300 /* Send one UL block (with TLLI since we are in One-Phase Access
3301 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003302 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 +02003303
3304 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003305 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003306
3307 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3308 tr_UlAckNackGprs(ms.tlli,
3309 tr_AckNackDescription(final_ack := '1'B),
3310 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3311 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3312
3313 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3314
3315 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07003316 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 +07003317 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003318 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3319 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3320
3321 /* Send one UL block (without TLLI since we are in Second-Phase Access)
3322 and make sure it is ACKED fine */
3323 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
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 Pedrolcdbe9032020-07-07 20:20:42 +02003327
3328 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3329 /* ACK the ACK */
3330 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3331
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003332 var StatsDExpects expect := {
3333 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1 },
3334 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 0, max := 0 },
3335 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 1, max := 1 },
3336 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
3337 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 1, max := 1 },
3338 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 1, max := 1 },
3339 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
3340 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 1, max := 1 },
3341 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 },
3342 { name := "TTCN3.bts.0.pkt.ul_assignment", mtype := "c", min := 1, max := 1 }
3343 };
3344 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003345
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02003346 f_shutdown(__BFILE__, __LINE__, final := true);
3347}
3348
Pau Espin Pedrold658f342021-10-15 14:52:22 +02003349/* Test scenario where MS wants to request a new TBF once the current one is
3350 * ending, by means of sending a Packet Resource Request on ul slot provided by
3351 * last Pkt Ul ACK's RRBP. new Pkt Ul Ass is never confirmed by the MS in this test.
3352 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3353testcase TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() runs on RAW_PCU_Test_CT {
3354 var PCUIF_info_ind info_ind;
3355 var RlcmacDlBlock dl_block;
3356 var octetstring data := f_rnd_octstring(10);
3357 var uint32_t sched_fn;
3358 var uint32_t dl_fn;
3359 var template (value) TsTrxBtsNum nr;
3360 var BTS_PDTCH_Block data_msg;
3361 var template RlcmacDlBlock acknack_tmpl;
3362 var GprsMS ms;
3363 const integer N3105_MAX := 2;
3364 var integer N3105 := 0;
3365 timer T_3195 := 1.0 + 0.5; /* 0.5: extra offset since we cannot match exactly */
3366
3367 /* Initialize NS/BSSGP side */
3368 f_init_bssgp();
3369 /* Initialize GPRS MS side */
3370 f_init_gprs_ms();
3371 ms := g_ms[0]; /* We only use first MS in this test */
3372
3373 /* Initialize the PCU interface abstraction */
3374 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
3375 /* Speedup test: */
3376 info_ind.n3105 := N3105_MAX;
3377 info_ind.t3195 := 1;
3378 f_init_raw(testcasename(), info_ind);
3379
3380 /* Establish BSSGP connection to the PCU */
3381 f_bssgp_establish();
3382 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3383
3384 /* Establish an Uplink TBF */
3385 f_ms_establish_ul_tbf(ms);
3386
3387 /* Send one UL block (with TLLI since we are in One-Phase Access
3388 contention resoultion) and make sure it is ACKED fine */
3389 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true, fn := ms.ul_tbf.start_time_fn);
3390
3391 /* UL block should be received in SGSN */
3392 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
3393
3394 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
3395 tr_UlAckNackGprs(ms.tlli,
3396 tr_AckNackDescription(final_ack := '1'B),
3397 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
3398 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
3399
3400 /* TODO: verify TBF_EST and FinalACK are both '1' above */
3401
3402 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
3403 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
3404
3405 /* Now Keep ignoring the Pkt Ul Ass on PACCH: */
3406 /* Now we go on receiving DL data and not answering RRBP: */
3407 nr := ts_TsTrxBtsNum;
3408 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3409 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3410 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3411 block_nr := nr.blk_nr));
3412 alt {
3413 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3414 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3415 tr_RLCMAC_UL_PACKET_ASS)) -> value data_msg {
3416 if (f_dl_block_rrbp_valid(data_msg.dl_block)) {
3417 log("Ignoring RRBP N3105 ", N3105);
3418 N3105 := N3105 + 1;
3419 }
3420 nr := ts_TsTrxBtsNum;
3421 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3422 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3423 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3424 block_nr := nr.blk_nr));
3425 repeat;
3426 }
3427 /* At this point in time (N3105_MAX reached), PCU already moved TBF to
3428 * RELEASE state so no data for it is tx'ed, hence the dummy blocks:
3429 */
3430 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3431 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3432 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3433 if (not T_3195.running) {
3434 T_3195.start;
3435 }
3436 nr := ts_TsTrxBtsNum;
3437 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3438 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3439 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3440 block_nr := nr.blk_nr));
3441 repeat;
3442 }
3443 [N3105 == N3105_MAX] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3444 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3445 omit)) -> value data_msg {
3446 /* We may already receive idle blocks before our own TTCN3 timer
3447 * triggers due to the TBF being released. Keep going until our T_3195 triggers. */
3448 nr := ts_TsTrxBtsNum;
3449 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3450 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3451 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3452 block_nr := nr.blk_nr));
3453 repeat;
3454 }
3455 /* We receive Dummy blocks in between Pkt Ul Ass while PCU waits for us to ack it */
3456 [not T_3195.running] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3457 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3458 tr_RLCMAC_DUMMY_CTRL)) -> value data_msg {
3459 log("Ignoring Dummy block FN ", data_msg.raw.fn);
3460 nr := ts_TsTrxBtsNum;
3461 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
3462 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
3463 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)),
3464 block_nr := nr.blk_nr));
3465 repeat;
3466 }
3467 [T_3195.running] T_3195.timeout {
3468 log("T_3195 timeout");
3469 /* Done in alt, wait for pending RTS initiated previously in
3470 * above case before continuing (expect nothing to be sent since there's no active TBF): */
3471 BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
3472 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
3473 omit));
3474 }
3475 [] BTS.receive {
3476 setverdict(fail, "Unexpected BTS message");
3477 f_shutdown(__BFILE__, __LINE__);
3478 }
3479 }
3480
3481 f_shutdown(__BFILE__, __LINE__, final := true);
3482}
3483
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01003484/* Test scenario where MS wants to request a new UL TBF using a DL (EGPRS) ACK/NACK
3485 * transmitted on ul slot provided by its DL TBF.
3486 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
3487function f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(boolean use_egprs) runs on RAW_PCU_Test_CT {
3488 var GprsMS ms;
3489 var octetstring data := f_rnd_octstring(10);
3490 var RlcmacDlBlock dl_block;
3491 var template RlcmacDlBlock rej_tmpl;
3492 var uint32_t dl_fn;
3493 var uint32_t sched_fn;
3494 var template (value) MSRadioAccessCapabilityV_BSSGP racap_tmpl;
3495
3496 if (use_egprs == true) {
3497 racap_tmpl := bssgp_ms_racap_egprs_def;
3498 } else {
3499 racap_tmpl := bssgp_ms_racap_gprs_def;
3500 }
3501
3502 /* Initialize NS/BSSGP side */
3503 f_init_bssgp();
3504 /* Initialize GPRS MS side */
3505 f_init_gprs_ms();
3506 ms := g_ms[0]; /* We only use first MS in this test */
3507 /* Initialize the PCU interface abstraction */
3508 f_init_raw(testcasename());
3509
3510 /* Establish BSSGP connection to the PCU */
3511 f_bssgp_establish();
3512 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3513
3514 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3515 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, racap_tmpl));
3516 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3517
3518 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3519 f_sleep(X2002);
3520 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3521
3522 /* ACK the DL block, asking for new UL TBF by including ChanReqDesc */
3523 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
3524 f_ms_tx_ul_block(ms, f_dltbf_ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf, use_egprs, ts_ChannelReqDescription()),
3525 f_dl_block_ack_fn(dl_block, dl_fn));
3526
3527 /* We should receive a Pkt Ul ASS */
3528 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
3529 f_shutdown(__BFILE__, __LINE__, final := true);
3530}
3531testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() runs on RAW_PCU_Test_CT {
3532 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(false);
3533}
3534testcase TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() runs on RAW_PCU_Test_CT {
3535 f_TC_ul_tbf_reestablish_with_pkt_dl_ack_nack(true);
3536}
3537
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003538/* Test CS paging over the BTS<->PCU socket.
3539 * 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.
3540 * Paging should be send on the PACCH.
3541 *
3542 * 1. Send a Paging Request over PCU socket.
3543 * 2. Send a Ready-To-Send message over PCU socket
3544 * 3. Expect a Paging Frame
3545 */
3546testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003547 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003548 var MobileIdentityLV mi;
3549 var octetstring mi_enc_lv;
3550 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003551 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003552
3553 /* Initialize NS/BSSGP side */
3554 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003555 /* Initialize GPRS MS side */
3556 f_init_gprs_ms();
3557 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003558
3559 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003560 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003561
3562 /* Establish BSSGP connection to the PCU */
3563 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003564 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003565
3566 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003567 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003568
3569 /* build mobile Identity */
3570 mi := valueof(ts_MI_IMSI_LV(imsi));
3571 mi_enc_lv := enc_MobileIdentityLV(mi);
3572 /* Send paging request */
3573 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
3574 sapi :=PCU_IF_SAPI_PDTCH));
3575
3576 /* Receive it on BTS side towards MS */
3577 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3578
3579 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003580 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3581 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3582 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3583 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003584
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003585 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003586}
3587
3588/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
3589 */
3590private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3591runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003592 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003593 var hexstring imsi := f_gen_imsi(42);
3594 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003595 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003596
3597 /* Initialize NS/BSSGP side */
3598 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003599 /* Initialize GPRS MS side */
3600 f_init_gprs_ms();
3601 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003602
3603 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003604 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003605
3606 /* Establish BSSGP connection to the PCU */
3607 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003608 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003609
3610 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003611 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003612
3613 /* Send paging request with or without TMSI */
3614 if (use_ptmsi) {
3615 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
3616 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
3617 } else {
3618 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
3619 }
3620
3621 /* Receive it on BTS side towards MS */
3622 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
3623
3624 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003625 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003626 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003627 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
3628 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
3629 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003630 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07003631 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
3632 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
3633 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003634 }
3635
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003636 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003637}
3638
3639testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3640 f_tc_paging_cs_from_sgsn(0, true);
3641}
3642
3643testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
3644 f_tc_paging_cs_from_sgsn(0);
3645}
3646
3647testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02003648 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003649}
3650
3651/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
3652 */
3653private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
3654runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003655 var integer imsi_suff_tx := 423;
3656 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003657 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003658
3659 /* Initialize NS/BSSGP side */
3660 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02003661 /* Initialize GPRS MS side */
3662 f_init_gprs_ms();
3663 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003664
Oliver Smith61b4e732021-07-22 08:14:29 +02003665 f_statsd_reset();
3666
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003667 /* Establish BSSGP connection to the PCU */
3668 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003669 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003670
3671 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
3672 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
3673 if (use_ptmsi) {
3674 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
3675 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
3676 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
3677 } else {
3678 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
3679 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
3680 }
3681
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003682 var StatsDExpects expect := {
3683 { name := "TTCN3.pcu.sgsn.0.rx_paging_ps", mtype := "c", min := 1, max := 1 },
3684 /* After the PCU receives the paging request from SGSN,
3685 * and it doesn't have any errors, PCU sends it to the
3686 * BTS to do paging over PCH. */
3687 { name := "TTCN3.bts.0.pch.requests", mtype := "c", min := 1, max := 1 }
3688 };
3689 f_statsd_expect(expect);
Oliver Smithfbd39312021-07-27 15:23:39 +02003690}
3691
3692testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
3693 /* Initialize the PCU interface abstraction */
3694 f_init_raw(testcasename());
3695
3696 f_tc_paging_ps_from_sgsn(0, true);
Oliver Smith61b4e732021-07-22 08:14:29 +02003697
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003698 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003699}
3700
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003701testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003702 /* Initialize the PCU interface abstraction */
3703 f_init_raw(testcasename());
3704
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003705 f_tc_paging_ps_from_sgsn(0);
Oliver Smithfbd39312021-07-27 15:23:39 +02003706
3707 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003708}
3709
3710testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Oliver Smithfbd39312021-07-27 15:23:39 +02003711 /* Initialize the PCU interface abstraction */
3712 f_init_raw(testcasename());
3713
Harald Welte5339b2e2020-10-04 22:52:56 +02003714 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Oliver Smithfbd39312021-07-27 15:23:39 +02003715
3716 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003717}
3718
Oliver Smithe1a77c42021-07-28 13:36:09 +02003719testcase TC_paging_pch_timeout() runs on RAW_PCU_Test_CT {
3720 /* Initialize the PCU interface abstraction */
3721 f_init_raw(testcasename());
3722
3723 /* Set T3113 to 1s to shorten the test duration */
3724 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 1");
3725
3726 /* Reset stats and send paging PS request */
3727 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
3728
3729 /* Verify that counter increases when T3113 times out (MS did not start
3730 * TBF to respond to paging). */
3731 f_sleep(1.2);
3732 var StatsDExpects expect := {
3733 { name := "TTCN3.bts.0.pch.requests.timeout", mtype := "c", min := 1, max := 1 }
3734 };
3735 f_statsd_expect(expect);
3736
3737 f_vty_config2(PCUVTY, {"pcu"}, "timer T3113 default");
3738 f_shutdown(__BFILE__, __LINE__, final := true);
3739}
3740
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003741/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
3742testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
3743 var RlcmacDlBlock dl_block;
3744 var octetstring data := f_rnd_octstring(10);
3745 var uint32_t sched_fn;
3746 var uint32_t dl_fn;
3747 var GprsMS ms;
3748
3749 /* Initialize NS/BSSGP side */
3750 f_init_bssgp();
3751 /* Initialize GPRS MS side */
3752 f_init_gprs_ms();
3753 ms := g_ms[0]; /* We only use first MS in this test */
3754
3755 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003756 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003757
Daniel Willmann535aea62020-09-21 13:27:08 +02003758 f_statsd_reset();
3759
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003760 /* Establish BSSGP connection to the PCU */
3761 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003762 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003763
3764 /* Establish an Uplink TBF */
3765 f_ms_establish_ul_tbf(ms);
3766
3767 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003768 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 +02003769 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3770 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3771 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3772
3773 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003774 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003775
3776 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
3777 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
3778 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3779
3780 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
3781 f_sleep(X2002);
3782 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
3783
3784 /* ACK the DL block */
3785 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
3786 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
3787 f_dl_block_ack_fn(dl_block, dl_fn));
3788
Daniel Willmann535aea62020-09-21 13:27:08 +02003789 var StatsDExpects expect := {
3790 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
3791 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
3792 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
3793 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01003794 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01003795 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02003796 };
3797 f_statsd_expect(expect);
3798
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003799 f_shutdown(__BFILE__, __LINE__, final := true);
3800}
3801
3802/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
3803testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
3804 var RlcmacDlBlock dl_block;
3805 var octetstring data := f_rnd_octstring(10);
3806 var uint32_t sched_fn;
3807 var uint32_t dl_fn;
3808 var GprsMS ms;
3809
3810 /* Initialize NS/BSSGP side */
3811 f_init_bssgp();
3812 /* Initialize GPRS MS side */
3813 f_init_gprs_ms();
3814 ms := g_ms[0]; /* We only use first MS in this test */
3815
3816 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003817 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003818
3819 /* Establish BSSGP connection to the PCU */
3820 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003821 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003822
3823 /* Establish an Uplink TBF */
3824 f_ms_establish_ul_tbf(ms);
3825
3826 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02003827 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 +02003828 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
3829 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3830 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
3831
3832 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02003833 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003834
3835 /* Now SGSN sends some DL data with an invalid IMSI */
3836 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
3837
Pau Espin Pedrolf7e947a2021-01-25 18:51:33 +01003838 BSSGP_GLOBAL[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02003839
3840 /* TODO: make sure no data is sent over PCU -> MS */
3841
3842 f_shutdown(__BFILE__, __LINE__, final := true);
3843}
3844
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003845private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
3846 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
3847 var octetstring data := f_rnd_octstring(6);
3848 var RlcmacDlBlock dl_block;
3849 var GprsMS ms;
3850 var uint32_t fn;
3851
3852 /* Initialize NS/BSSGP side */
3853 f_init_bssgp();
3854 /* Initialize GPRS MS side */
3855 f_init_gprs_ms();
3856 ms := g_ms[0]; /* We only use first MS in this test */
3857
3858 /* Initialize the PCU interface abstraction */
3859 f_init_raw(testcasename());
3860
3861 /* Establish BSSGP connection to the PCU */
3862 f_bssgp_establish();
3863 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3864
3865 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3866 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
3867 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3868
3869 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
3870 f_sleep(X2002);
3871
3872 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
3873 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
3874
3875 if (ischosen(dl_block.data_egprs)) {
3876 if (lengthof(dl_block.data_egprs.blocks) != 2) {
3877 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
3878 f_shutdown(__BFILE__, __LINE__);
3879 }
3880 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
3881 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3882 f_shutdown(__BFILE__, __LINE__);
3883 }
3884 if (not match(dl_block.data_egprs.blocks[1].payload,
3885 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
3886 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
3887 f_shutdown(__BFILE__, __LINE__);
3888 }
3889 } else if (lengthof(dl_block.data.blocks) > 1) {
3890 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
3891 f_shutdown(__BFILE__, __LINE__);
3892 }
3893
3894 f_shutdown(__BFILE__, __LINE__, final := true);
3895}
3896
3897/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3898 * containing llc data. See OS#4849 */
3899testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
3900 f_tc_dl_data_no_llc_ui_dummy(omit);
3901}
3902
3903/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
3904 * containing llc data. See OS#4849 */
3905testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01003906 f_tc_dl_data_no_llc_ui_dummy(bssgp_ms_racap_egprs_def);
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01003907}
3908
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003909private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003910 template GsmRrMessage t_imm_ass := ?,
3911 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003912runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003913 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003914 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003915
3916 ra11 := enc_EGPRSPktChRequest2uint(req);
3917 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
3918
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07003919 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07003920 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003921 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003922 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003923 }
3924
3925 setverdict(pass);
3926}
3927
3928testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
3929 var template GsmRrMessage imm_ass;
3930 var template IaRestOctets rest;
3931 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003932 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003933
3934 /* Initialize the PCU interface abstraction */
3935 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003936 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003937
3938 var EGPRSPktChRequest req := {
3939 /* NOTE: other fields are set in the loop */
3940 signalling := { tag := '110011'B }
3941 };
3942
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003943 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003944 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3945 req.signalling.random_bits := ext_ra;
3946
3947 /* For signalling, do we expect Multiblock UL TBF Assignment? */
3948 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
3949 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3950 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
3951
3952 f_TC_egprs_pkt_chan_req(req, imm_ass);
3953 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003954
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01003955 var StatsDExpects expect := {
3956 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
3957 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
3958 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
3959 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
3960 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
3961 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
3962 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
3963 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
3964 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
3965 };
3966 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003967
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07003968 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003969}
3970
3971testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
3972 var template GsmRrMessage imm_ass;
3973 var template IaRestOctets rest;
3974 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003975 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003976
3977 /* Initialize the PCU interface abstraction */
3978 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003979 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003980
3981 var EGPRSPktChRequest req := {
3982 /* NOTE: other fields are set in the loop */
3983 one_phase := { tag := '0'B }
3984 };
3985
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01003986 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02003987 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
3988 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
3989 var BIT2 priority := substr(ext_ra, 0, 2);
3990 var BIT3 rand := substr(ext_ra, 2, 3);
3991
3992 req.one_phase.multislot_class := mslot_class;
3993 req.one_phase.priority := priority;
3994 req.one_phase.random_bits := rand;
3995
3996 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
3997 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
3998 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
3999 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4000
4001 f_TC_egprs_pkt_chan_req(req, imm_ass);
4002 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004003
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004004 var StatsDExpects expect := {
4005 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4006 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4007 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := num_req, max := num_req },
4008 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4009 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4010 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := num_req, max := num_req },
4011 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4012 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4013 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4014 };
4015 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004016
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004017 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004018}
4019
4020testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
4021 var template GsmRrMessage imm_ass;
4022 var template IaRestOctets rest;
4023 var template EgprsUlAss ul_ass;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004024 const integer num_req := 6;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004025
4026 /* Initialize the PCU interface abstraction */
4027 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004028 f_statsd_reset();
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004029
4030 var EGPRSPktChRequest req := {
4031 /* NOTE: other fields are set in the loop */
4032 two_phase := { tag := '110000'B }
4033 };
4034
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004035 for (var integer i := 0; i < num_req; i := i + 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004036 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
4037 var BIT2 priority := substr(ext_ra, 0, 2);
4038 var BIT3 rand := substr(ext_ra, 2, 3);
4039
4040 req.two_phase.priority := priority;
4041 req.two_phase.random_bits := rand;
4042
4043 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
4044 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
4045 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
4046 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
4047
4048 f_TC_egprs_pkt_chan_req(req, imm_ass);
4049 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004050
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004051 var StatsDExpects expect := {
4052 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4053 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4054 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4055 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := num_req, max := num_req },
4056 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := num_req, max := num_req },
4057 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 0, max := 0 },
4058 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := num_req, max := num_req },
4059 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4060 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4061 };
4062 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004063
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07004064 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004065}
4066
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004067private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
4068 template IARRestOctets rest := ?,
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004069 PCUIF_BurstType bt := BURST_TYPE_1,
4070 template WaitIndication wi := ?)
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004071runs on RAW_PCU_Test_CT {
4072 var template ReqRefWaitInd tr_ref;
4073 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004074
4075 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
4076 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
4077 ra := bit2int(ra11), is_11bit := 1,
4078 burst_type := bt, fn := fn,
4079 arfcn := 871));
4080
4081 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07004082 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004083
4084 /* Just to have a short-name reference to the actual message */
4085 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
4086
4087 /* Make sure that Request Reference list contains at least one entry
4088 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004089 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn), wi);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004090 if (not match(iar.payload, { *, tr_ref, * })) {
4091 setverdict(fail, "Request Reference list does not match");
4092 f_shutdown(__BFILE__, __LINE__);
4093 }
4094
4095 /* Match Feature Indicator (must indicate PS domain) */
4096 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
4097 setverdict(fail, "Feature Indicator does not match");
4098 f_shutdown(__BFILE__, __LINE__);
4099 }
4100
4101 /* Match IAR Rest Octets */
4102 if (not match(iar.rest_octets, rest)) {
4103 setverdict(fail, "IAR Rest Octets does not match: ",
4104 iar.rest_octets, " vs expected ", rest);
4105 f_shutdown(__BFILE__, __LINE__);
4106 }
4107
4108 setverdict(pass);
4109}
4110
4111/* Verify the contents of RR Immediate Assignment Reject message and its
4112 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
4113testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
4114 var template IARRestOctets rest;
4115 var BIT5 ext_ra;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004116 const integer num_req := 6;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004117
4118 /* Initialize the PCU interface abstraction */
4119 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004120 f_statsd_reset();
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004121
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004122 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004123 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4124 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4125
4126 /* Intentionally incorrect message (see table 11.2.5a.2) */
4127 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
4128 }
4129
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004130 var StatsDExpects expect := {
4131 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4132 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4133 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4134 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4135 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4136 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4137 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4138 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4139 };
4140 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004141
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004142 f_shutdown(__BFILE__, __LINE__, final := true);
4143}
4144
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004145/* At the moment, the IUT does not support any emergency services. Make sure
4146 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
4147testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
4148 var template IARRestOctets rest;
4149 var BIT5 ext_ra;
4150 var BIT11 ra11;
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004151 const integer num_req := 6;
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004152
4153 /* Initialize the PCU interface abstraction */
4154 f_init_raw(testcasename());
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004155 f_statsd_reset();
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004156
4157 var EGPRSPktChRequest req := {
4158 /* NOTE: other fields are set in the loop */
4159 emergency := { tag := '110111'B }
4160 };
4161
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004162 for (var integer i := 0; i < num_req; i := i + 1) {
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004163 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
4164 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
4165
4166 req.emergency.random_bits := ext_ra;
4167 ra11 := enc_EGPRSPktChRequest2bits(req);
4168
4169 /* Intentionally incorrect message (see table 11.2.5a.2) */
4170 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
4171 }
4172
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004173 var StatsDExpects expect := {
4174 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := num_req, max := num_req },
4175 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := num_req, max := num_req },
4176 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 0, max := 0 },
4177 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4178 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := num_req, max := num_req },
4179 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0 },
4180 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := num_req, max := num_req },
4181 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4182 };
4183 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004184
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004185 f_shutdown(__BFILE__, __LINE__, final := true);
4186}
4187
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004188/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
4189testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004190 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004191 var template IARRestOctets rest;
4192 var BIT11 ra11;
4193
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004194 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004195 info_ind.t3142 := 3;
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07004196
4197 /* Only the first TRX is enabled. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004198 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
4199 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004200
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004201 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01004202 f_init_raw(testcasename(), info_ind);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004203 f_statsd_reset();
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004204
4205 var EGPRSPktChRequest req := {
4206 one_phase := {
4207 tag := '0'B,
4208 multislot_class := '10101'B,
4209 priority := '01'B,
4210 random_bits := '101'B
4211 }
4212 };
4213
4214 /* We send 7 requests, the IUT gives us all available USFs (0..6).
4215 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
4216 for (var integer i := 0; i < 7; i := i + 1) {
4217 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
4218 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
4219 }
4220
4221 ra11 := enc_EGPRSPktChRequest2bits(req);
4222 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
4223
4224 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrola5cee4c2021-04-26 13:50:29 +02004225 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest, wi := info_ind.t3142);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004226
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01004227 var StatsDExpects expect := {
4228 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 8, max := 8 },
4229 { name := "TTCN3.bts.0.rach.requests.11bit", mtype := "c", min := 8, max := 8 },
4230 { name := "TTCN3.bts.0.rach.requests.one_phase", mtype := "c", min := 8, max := 8 },
4231 { name := "TTCN3.bts.0.rach.requests.two_phase", mtype := "c", min := 0, max := 0 },
4232 { name := "TTCN3.bts.0.rach.requests.unexpected", mtype := "c", min := 0, max := 0 },
4233 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 7, max := 7 },
4234 { name := "TTCN3.bts.0.immediate.assignment_ul.one_phase", mtype := "c", min := 7, max := 7 },
4235 { name := "TTCN3.bts.0.immediate.assignment_ul.two_phase", mtype := "c", min := 0, max := 0 },
4236 { name := "TTCN3.bts.0.immediate.assignment_ul.contention_resolution_success", mtype := "c", min := 0, max := 0 },
4237 { name := "TTCN3.bts.0.immediate.assignment_rej", mtype := "c", min := 1, max := 1 },
4238 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 0, max := 0 }
4239 };
4240 f_statsd_expect(expect);
Pau Espin Pedrol023330d2021-11-08 14:10:21 +01004241
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004242 f_shutdown(__BFILE__, __LINE__, final := true);
4243}
4244
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004245/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004246private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004247return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07004248 /* Pick a random MA length in range 2 .. max_ma_len */
4249 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
4250
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004251 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
4252 hsn := f_rnd_int(63),
4253 maio := f_rnd_int(63),
4254 ma := f_rnd_bitstring(ma_len));
4255}
4256
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004257private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
4258 in GsmRrMessage rr_msg)
4259{
4260 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004261 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[ia.pkt_chan_desc.tn];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004262
4263 var template PacketChannelDescription tr_pkt_chan_desc := {
4264 channel_Type_spare := ?,
4265 tn := ?,
4266 tsc := ts.tsc,
4267 presence := '1'B,
4268 zero := omit,
4269 one := {
4270 maio := ts.maio,
4271 hsn := ts.hsn
4272 }
4273 };
4274
4275 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
4276 setverdict(fail, "Packet Channel Description does not match: ",
4277 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
4278 }
4279
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004280 /* Mobile Allocation is expected to be octet-aligned */
4281 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
4282 var template MobileAllocationLV tr_ma := {
4283 len := ma_oct_len, /* in bytes */
4284 ma := substr(ts.ma, 0, ma_oct_len * 8)
4285 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004286
4287 if (not match(ia.mobile_allocation, tr_ma)) {
4288 setverdict(fail, "Mobile Allocation does not match: ",
4289 ia.mobile_allocation, " vs ", tr_ma);
4290 }
4291
4292 setverdict(pass);
4293}
4294
4295/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
4296testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004297 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004298 var GprsMS ms := valueof(t_GprsMS_def);
4299
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004300 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004301 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004302
4303 /* Initialize the PCU interface abstraction */
4304 f_init_raw(testcasename(), info_ind);
4305
4306 /* EGPRS Packet Channel Request (cause=Signalling) */
4307 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
4308
4309 /* Establish an Uplink EGPRS TBF */
4310 f_ms_establish_ul_tbf(ms);
4311
4312 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4313 f_shutdown(__BFILE__, __LINE__, final := true);
4314}
4315
4316/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
4317testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004318 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004319 var GprsMS ms := valueof(t_GprsMS_def);
4320
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004321 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004322 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004323
4324 /* Initialize the PCU interface abstraction */
4325 f_init_raw(testcasename(), info_ind);
4326
4327 /* Establish an Uplink TBF */
4328 f_ms_establish_ul_tbf(ms);
4329
4330 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
4331 f_shutdown(__BFILE__, __LINE__, final := true);
4332}
4333
4334/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
4335testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004336 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004337 var GprsMS ms := valueof(t_GprsMS_def);
4338
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004339 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004340 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004341
4342 /* Initialize NS/BSSGP side */
4343 f_init_bssgp();
4344
4345 /* Initialize the PCU interface abstraction */
4346 f_init_raw(testcasename(), info_ind);
4347
4348 /* Establish BSSGP connection to the PCU */
4349 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004350 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004351
4352 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
4353 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
4354 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
4355
4356 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
4357 f_shutdown(__BFILE__, __LINE__, final := true);
4358}
4359
4360private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
4361 in FrequencyParameters fp)
4362{
4363 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004364 var PCUIF_InfoTrxTs ts := info_ind.trx[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004365
4366 /* Table 12.8.1: Frequency Parameters information elements */
4367 var template FrequencyParameters tr_fp := {
4368 tsc := ts.tsc,
4369 presence := '10'B, /* Direct encoding 1 */
4370 arfcn := omit,
4371 indirect := omit,
4372 direct1 := {
4373 maio := ts.maio,
4374 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
4375 mobile_allocation := {
4376 hsn := ts.hsn,
4377 rfl_number_list_present := '0'B,
4378 rfl_number_list := omit,
4379 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07004380 ma_length := ts.ma_bit_len,
4381 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004382 }
4383 },
4384 direct2 := omit
4385 };
4386
4387 if (not match(fp, tr_fp)) {
4388 setverdict(fail, "Frequency Parameters IE does not match: ",
4389 fp, " vs ", tr_fp);
4390 }
4391
4392 setverdict(pass);
4393}
4394
4395/* Make sure that Packet Uplink Assignment contains hopping parameters */
4396testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004397 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004398 var GprsMS ms := valueof(t_GprsMS_def);
4399 var uint32_t poll_fn;
4400
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004401 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004402 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004403
4404 /* Initialize the PCU interface abstraction */
4405 f_init_raw(testcasename(), info_ind);
4406
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004407 /* Single block (two phase) packet access */
4408 var uint16_t ra := bit2int(chan_req_sb);
4409 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
4410
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004411 /* Establish an Uplink TBF */
4412 f_ms_establish_ul_tbf(ms);
4413
4414 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004415 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)),
4416 fn := ms.ul_tbf.start_time_fn);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004417
4418 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004419 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
4420 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004421
4422 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
4423 var template (omit) FrequencyParameters fp;
4424 if (ua.is_egprs == '1'B) {
4425 fp := ua.egprs.freq_par;
4426 } else {
4427 fp := ua.gprs.freq_par;
4428 }
4429
4430 /* This is an optional IE, so it's worth to check its presence */
4431 if (istemplatekind(fp, "omit")) {
4432 setverdict(fail, "Frequency Parameters IE is not present");
4433 f_shutdown(__BFILE__, __LINE__);
4434 }
4435
4436 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
4437 f_shutdown(__BFILE__, __LINE__, final := true);
4438}
4439
4440/* Make sure that Packet Downlink Assignment contains hopping parameters */
4441testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004442 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004443 var octetstring data := f_rnd_octstring(10);
4444 var GprsMS ms := valueof(t_GprsMS_def);
4445 var RlcmacDlBlock dl_block;
4446 var uint32_t poll_fn;
4447
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07004448 /* Enable frequency hopping on TRX0/TS7 */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004449 info_ind.trx[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004450
4451 /* Initialize NS/BSSGP side */
4452 f_init_bssgp();
4453
4454 /* Initialize the PCU interface abstraction */
4455 f_init_raw(testcasename(), info_ind);
4456
4457 /* Establish BSSGP connection to the PCU */
4458 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01004459 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004460
4461 /* Establish an Uplink TBF */
4462 f_ms_establish_ul_tbf(ms);
4463
4464 /* Send an Uplink block, so this TBF becomes "active" */
Pau Espin Pedroldee55702021-04-23 21:08:22 +02004465 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 +07004466
4467 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
4468 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
4469 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
4470
4471 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
4472 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
4473
4474 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01004475 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
4476 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004477
4478 /* This is an optional IE, so it's worth to check its presence */
4479 if (not ispresent(da.freq_par)) {
4480 setverdict(fail, "Frequency Parameters IE is not present");
4481 f_shutdown(__BFILE__, __LINE__);
4482 }
4483
4484 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
4485 f_shutdown(__BFILE__, __LINE__, final := true);
4486}
4487
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004488/* Check if the IUT handles subsequent INFO.ind messages */
4489testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01004490 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004491 var BTS_PDTCH_Block data_msg;
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004492
4493 /* Initialize the PCU interface abstraction */
4494 f_init_raw(testcasename(), info_ind);
4495
4496 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
4497 for (var integer i := 0; i < 16; i := i + 1) {
4498 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
Pau Espin Pedrolb34bb062021-01-19 18:58:07 +01004499 f_pcuif_rx_data_req_pdtch(data_msg);
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004500 }
4501
4502 f_shutdown(__BFILE__, __LINE__, final := true);
4503}
4504
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004505/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
4506testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
4507 var PCUIF_info_ind info_ind;
4508 var integer i;
4509 const integer num_ms := 8;
4510
4511 /* Initialize NS/BSSGP side */
4512 f_init_bssgp();
4513 /* Initialize GPRS MS side */
4514 f_init_gprs_ms(num_ms);
4515
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01004516 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004517 /* Only the 3 first TRX are enabled. The enabled ones all have same
4518 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004519 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
4520 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
4521 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
4522 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004523
4524 /* Initialize the PCU interface abstraction */
4525 f_init_raw(testcasename(), info_ind);
4526
4527 /* Establish BSSGP connection to the PCU */
4528 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004529 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004530
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07004531 /* Establish an Uplink TBF for each GprsMS instance */
4532 f_multi_ms_establish_tbf(do_activate := false);
4533
4534 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004535 for (i := 0; i < num_ms; i := i + 1) {
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004536 if (g_ms[i].ul_tbf.arfcn != info_ind.trx[i mod 3].arfcn) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01004537 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004538 " vs exp ", info_ind.trx[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004539 f_shutdown(__BFILE__, __LINE__);
4540 }
4541 }
4542
4543 f_shutdown(__BFILE__, __LINE__, final := true);
4544}
4545
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004546/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
4547 * downgraded to CS1-4 so that GPRS can read the USF).
4548 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
4549 */
4550testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
4551 var PCUIF_info_ind info_ind;
4552 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
4553 var PollFnCtx pollctx;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004554 var uint32_t sched_fn, dl_fn, ack_fn;
4555 var octetstring data := f_rnd_octstring(10);
4556 var RlcmacDlBlock dl_block;
4557 var integer tx_data_remain := 5;
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004558 var integer tgt_ms, usf_ms;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004559 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
4560 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
4561
4562 /* Initialize NS/BSSGP side */
4563 f_init_bssgp();
4564 /* Initialize GPRS MS side */
4565 f_init_gprs_ms(num_ms);
4566
4567 info_ind := valueof(ts_PCUIF_INFO_default);
4568 /* Only use 1 PDCH to make sure both end up in the same slot: */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004569 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
4570 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004571
4572 /* Initialize the PCU interface abstraction */
4573 f_init_raw(testcasename(), info_ind);
4574
4575 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
4576 g_mcs_initial_dl := 5;
4577 g_mcs_max_dl := 5;
4578 f_pcuvty_set_allowed_cs_mcs();
4579
4580 /* Establish BSSGP connection to the PCU */
4581 f_bssgp_establish();
4582 f_multi_ms_bssgp_register();
4583
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004584 /* Establish UL TBF for MS0 (GPRS-only) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004585 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 +01004586 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
4587 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
4588 f_shutdown(__BFILE__, __LINE__);
4589 }
4590 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4591 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4592
4593 /* Establish UL TBF for MS1 (EGPRS) */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01004594 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 +01004595 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
4596 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
4597 f_shutdown(__BFILE__, __LINE__);
4598 }
4599 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4600 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
4601
4602 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
4603 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4604 f_sleep(0.1);
4605 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4606 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4607 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
4608 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4609 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
4610 /* ACK the DL block */
4611 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
4612 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
4613 f_dl_block_ack_fn(dl_block, dl_fn));
4614
4615 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
4616 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4617 f_sleep(0.1);
4618 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
4619 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
4620 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
4621 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
4622 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
4623 /* ACK the DL block */
4624 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
4625 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
4626 f_dl_block_ack_fn(dl_block, dl_fn));
4627
4628 data := f_rnd_octstring(1400);
4629 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4630 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4631
4632 for (var integer i := 0; i < 800; i := i + 1) {
4633 f_rx_rlcmac_dl_block(dl_block, dl_fn);
4634
4635 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
4636 /* No more data to receive, done */
4637 break;
4638 }
4639
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004640 usf_ms := -1;
4641
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004642 if (ischosen(dl_block.ctrl)) {
4643 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
4644 f_shutdown(__BFILE__, __LINE__);
4645 } else if (ischosen(dl_block.data_egprs)) {
4646 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
4647 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
4648 f_shutdown(__BFILE__, __LINE__);
4649 }
4650 tgt_ms := 1;
4651 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
4652 if (dl_block.data_egprs.mcs > MCS_4) {
4653 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
4654 f_shutdown(__BFILE__, __LINE__);
4655 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004656 usf_ms := 0;
4657 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004658 } else {
4659 if (dl_block.data_egprs.mcs <= MCS_4) {
4660 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
4661 f_shutdown(__BFILE__, __LINE__);
4662 }
4663 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004664 usf_ms := 1;
4665 ms_egprs_usf_count[usf_ms] := ms_egprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004666 }
4667 }
4668 } else {
4669 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
4670 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
4671 f_shutdown(__BFILE__, __LINE__);
4672 }
4673 tgt_ms := 0;
4674 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 +01004675 usf_ms := 0;
4676 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004677 } 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 +01004678 usf_ms := 1;
4679 ms_gprs_usf_count[usf_ms] := ms_gprs_usf_count[usf_ms] + 1;
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004680 }
4681 }
4682
4683 /* Keep Ack/Nack description updated */
4684 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
4685
4686 /* TDMA frame number on which we are supposed to send the ACK */
4687 if (f_dl_block_rrbp_valid(dl_block)) {
4688 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
4689 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);
4690 if (tx_data_remain != 0) {
4691 /* Submit more data from time to time to keep the TBF ongoing */
4692 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
4693 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
4694 tx_data_remain := tx_data_remain - 1;
4695 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004696 } else if (tx_data_remain != 0) {
4697 /* keep sending UL blocks when requested by USF to avoid
4698 * UL TBF timeout and hence stop receival of USFs */
4699 if (usf_ms != -1) {
4700 f_ms_tx_ul_data_block(g_ms[usf_ms], f_rnd_octstring(10), cv := 15);
4701 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004702 }
4703 }
4704
4705 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 +01004706 /* He we check that DL blocks scheduled at GPRS can still request UL
4707 * blocks for EGPRS MS, and the other way around. Furthermore, the 2nd
4708 * condition also ensures the downgrade to <=MCS4 condition is tested
4709 * above */
4710 if (ms_gprs_usf_count[1] == 0 or ms_egprs_usf_count[0] == 0) {
4711 setverdict(fail, "USF exchange thresholds not met!");
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004712 f_shutdown(__BFILE__, __LINE__);
4713 }
Pau Espin Pedrol4ceb61c2021-03-24 18:03:42 +01004714 /* Here check for some level of fairness between them (at least ~40%): */
4715 var integer gprs_usf_cnt := ms_gprs_usf_count[0] + ms_egprs_usf_count[0];
4716 var integer egprs_usf_cnt := ms_gprs_usf_count[1] + ms_egprs_usf_count[1];
4717 var integer total_usf_cnt := gprs_usf_cnt + egprs_usf_cnt;
4718 if (gprs_usf_cnt < total_usf_cnt * 4 / 10) {
4719 setverdict(fail, "USF GPRS-only MS ", gprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4720 f_shutdown(__BFILE__, __LINE__);
4721 }
4722 if (egprs_usf_cnt < total_usf_cnt * 4 / 10) {
4723 setverdict(fail, "USF EGPRS MS ", egprs_usf_cnt, " < ", total_usf_cnt * 4 / 10);
4724 f_shutdown(__BFILE__, __LINE__);
4725 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004726
4727 f_shutdown(__BFILE__, __LINE__, final := true);
4728}
4729
4730
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004731private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
4732 boolean exp_imsi, boolean exp_tmsi)
4733runs on RAW_PCU_Test_CT {
4734 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
4735 var integer pending := lengthof(g_ms);
4736 var RlcmacDlBlock dl_block;
4737 var boolean f1, f2;
4738
4739 while (pending > 0) {
4740 var uint32_t poll_fn;
4741
4742 /* Obtain a Downlink block and make sure it is a paging request */
4743 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
4744 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
4745 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4746 break;
4747 }
4748
4749 /* This should not happen in general, but who knows... */
4750 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
4751 if (not ispresent(req.repeated_pageinfo)) {
4752 setverdict(fail, "Repeated Page Info IE is absent?!?");
4753 break;
4754 }
4755
4756 /* A single message may contain several MIs depending on their type */
4757 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4758 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
4759 ps_domain := false);
4760 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
4761 ps_domain := false);
4762 if (not f1 and not f2)
4763 { continue; }
4764
4765 /* Detect duplicate MIs */
4766 if (mask[i] == '1'B) {
4767 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
4768 continue;
4769 }
4770
4771 mask[i] := '1'B;
4772 }
4773
4774 pending := pending - lengthof(req.repeated_pageinfo);
4775 }
4776
4777 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
4778 if (mask[i] != '1'B) {
4779 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
4780 log("===== mask := ", mask);
4781 }
4782 }
4783
4784 /* All messages must have been received by now, expect a dummy block */
4785 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
4786}
4787
4788private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
4789runs on RAW_PCU_Test_CT {
4790 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4791 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4792
4793 /* Initialize NS/BSSGP side */
4794 f_init_bssgp();
4795
4796 /* Explicitly set the given PDCH slot-mask to all transceivers */
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01004797 f_PCUIF_PDCHMask_set(info_ind, pdch_mask);
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004798
4799 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
4800 f_init_gprs_ms(7 * 8);
4801
4802 /* Initialize the PCU interface abstraction */
4803 f_init_raw(testcasename(), info_ind);
4804
4805 /* Establish BSSGP connection to the PCU */
4806 f_bssgp_establish();
4807 f_multi_ms_bssgp_register();
4808
4809 /* Establish an Uplink TBF for each GprsMS instance */
4810 f_multi_ms_establish_tbf(do_activate := true);
4811}
4812
4813testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
4814 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4815
4816 /* Common part: send INFO.ind, establish TBFs... */
4817 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4818
4819 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
4820 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4821 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4822 }
4823
4824 /* FIXME: work around a race condition between PCUIF and BSSGP */
4825 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4826
4827 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4828 * The IUT is expected to page on all PDCH slots of all transceivers. */
4829 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4830 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4831 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
4832 }
4833
4834 f_shutdown(__BFILE__, __LINE__, final := true);
4835}
4836
4837testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
4838 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4839
4840 /* Common part: send INFO.ind, establish TBFs... */
4841 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4842
4843 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
4844 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4845 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4846 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4847 }
4848
4849 /* FIXME: work around a race condition between PCUIF and BSSGP */
4850 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4851
4852 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4853 * The IUT is expected to page on all PDCH slots of all transceivers. */
4854 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4855 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4856 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
4857 }
4858
4859 f_shutdown(__BFILE__, __LINE__, final := true);
4860}
4861
4862testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
4863 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
4864
4865 /* Common part: send INFO.ind, establish TBFs... */
4866 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
4867
4868 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
4869 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
4870 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
4871 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
4872 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
4873 } else {
4874 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
4875 }
4876 }
4877
4878 /* FIXME: work around a race condition between PCUIF and BSSGP */
4879 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
4880
4881 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
4882 * The IUT is expected to page on all PDCH slots of all transceivers. */
4883 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
4884 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
4885 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
4886 }
4887
4888 f_shutdown(__BFILE__, __LINE__, final := true);
4889}
4890
Pau Espin Pedrola846e612021-02-01 19:25:25 +01004891private function f_skip_dummy(integer max_num_iter, out uint32_t sched_fn)
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004892runs on RAW_PCU_Test_CT return RlcmacDlBlock {
4893 var RlcmacDlBlock dl_block;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004894 var integer i := 0;
4895 while (true) {
4896 f_rx_rlcmac_dl_block(dl_block, sched_fn);
4897 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
4898 break;
4899 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004900 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004901 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4902 f_shutdown(__BFILE__, __LINE__);
4903 }
4904 i := i + 1;
4905 }
4906 return dl_block;
4907}
4908
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01004909private function f_outbound_nacc_rim_tx_resp(PCUIF_info_ind info_ind)
4910runs on RAW_PCU_Test_CT {
4911 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),
4912 info_ind.lac),
4913 info_ind.rac),
4914 info_ind.cell_id));
4915 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4916 423),
4917 2),
4918 5));
4919 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4920 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4921 var template (value) RAN_Information_RIM_Container res_cont :=
4922 ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
4923 ts_RIM_Sequence_Number(2),
4924 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
4925 ts_RIM_Protocol_Version_Number(1),
4926 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
4927 omit);
4928 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4929 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4930 res_cont));
4931}
4932
4933altstep as_outbound_nacc_rim_resolve(PCUIF_info_ind info_ind, boolean do_answer := true, boolean do_repeat := false)
4934runs on RAW_PCU_Test_CT {
4935 /* RIM procedure: */
4936 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),
4937 info_ind.lac),
4938 info_ind.rac),
4939 info_ind.cell_id));
4940 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4941 423),
4942 2),
4943 5));
4944 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src));
4945 var RIM_Routing_Address dst_addr := valueof(t_RIM_Routing_Address_cid(dst));
4946 [] RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4947 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4948 tr_RAN_Information_Request_RIM_Container)) {
4949 if (do_answer) {
4950 f_outbound_nacc_rim_tx_resp(info_ind);
4951 }
4952 if (do_repeat) {
4953 repeat;
4954 }
4955 }
4956}
4957
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004958private function f_handle_nacc_rac_ci_query(PCUIF_info_ind info_ind, GsmArfcn req_arfcn, uint6_t req_bsic,
4959 boolean answer := true, boolean use_old_ctrl_iface := false)
4960runs on RAW_PCU_Test_CT {
4961 if (use_old_ctrl_iface == true) {
4962 f_ipa_ctrl_wait_link_up();
4963 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4964 int2str(info_ind.lac) & "." &
4965 int2str(info_ind.cell_id) & "." &
4966 int2str(req_arfcn) & "." &
4967 int2str(req_bsic);
4968 if (answer) {
4969 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4970 } else {
4971 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
4972 }
4973 } else {
4974 var PCUIF_Message pcu_msg;
4975 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
4976 if (answer) {
4977 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
4978 }
4979 }
4980}
4981
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004982/* Start NACC from MS side */
4983private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01004984 boolean exp_rac_ci_query := true, boolean exp_si_query := true,
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02004985 boolean skip_final_ctrl_ack := false,
4986 boolean use_old_ctrl_iface := false)
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004987runs on RAW_PCU_Test_CT {
4988 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4989 var RlcmacDlBlock dl_block;
4990 var uint32_t sched_fn;
4991 var GsmArfcn req_arfcn := 862;
4992 var uint6_t req_bsic := 43;
4993
4994 /* Start NACC from MS side */
4995 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4996 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4997
4998 if (exp_rac_ci_query == true) {
4999 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005000 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005001 }
5002
5003 if (exp_si_query == true) {
5004 /* RIM procedure: */
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005005 as_outbound_nacc_rim_resolve(info_ind);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005006 }
5007
5008 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005009 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005010
5011 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5012 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5013 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5014 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5015 f_shutdown(__BFILE__, __LINE__);
5016 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005017 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005018 if (not skip_final_ctrl_ack and dl_block.ctrl.mac_hdr.rrbp_valid) {
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005019 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5020 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5021 }
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005022}
5023
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005024/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
5025testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005026 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005027 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005028 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005029 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005030
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005031 if (use_old_ctrl_iface) {
5032 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5033 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5034 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005035
5036 /* Initialize NS/BSSGP side */
5037 f_init_bssgp();
5038 /* Initialize GPRS MS side */
5039 f_init_gprs_ms();
5040 ms := g_ms[0]; /* We only use first MS in this test */
5041
5042 /* Initialize the PCU interface abstraction */
5043 f_init_raw(testcasename(), info_ind);
5044
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005045 /* Make sure we are not affected by full cache from previous tests */
5046 f_pcuvty_flush_neigh_caches();
5047
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005048 /* Establish BSSGP connection to the PCU */
5049 f_bssgp_establish();
5050 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5051
5052 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005053 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 +01005054 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5055 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5056
5057 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005058 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005059
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005060 f_shutdown(__BFILE__, __LINE__, final := true);
5061}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005062
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005063/* Verify Pkt Cell Change Continue is retransmitted if not CTRL ACKed */
5064testcase TC_nacc_outbound_success_no_ctrl_ack() runs on RAW_PCU_Test_CT {
5065 var PollFnCtx pollctx;
5066 var GprsMS ms;
5067 var RlcmacDlBlock dl_block;
5068 var uint32_t sched_fn;
5069 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005070 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005071
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005072 if (use_old_ctrl_iface) {
5073 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5074 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5075 }
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005076
5077 /* Initialize NS/BSSGP side */
5078 f_init_bssgp();
5079 /* Initialize GPRS MS side */
5080 f_init_gprs_ms();
5081 ms := g_ms[0]; /* We only use first MS in this test */
5082
5083 /* Initialize the PCU interface abstraction */
5084 f_init_raw(testcasename(), info_ind);
5085
5086 /* Make sure we are not affected by full cache from previous tests */
5087 f_pcuvty_flush_neigh_caches();
5088
5089 /* Establish BSSGP connection to the PCU */
5090 f_bssgp_establish();
5091 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5092
5093 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005094 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 +01005095 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5096 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5097
5098 /* Start NACC from MS side, avoid sending final CTRL ACK */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005099 f_outbound_nacc_success(ms, info_ind, skip_final_ctrl_ack := true, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01005100
5101 /* Wait until we receive something non-dummy */
5102 dl_block := f_skip_dummy(0, sched_fn);
5103 /* Make sure it is a Pkt Cell Chg Continue (retransmitted)*/
5104 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5105 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5106 }
5107 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5108 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5109 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5110 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5111 }
5112
5113 f_shutdown(__BFILE__, __LINE__, final := true);
5114}
5115
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005116/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
5117testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
5118 var PollFnCtx pollctx;
5119 var GprsMS ms;
5120 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005121 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005122 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005123
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005124 if (use_old_ctrl_iface) {
5125 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5126 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5127 }
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005128
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005129 /* Initialize NS/BSSGP side */
5130 f_init_bssgp();
5131 /* Initialize GPRS MS side */
5132 f_init_gprs_ms();
5133 ms := g_ms[0]; /* We only use first MS in this test */
5134
5135 /* Initialize the PCU interface abstraction */
5136 f_init_raw(testcasename(), info_ind);
5137
5138 /* Make sure we are not affected by full cache from previous tests */
5139 f_pcuvty_flush_neigh_caches();
5140 /* Set timeout values for caches so that entries will be in cache during second try */
5141 f_pcuvty_set_neigh_caches(10, 10);
5142
5143 /* Establish BSSGP connection to the PCU */
5144 f_bssgp_establish();
5145 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5146
5147 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005148 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 +01005149 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5150 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5151
5152 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005153 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005154
5155 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005156 f_outbound_nacc_success(ms, info_ind, false, false, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01005157
5158 f_shutdown(__BFILE__, __LINE__, final := true);
5159}
5160
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005161/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC,
5162 * TS 44.060 sec 8.8) twice, the second time after caches timed out
5163 */
5164testcase TC_nacc_outbound_success_twice_nocache() runs on RAW_PCU_Test_CT {
5165 var PollFnCtx pollctx;
5166 var GprsMS ms;
5167 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005168 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005169 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005170
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005171 if (use_old_ctrl_iface) {
5172 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5173 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5174 }
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005175
5176 /* Initialize NS/BSSGP side */
5177 f_init_bssgp();
5178 /* Initialize GPRS MS side */
5179 f_init_gprs_ms();
5180 ms := g_ms[0]; /* We only use first MS in this test */
5181
5182 /* Initialize the PCU interface abstraction */
5183 f_init_raw(testcasename(), info_ind);
5184
5185 /* Make sure we are not affected by full cache from previous tests */
5186 f_pcuvty_flush_neigh_caches();
5187 /* Set timeout values for caches so that entries will be erased before the second try */
5188 f_pcuvty_set_neigh_caches(1, 1);
5189
5190 /* Establish BSSGP connection to the PCU */
5191 f_bssgp_establish();
5192 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5193
5194 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005195 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 +01005196 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5197 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5198
5199 /* Start NACC from MS side */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005200 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005201
5202 /* CTRL client should have disconnected from us */
5203 f_ipa_ctrl_wait_link_down();
5204 /* wait for cache entries to time out */
5205 f_sleep(2.0);
5206 /* First NACC procedure is done, let's try to start a new one now that previous queries have timed out: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005207 f_outbound_nacc_success(ms, info_ind, use_old_ctrl_iface := use_old_ctrl_iface);
Pau Espin Pedrol85366682021-01-27 19:04:54 +01005208
5209 f_shutdown(__BFILE__, __LINE__, final := true);
5210}
5211
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005212/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005213testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
5214 var RlcmacDlBlock dl_block;
5215 var PollFnCtx pollctx;
5216 var uint32_t sched_fn;
5217 var GprsMS ms;
5218 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5219 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005220 var GsmArfcn req_arfcn := 862;
5221 var uint6_t req_bsic := 43;
5222
5223 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
5224 * resolution CTRL port, to trigger Conn Refused by socket:
5225 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5226 */
5227
5228 /* Initialize NS/BSSGP side */
5229 f_init_bssgp();
5230 /* Initialize GPRS MS side */
5231 f_init_gprs_ms();
5232 ms := g_ms[0]; /* We only use first MS in this test */
5233
5234 /* Initialize the PCU interface abstraction */
5235 f_init_raw(testcasename(), info_ind);
5236
5237 /* Make sure we are not affected by full cache from previous tests */
5238 f_pcuvty_flush_neigh_caches();
5239
5240 /* Establish BSSGP connection to the PCU */
5241 f_bssgp_establish();
5242 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5243
5244 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005245 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 +01005246 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5247 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5248
5249 /* Start NACC from MS side */
5250 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5251 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5252
5253 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005254 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005255 /* Make sure it is a Pkt Cell Chg Continue */
5256 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5257 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5258 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005259 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5260 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5261 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5262 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5263 }
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01005264
5265 f_shutdown(__BFILE__, __LINE__, final := true);
5266}
5267
5268/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005269testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
5270 var RlcmacDlBlock dl_block;
5271 var PollFnCtx pollctx;
5272 var uint32_t sched_fn;
5273 var GprsMS ms;
5274 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5275 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005276 var GsmArfcn req_arfcn := 862;
5277 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005278 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005279
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005280 if (use_old_ctrl_iface) {
5281 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5282 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5283 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005284
5285 /* Initialize NS/BSSGP side */
5286 f_init_bssgp();
5287 /* Initialize GPRS MS side */
5288 f_init_gprs_ms();
5289 ms := g_ms[0]; /* We only use first MS in this test */
5290
5291 /* Initialize the PCU interface abstraction */
5292 f_init_raw(testcasename(), info_ind);
5293
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005294 /* Make sure we are not affected by full cache from previous tests */
5295 f_pcuvty_flush_neigh_caches();
5296
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005297 /* Establish BSSGP connection to the PCU */
5298 f_bssgp_establish();
5299 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5300
5301 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005302 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 +01005303 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5304 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5305
5306 /* Start NACC from MS side */
5307 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5308 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5309
5310 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005311 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005312 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, false, use_old_ctrl_iface);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005313
5314 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005315 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005316 /* Make sure it is a Pkt Cell Chg Continue */
5317 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5318 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5319 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005320 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5321 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5322 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5323 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5324 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01005325
5326 f_shutdown(__BFILE__, __LINE__, final := true);
5327}
5328
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005329/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
5330testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
5331 var RlcmacDlBlock dl_block;
5332 var PollFnCtx pollctx;
5333 var uint32_t sched_fn;
5334 var GprsMS ms;
5335 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5336 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005337 var GsmArfcn req_arfcn := 862;
5338 var uint6_t req_bsic := 43;
5339
5340 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5341 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5342
5343 /* Initialize NS/BSSGP side */
5344 f_init_bssgp();
5345 /* Initialize GPRS MS side */
5346 f_init_gprs_ms();
5347 ms := g_ms[0]; /* We only use first MS in this test */
5348
5349 /* Initialize the PCU interface abstraction */
5350 f_init_raw(testcasename(), info_ind);
5351
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005352 /* Make sure we are not affected by full cache from previous tests */
5353 f_pcuvty_flush_neigh_caches();
5354
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005355 /* Establish BSSGP connection to the PCU */
5356 f_bssgp_establish();
5357 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5358
5359 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005360 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 +01005361 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5362 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5363
5364 /* Start NACC from MS side */
5365 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5366 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5367
5368 /* osmo-pcu should now ask for resolution: */
5369 f_ipa_ctrl_wait_link_up();
5370 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5371 int2str(info_ind.lac) & "." &
5372 int2str(info_ind.cell_id) & "." &
5373 int2str(req_arfcn) & "." &
5374 int2str(req_bsic);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005375 /* we receive RAC+CI resolution request and we send incorrectly formated response */
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005376 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
5377
5378 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005379 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005380 /* Make sure it is a Pkt Cell Chg Continue */
5381 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5382 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5383 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005384 /* 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 }
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01005389
5390 f_shutdown(__BFILE__, __LINE__, final := true);
5391}
5392
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005393/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
5394testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
5395 var RlcmacDlBlock dl_block;
5396 var PollFnCtx pollctx;
5397 var uint32_t sched_fn;
5398 var GprsMS ms;
5399 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5400 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005401 var GsmArfcn req_arfcn := 862;
5402 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005403 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005404 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 */
5405 info_ind.lac),
5406 info_ind.rac),
5407 info_ind.cell_id));
5408 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
5409 423),
5410 2),
5411 5));
5412 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
5413 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
5414
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005415 if (use_old_ctrl_iface) {
5416 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5417 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5418 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005419
5420 /* Initialize NS/BSSGP side */
5421 f_init_bssgp();
5422 /* Initialize GPRS MS side */
5423 f_init_gprs_ms();
5424 ms := g_ms[0]; /* We only use first MS in this test */
5425
5426 /* Initialize the PCU interface abstraction */
5427 f_init_raw(testcasename(), info_ind);
5428
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01005429 /* Make sure we are not affected by full cache from previous tests */
5430 f_pcuvty_flush_neigh_caches();
5431
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005432 /* Establish BSSGP connection to the PCU */
5433 f_bssgp_establish();
5434 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5435
5436 /* Send PACKET RESOURCE REQUEST */
Pau Espin Pedrol13ab5ea2021-02-05 11:56:15 +01005437 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 +01005438 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5439 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5440
5441 /* Start NACC from MS side */
5442 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5443 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5444
5445 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005446 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005447
5448 /* RIM procedure: */
5449 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
5450 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
5451 tr_RAN_Information_Request_RIM_Container));
5452 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
5453
5454 /* Wait until we receive something non-dummy */
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005455 dl_block := f_skip_dummy(0, sched_fn);
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005456 /* Make sure it is a Pkt Cell Chg Continue */
5457 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5458 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5459 }
Pau Espin Pedrola846e612021-02-01 19:25:25 +01005460 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5461 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5462 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5463 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5464 }
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01005465
5466 f_shutdown(__BFILE__, __LINE__, final := true);
5467}
5468
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005469/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for CTRL resolution */
5470testcase TC_nacc_outbound_pkt_cell_chg_notif_dup() runs on RAW_PCU_Test_CT {
5471 var PollFnCtx pollctx;
5472 var GprsMS ms;
5473 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5474 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5475 var RlcmacDlBlock dl_block;
5476 var uint32_t sched_fn;
5477 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005478 var charstring ctrl_var;
5479 var PCUIF_Message pcu_msg;
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005480 var GsmArfcn req_arfcn := 862;
5481 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005482 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005483
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005484 if (use_old_ctrl_iface) {
5485 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5486 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5487 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005488
5489 /* Initialize NS/BSSGP side */
5490 f_init_bssgp();
5491 /* Initialize GPRS MS side */
5492 f_init_gprs_ms();
5493 ms := g_ms[0]; /* We only use first MS in this test */
5494
5495 /* Initialize the PCU interface abstraction */
5496 f_init_raw(testcasename(), info_ind);
5497
5498 /* Make sure we are not affected by full cache from previous tests */
5499 f_pcuvty_flush_neigh_caches();
5500
5501 /* Establish BSSGP connection to the PCU */
5502 f_bssgp_establish();
5503 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5504
5505 /* Send PACKET RESOURCE REQUEST */
5506 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5507 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5508 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5509
5510 /* Start NACC from MS side */
5511 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5512 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5513
5514 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005515 if (use_old_ctrl_iface) {
5516 f_ipa_ctrl_wait_link_up();
5517 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 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5523 } else {
5524 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5525 }
5526
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005527 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif */
5528 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5529 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005530
5531 if (use_old_ctrl_iface) {
5532 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5533 } else {
5534 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5535 }
5536
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005537 timer T := 2.0;
5538 T.start;
5539 alt {
5540 [] as_outbound_nacc_rim_resolve(info_ind, do_repeat := true);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005541 [use_old_ctrl_iface] IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl {
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005542 setverdict(fail, "Received unexpected CTRL resolution after duplicate Pkt Cell Change Notification:", rx_ctrl);
5543 f_shutdown(__BFILE__, __LINE__);
5544 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005545 [not use_old_ctrl_iface] BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg {
5546 setverdict(fail, "Received unexpected PCUIF resolution after duplicate Pkt Cell Change Notification:", pcu_msg);
5547 f_shutdown(__BFILE__, __LINE__);
5548 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005549 [] T.timeout {
5550 setverdict(pass);
5551 }
5552 }
5553
5554 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005555 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005556
5557 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5558 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5559 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5560 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5561 f_shutdown(__BFILE__, __LINE__);
5562 }
5563 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5564 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5565 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5566 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5567 }
5568
5569 f_shutdown(__BFILE__, __LINE__, final := true);
5570}
5571
5572/* Test MS sending Pkt Cell Change Notify twice (duplicate msg) while waiting for SI resolution */
5573testcase TC_nacc_outbound_pkt_cell_chg_notif_dup2() runs on RAW_PCU_Test_CT {
5574 var PollFnCtx pollctx;
5575 var GprsMS ms;
5576 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5577 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5578 var RlcmacDlBlock dl_block;
5579 var uint32_t sched_fn;
5580 var CtrlMessage rx_ctrl;
5581 var GsmArfcn req_arfcn := 862;
5582 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005583 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005584
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005585 if (use_old_ctrl_iface) {
5586 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5587 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5588 }
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005589
5590 /* Initialize NS/BSSGP side */
5591 f_init_bssgp();
5592 /* Initialize GPRS MS side */
5593 f_init_gprs_ms();
5594 ms := g_ms[0]; /* We only use first MS in this test */
5595
5596 /* Initialize the PCU interface abstraction */
5597 f_init_raw(testcasename(), info_ind);
5598
5599 /* Make sure we are not affected by full cache from previous tests */
5600 f_pcuvty_flush_neigh_caches();
5601
5602 /* Establish BSSGP connection to the PCU */
5603 f_bssgp_establish();
5604 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5605
5606 /* Send PACKET RESOURCE REQUEST */
5607 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5608 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5609 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5610
5611 /* Start NACC from MS side */
5612 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5613 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5614
5615 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005616 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005617 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5618 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif */
5619 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5620 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5621 f_outbound_nacc_rim_tx_resp(info_ind);
5622 timer T := 1.0;
5623 T.start;
5624 alt {
5625 [] RIM.receive {
5626 setverdict(fail, "Received unexpected RIM message");
5627 f_shutdown(__BFILE__, __LINE__);
5628 }
5629 [] T.timeout {
5630 setverdict(pass);
5631 }
5632 }
5633
5634 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005635 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01005636
5637 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5638 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5639 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5640 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5641 f_shutdown(__BFILE__, __LINE__);
5642 }
5643 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5644 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5645 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5646 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5647 }
5648
5649 f_shutdown(__BFILE__, __LINE__, final := true);
5650}
5651
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005652/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Neigh Data Change */
5653testcase TC_nacc_outbound_pkt_cell_chg_notif_dup3() runs on RAW_PCU_Test_CT {
5654 var PollFnCtx pollctx;
5655 var GprsMS ms;
5656 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5657 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5658 var RlcmacDlBlock dl_block;
5659 var uint32_t sched_fn;
5660 var CtrlMessage rx_ctrl;
5661 var GsmArfcn req_arfcn := 862;
5662 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005663 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005664
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005665 if (use_old_ctrl_iface) {
5666 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5667 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5668 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005669
5670 /* Initialize NS/BSSGP side */
5671 f_init_bssgp();
5672 /* Initialize GPRS MS side */
5673 f_init_gprs_ms();
5674 ms := g_ms[0]; /* We only use first MS in this test */
5675
5676 /* Initialize the PCU interface abstraction */
5677 f_init_raw(testcasename(), info_ind);
5678
5679 /* Make sure we are not affected by full cache from previous tests */
5680 f_pcuvty_flush_neigh_caches();
5681
5682 /* Establish BSSGP connection to the PCU */
5683 f_bssgp_establish();
5684 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5685
5686 /* Send PACKET RESOURCE REQUEST */
5687 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5688 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5689 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5690
5691 /* Start NACC from MS side */
5692 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5693 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5694
5695 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005696 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005697 /* RIM procedure: */
5698 as_outbound_nacc_rim_resolve(info_ind);
5699
5700 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif: */
5701 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
5702 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5703
5704 /* It should be ignored, let's continue fetching Pkt Neigh Data Change */
5705 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
5706
5707 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5708 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5709 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5710 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5711 f_shutdown(__BFILE__, __LINE__);
5712 }
5713 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5714 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5715 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5716 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5717 }
5718}
5719
5720/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while sending Pkt Cell Change Continue */
5721testcase TC_nacc_outbound_pkt_cell_chg_notif_dup4() runs on RAW_PCU_Test_CT {
5722 var PollFnCtx pollctx;
5723 var GprsMS ms;
5724 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5725 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5726 var RlcmacDlBlock dl_block;
5727 var uint32_t sched_fn;
5728 var CtrlMessage rx_ctrl;
5729 var GsmArfcn req_arfcn := 862;
5730 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005731 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005732
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005733 if (use_old_ctrl_iface) {
5734 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5735 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5736 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005737
5738 /* Initialize NS/BSSGP side */
5739 f_init_bssgp();
5740 /* Initialize GPRS MS side */
5741 f_init_gprs_ms();
5742 ms := g_ms[0]; /* We only use first MS in this test */
5743
5744 /* Initialize the PCU interface abstraction */
5745 f_init_raw(testcasename(), info_ind);
5746
5747 /* Make sure we are not affected by full cache from previous tests */
5748 f_pcuvty_flush_neigh_caches();
5749
5750 /* Establish BSSGP connection to the PCU */
5751 f_bssgp_establish();
5752 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5753
5754 /* Send PACKET RESOURCE REQUEST */
5755 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5756 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5757 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5758
5759 /* Start NACC from MS side */
5760 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5761 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5762
5763 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005764 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005765 /* RIM procedure: */
5766 as_outbound_nacc_rim_resolve(info_ind);
5767
5768 /* Announce SI back to MS, continue NACC procedure */
5769 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5770
5771 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5772 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5773
5774 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5775 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5776 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5777 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5778 f_shutdown(__BFILE__, __LINE__);
5779 }
5780 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5781 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5782 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5783 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5784 }
5785}
5786
5787/* Test MS sending Pkt Cell Change Notification twice (duplicate msg) while waiting for Pkt Cell Change Continue CTRL ACK */
5788testcase TC_nacc_outbound_pkt_cell_chg_notif_dup5() runs on RAW_PCU_Test_CT {
5789 var PollFnCtx pollctx;
5790 var GprsMS ms;
5791 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5792 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5793 var RlcmacDlBlock dl_block;
5794 var uint32_t sched_fn;
5795 var CtrlMessage rx_ctrl;
5796 var GsmArfcn req_arfcn := 862;
5797 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005798 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005799
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005800 if (use_old_ctrl_iface) {
5801 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5802 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5803 }
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005804
5805 /* Initialize NS/BSSGP side */
5806 f_init_bssgp();
5807 /* Initialize GPRS MS side */
5808 f_init_gprs_ms();
5809 ms := g_ms[0]; /* We only use first MS in this test */
5810
5811 /* Initialize the PCU interface abstraction */
5812 f_init_raw(testcasename(), info_ind);
5813
5814 /* Make sure we are not affected by full cache from previous tests */
5815 f_pcuvty_flush_neigh_caches();
5816
5817 /* Establish BSSGP connection to the PCU */
5818 f_bssgp_establish();
5819 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5820
5821 /* Send PACKET RESOURCE REQUEST */
5822 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5823 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5824 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5825
5826 /* Start NACC from MS side */
5827 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5828 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5829
5830 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005831 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01005832 /* RIM procedure: */
5833 as_outbound_nacc_rim_resolve(info_ind);
5834
5835 /* Announce SI back to MS, continue NACC procedure */
5836 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
5837
5838 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5839 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5840 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5841 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5842 f_shutdown(__BFILE__, __LINE__);
5843 }
5844 /* trigger a dup Pkt Cell Change Notif, it should be ignored: */
5845 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5846
5847 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5848 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5849 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5850 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5851 }
5852}
5853
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005854/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5855 * while waiting for CTRL resolution */
5856testcase TC_nacc_outbound_pkt_cell_chg_notif_twice() runs on RAW_PCU_Test_CT {
5857 var PollFnCtx pollctx;
5858 var GprsMS ms;
5859 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5860 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5861 var RlcmacDlBlock dl_block;
5862 var uint32_t sched_fn;
5863 var CtrlMessage rx_ctrl;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005864 var charstring ctrl_var;
5865 var PCUIF_Message pcu_msg;
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005866 var GsmArfcn req_arfcn := 862;
5867 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005868 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005869
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005870 if (use_old_ctrl_iface) {
5871 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5872 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5873 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005874
5875 /* Initialize NS/BSSGP side */
5876 f_init_bssgp();
5877 /* Initialize GPRS MS side */
5878 f_init_gprs_ms();
5879 ms := g_ms[0]; /* We only use first MS in this test */
5880
5881 /* Initialize the PCU interface abstraction */
5882 f_init_raw(testcasename(), info_ind);
5883
5884 /* Make sure we are not affected by full cache from previous tests */
5885 f_pcuvty_flush_neigh_caches();
5886
5887 /* Establish BSSGP connection to the PCU */
5888 f_bssgp_establish();
5889 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5890
5891 /* Send PACKET RESOURCE REQUEST */
5892 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5893 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5894 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5895
5896 /* Start NACC from MS side */
5897 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5898 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5899
5900 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005901 if (use_old_ctrl_iface) {
5902 f_ipa_ctrl_wait_link_up();
5903 ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
5904 int2str(info_ind.lac) & "." &
5905 int2str(info_ind.cell_id) & "." &
5906 int2str(req_arfcn) & "." &
5907 int2str(req_bsic);
5908 IPA_CTRL.receive(tr_CtrlMsgGet(?, ctrl_var)) -> value rx_ctrl;
5909 } else {
5910 BTS.receive(tr_PCUIF_NEIGH_ADDR_REQ(0, info_ind.lac, info_ind.cell_id, req_arfcn, req_bsic)) -> value pcu_msg;
5911 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005912 /* Before receiving CTRL response, MS retransmits Pkt cell Chg Notif with different tgt arfcn */
5913 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5914 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5915 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005916 if (use_old_ctrl_iface) {
5917 IPA_CTRL.send(ts_CtrlMsgGetRepl(rx_ctrl.cmd.id, valueof(ctrl_var), valueof("023-43-423-2-5")));
5918 } else {
5919 BTS.send(ts_PCUIF_NEIGH_ADDR_CNF(0, pcu_msg.u.container.u.neigh_addr_req, 0, 23, 43, 0, 423, 2, 5));
5920 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005921 /* We should now receive a 2nd CTRL request with the new ARFCN+BSIC */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005922 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005923
5924 /* And finally everything continues as usual with RIN procedure */
5925 as_outbound_nacc_rim_resolve(info_ind);
5926
5927 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01005928 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005929
5930 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
5931 f_rx_rlcmac_dl_block(dl_block, sched_fn);
5932 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
5933 setverdict(fail, "Rx unexpected DL block: ", dl_block);
5934 f_shutdown(__BFILE__, __LINE__);
5935 }
5936 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
5937 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
5938 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
5939 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
5940 }
5941
5942 f_shutdown(__BFILE__, __LINE__, final := true);
5943}
5944
5945/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
5946 * while waiting for SI resolution */
5947testcase TC_nacc_outbound_pkt_cell_chg_notif_twice2() runs on RAW_PCU_Test_CT {
5948 var PollFnCtx pollctx;
5949 var GprsMS ms;
5950 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
5951 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
5952 var RlcmacDlBlock dl_block;
5953 var uint32_t sched_fn;
5954 var CtrlMessage rx_ctrl;
5955 var GsmArfcn req_arfcn := 862;
5956 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005957 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005958
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005959 if (use_old_ctrl_iface) {
5960 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
5961 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
5962 }
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005963
5964 /* Initialize NS/BSSGP side */
5965 f_init_bssgp();
5966 /* Initialize GPRS MS side */
5967 f_init_gprs_ms();
5968 ms := g_ms[0]; /* We only use first MS in this test */
5969
5970 /* Initialize the PCU interface abstraction */
5971 f_init_raw(testcasename(), info_ind);
5972
5973 /* Make sure we are not affected by full cache from previous tests */
5974 f_pcuvty_flush_neigh_caches();
5975
5976 /* Establish BSSGP connection to the PCU */
5977 f_bssgp_establish();
5978 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
5979
5980 /* Send PACKET RESOURCE REQUEST */
5981 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
5982 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
5983 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
5984
5985 /* Start NACC from MS side */
5986 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
5987 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5988
5989 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005990 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01005991 as_outbound_nacc_rim_resolve(info_ind, do_answer := false);
5992 /* Before receiving RIM response, MS retransmits Pkt cell Chg Notif with different tgt cell: */
5993 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
5994 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
5995 f_sleep(0.2); /* let some time to avoid race conditons between CTRL and RLCMAC */
5996 f_outbound_nacc_rim_tx_resp(info_ind);
5997
5998 /* As a result, CTRL + RIM resolution for new tgt cell should now be done: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02005999 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006000
6001 /* And finally everything continues as usual with RIN procedure */
6002 as_outbound_nacc_rim_resolve(info_ind);
6003
6004 /* Announce SI back to MS, continue NACC procedure */
Pau Espin Pedrol6cb71cc2021-02-11 13:54:01 +01006005 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006006
6007 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6008 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6009 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6010 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6011 f_shutdown(__BFILE__, __LINE__);
6012 }
6013 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6014 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6015 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6016 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6017 }
6018
6019 f_shutdown(__BFILE__, __LINE__, final := true);
6020}
6021
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006022/* Test MS sending Pkt Cell Change Notify twice (different tgt cell each time)
6023 * while sending Pkt Neigh Data Change */
6024testcase TC_nacc_outbound_pkt_cell_chg_notif_twice3() runs on RAW_PCU_Test_CT {
6025 var PollFnCtx pollctx;
6026 var GprsMS ms;
6027 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6028 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6029 var RlcmacDlBlock dl_block;
6030 var uint32_t sched_fn;
6031 var CtrlMessage rx_ctrl;
6032 var GsmArfcn req_arfcn := 862;
6033 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006034 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006035
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006036 if (use_old_ctrl_iface) {
6037 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6038 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6039 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006040
6041 /* Initialize NS/BSSGP side */
6042 f_init_bssgp();
6043 /* Initialize GPRS MS side */
6044 f_init_gprs_ms();
6045 ms := g_ms[0]; /* We only use first MS in this test */
6046
6047 /* Initialize the PCU interface abstraction */
6048 f_init_raw(testcasename(), info_ind);
6049
6050 /* Make sure we are not affected by full cache from previous tests */
6051 f_pcuvty_flush_neigh_caches();
6052
6053 /* Establish BSSGP connection to the PCU */
6054 f_bssgp_establish();
6055 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6056
6057 /* Send PACKET RESOURCE REQUEST */
6058 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6059 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6060 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6061
6062 /* Start NACC from MS side */
6063 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6064 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6065
6066 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006067 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006068 /* RIM procedure: */
6069 as_outbound_nacc_rim_resolve(info_ind);
6070
6071 /* Receive first Pkt Neigh data Change, then trigger a new Pkt Cell Change Notif (different ARFCN+BSIC): */
6072 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6073 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6074 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6075
6076 /* It should trigger RAC_CI resolution to start again: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006077 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006078 /* RIM procedure: */
6079 as_outbound_nacc_rim_resolve(info_ind);
6080 /* Transmit SI back to MS */
6081 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6082
6083 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6084 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6085 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6086 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6087 f_shutdown(__BFILE__, __LINE__);
6088 }
6089 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6090 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6091 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6092 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6093 }
6094}
6095
6096/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while sending Pkt Cell Change Continue */
6097testcase TC_nacc_outbound_pkt_cell_chg_notif_twice4() runs on RAW_PCU_Test_CT {
6098 var PollFnCtx pollctx;
6099 var GprsMS ms;
6100 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6101 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6102 var RlcmacDlBlock dl_block;
6103 var uint32_t sched_fn;
6104 var CtrlMessage rx_ctrl;
6105 var GsmArfcn req_arfcn := 862;
6106 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006107 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006108
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006109 if (use_old_ctrl_iface) {
6110 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6111 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6112 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006113
6114 /* Initialize NS/BSSGP side */
6115 f_init_bssgp();
6116 /* Initialize GPRS MS side */
6117 f_init_gprs_ms();
6118 ms := g_ms[0]; /* We only use first MS in this test */
6119
6120 /* Initialize the PCU interface abstraction */
6121 f_init_raw(testcasename(), info_ind);
6122
6123 /* Make sure we are not affected by full cache from previous tests */
6124 f_pcuvty_flush_neigh_caches();
6125
6126 /* Establish BSSGP connection to the PCU */
6127 f_bssgp_establish();
6128 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6129
6130 /* Send PACKET RESOURCE REQUEST */
6131 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6132 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6133 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6134
6135 /* Start NACC from MS side */
6136 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6137 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6138
6139 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006140 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006141 /* RIM procedure: */
6142 as_outbound_nacc_rim_resolve(info_ind);
6143
6144 /* Announce SI back to MS, continue NACC procedure */
6145 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6146
6147 /* trigger a Pkt Cell Change Notif with different tgt cell */
6148 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6149 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6150
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006151 /* It should trigger RAC_CI resolution to start again: */
6152 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6153
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006154 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6155 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := f_ms_tx_TsTrxBtsNum(ms));
6156
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006157 /* RIM procedure: */
6158 as_outbound_nacc_rim_resolve(info_ind);
6159 /* Transmit SI back to MS */
6160 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6161
6162 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6163 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6164 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6165 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6166 f_shutdown(__BFILE__, __LINE__);
6167 }
6168 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6169 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6170 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6171 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6172 }
6173}
6174
6175/* Test MS sending Pkt Cell Change Notification twice (different tgt cell) while waiting for Pkt Cell Change Continue CTRL ACK*/
6176testcase TC_nacc_outbound_pkt_cell_chg_notif_twice5() runs on RAW_PCU_Test_CT {
6177 var PollFnCtx pollctx;
6178 var GprsMS ms;
6179 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6180 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6181 var RlcmacDlBlock dl_block;
6182 var uint32_t sched_fn;
6183 var CtrlMessage rx_ctrl;
6184 var GsmArfcn req_arfcn := 862;
6185 var uint6_t req_bsic := 43;
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006186 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006187
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006188 if (use_old_ctrl_iface) {
6189 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6190 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6191 }
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006192
6193 /* Initialize NS/BSSGP side */
6194 f_init_bssgp();
6195 /* Initialize GPRS MS side */
6196 f_init_gprs_ms();
6197 ms := g_ms[0]; /* We only use first MS in this test */
6198
6199 /* Initialize the PCU interface abstraction */
6200 f_init_raw(testcasename(), info_ind);
6201
6202 /* Make sure we are not affected by full cache from previous tests */
6203 f_pcuvty_flush_neigh_caches();
6204
6205 /* Establish BSSGP connection to the PCU */
6206 f_bssgp_establish();
6207 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6208
6209 /* Send PACKET RESOURCE REQUEST */
6210 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6211 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6212 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6213
6214 /* Start NACC from MS side */
6215 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6216 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6217
6218 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006219 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006220 /* RIM procedure: */
6221 as_outbound_nacc_rim_resolve(info_ind);
6222
6223 /* Announce SI back to MS, continue NACC procedure */
6224 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6225
6226 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6227 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6228 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6229 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6230 f_shutdown(__BFILE__, __LINE__);
6231 }
6232
6233 /* trigger a Pkt Cell Change Notif with different tgt cell */
6234 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn + 1, req_bsic + 1);
6235 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6236
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006237 /* It should trigger RAC_CI resolution to start again: */
6238 /* When using new PCUIF interface for resolution, we must
6239 * PCUIF.receive() here since that's the first message in the PCUIF
6240 * queue that PCU will have sent. Calling other functions doing
6241 * PCUIF.receive() (like f_ms_tx_ul_block() below) will make them fail
6242 * due to unexpected message receive. */
6243 if (not use_old_ctrl_iface) {
6244 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6245 }
6246
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006247 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6248 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6249 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6250 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6251 }
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006252
6253 /* When using CTRL interface, we must schedule the ACK before (see
6254 * above) blocking here waiting for the resoltion, otherwise we'll be
6255 * too late scheduling by the time the resolution is done. */
6256 if (use_old_ctrl_iface) {
6257 f_handle_nacc_rac_ci_query(info_ind, req_arfcn + 1, req_bsic + 1, true, use_old_ctrl_iface);
6258 }
6259
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006260 /* PCU TBF NACC state changed, so we should next receive a dummy block: */
6261 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
6262
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006263 /* RIM procedure: */
6264 as_outbound_nacc_rim_resolve(info_ind);
6265 /* Transmit SI back to MS */
6266 f_ms_handle_pkt_neighbor_cell_data(ms, si_default);
6267
6268 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6269 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6270 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6271 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6272 f_shutdown(__BFILE__, __LINE__);
6273 }
6274 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6275 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6276 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6277 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6278 }
6279}
6280
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006281/* Test MS sending Pkt Cell Change Notification on an MS with an existing but unassigned (no TFI) DL TBF */
6282testcase TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() runs on RAW_PCU_Test_CT {
6283 var PollFnCtx pollctx;
6284 var GprsMS ms;
6285 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6286 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
6287 var RlcmacDlBlock dl_block;
6288 var uint32_t sched_fn, dl_fn;
6289 var CtrlMessage rx_ctrl;
6290 var GsmArfcn req_arfcn := 862;
6291 var uint6_t req_bsic := 43;
6292 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006293 var boolean use_old_ctrl_iface := mp_ctrl_neigh_ip != "";
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006294
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006295 if (use_old_ctrl_iface) {
6296 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
6297 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
6298 }
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006299
6300 /* Initialize NS/BSSGP side */
6301 f_init_bssgp();
6302 /* Initialize GPRS MS side */
6303 f_init_gprs_ms();
6304 ms := g_ms[0]; /* We only use first MS in this test */
6305
6306 /* Initialize the PCU interface abstraction */
6307 f_init_raw(testcasename(), info_ind);
6308
6309 /* Make sure we are not affected by full cache from previous tests */
6310 f_pcuvty_flush_neigh_caches();
6311
6312 /* Establish BSSGP connection to the PCU */
6313 f_bssgp_establish();
6314 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6315
6316 /* Send PACKET RESOURCE REQUEST */
6317 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap_gprs_def));
6318 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
6319 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
6320
6321 /* Start NACC from MS side */
6322 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
6323 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
6324
6325 /* osmo-pcu should now ask for resolution: */
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006326 f_handle_nacc_rac_ci_query(info_ind, req_arfcn, req_bsic, true, use_old_ctrl_iface);
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006327 /* RIM procedure: */
6328 as_outbound_nacc_rim_resolve(info_ind);
6329
6330 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
6331 /* Make sure we leave some time for SGSN->PCU data to arrive to PCU */
6332 f_sleep(0.1);
6333 /* rx DL assignment, don't ack it yet (keep TBF in state ASSIGN): */
6334 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
6335
6336 /* NACC: scheduler selects tx Pkt Cell Neighbor Data. Receive first one: */
6337 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, single_step := true);
6338 /* ACK DL assignment (we do it here on purpose to test tx Pkt Neigh Cell
6339 * Data with unassigned DL TBF in line above): */
6340 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6341 /* Continue receiving Pkt Cell Neighbor Data */
6342 f_ms_handle_pkt_neighbor_cell_data(ms, si_default, f_ms_tx_TsTrxBtsNum(ms), 1, 16);
6343
6344 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
6345 f_rx_rlcmac_dl_block(dl_block, sched_fn);
6346 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
6347 setverdict(fail, "Rx unexpected DL block: ", dl_block);
6348 f_shutdown(__BFILE__, __LINE__);
6349 }
6350 /* PKT CELL CHG CONTINUE ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
6351 if (dl_block.ctrl.mac_hdr.rrbp_valid) {
6352 sched_fn := f_rrbp_ack_fn(sched_fn, dl_block.ctrl.mac_hdr.rrbp);
6353 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
6354 }
6355
6356 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
6357 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
6358 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
6359 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
6360 f_dl_block_ack_fn(dl_block, dl_fn));
6361}
6362
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006363
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006364function f_do_inbound_nacc(template (value) RIM_Routing_Information tx_src_addr, template RIM_Routing_Information rx_dst_addr)
6365runs on RAW_PCU_Test_CT
6366{
6367 var template (value) RAN_Information_Request_RIM_Container req_cont;
6368 var template (value) PDU_BSSGP bssgp_rim_pdu;
6369 var template PDU_BSSGP bssgp_rim_pdu_expect;
6370 var template RAN_Information_RIM_Container rim_cont_expect;
6371 var RIM_Routing_Address bts_addr;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006372
6373 /* Send sysinfo to the PCU */
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006374 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 +01006375 BTS.send(si1_data_ind);
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006376 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 +01006377 BTS.send(si3_data_ind);
Pau Espin Pedrol02a6d0c2021-04-19 17:11:07 +02006378 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);
6379 BTS.send(si13_data_ind);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006380 f_sleep(1.0);
6381
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006382 bts_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006383
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006384 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6385 ts_RIM_Sequence_Number(1),
6386 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6387 ts_RIM_Protocol_Version_Number(1),
6388 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6389 omit);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006390 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
6391 tx_src_addr, req_cont);
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006392
6393 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6394 tr_RIM_Sequence_Number(1),
6395 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6396 tr_RIM_Protocol_Version_Number(1),
Pau Espin Pedrol0af478e2021-02-05 18:00:58 +01006397 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 +01006398 omit);
6399
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006400 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(rx_dst_addr,
6401 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, bts_addr),
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006402 rim_cont_expect);
6403 RIM.send(bssgp_rim_pdu);
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006404 timer T := 2.0;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006405 T.start;
6406 alt {
6407 [] RIM.receive(bssgp_rim_pdu_expect) { }
6408 [] RIM.receive {
6409 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6410 }
6411 [] T.timeout {
6412 setverdict(fail, "No BSSGP RIM PDU received");
6413 mtc.stop;
6414 }
6415 }
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006416}
6417/* Send a RIM RAN info request to the PCU and verify the response, we expect
6418 * getting the system information back which we have transfered to the PCU via
6419 * PCUIF on startup. */
6420testcase TC_rim_ran_info_req_single_rep() runs on RAW_PCU_Test_CT {
6421 /* Initialize NS/BSSGP side */
6422 f_init_bssgp();
6423
6424 /* Initialize the PCU interface abstraction */
6425 f_init_raw(testcasename());
6426
6427 /* Establish BSSGP connection to the PCU */
6428 f_bssgp_establish();
6429
6430 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6431 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6432
6433 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6434 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr));
6435
6436 f_shutdown(__BFILE__, __LINE__, final := true);
6437}
6438
6439/* Same as TC_rim_ran_info_req_single_rep, but using an EUTRAN eNodeB ID as
6440 * Routing information, to verify PCU handles that kind of address just fine
6441 */
6442testcase TC_rim_ran_info_req_single_rep_eutran() runs on RAW_PCU_Test_CT {
6443 /* Initialize NS/BSSGP side */
6444 f_init_bssgp();
6445
6446 /* Initialize the PCU interface abstraction */
6447 f_init_raw(testcasename());
6448
6449 /* Establish BSSGP connection to the PCU */
6450 f_bssgp_establish();
6451
6452 var BssgpCellId src_cid := {ra_id := { lai := { mcc_mnc := '262F42'H, lac := 12345}, rac := 0 }, cell_id := 20962 };
6453 var RIM_Routing_Address src_addr := valueof(t_RIM_Routing_Address_enbid(src_cid, tac := 3, gnbid := '12345678123456'O));
6454
6455 f_do_inbound_nacc(ts_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr),
6456 tr_RIM_Routing_Information(RIM_ADDR_EUTRAN_NODEB_ID, src_addr));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006457
6458 f_shutdown(__BFILE__, __LINE__, final := true);
6459}
6460
6461/* Same as above, but in this case we simulate the rare case in which the PCU
6462 * has no system information available. We expect getting a response back but
6463 * with no system information inside. */
6464testcase TC_rim_ran_info_req_single_rep_no_si() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006465 var template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006466 var PCUIF_Message pcu_msg;
6467 timer T := 2.0;
6468
6469 /* Initialize NS/BSSGP side */
6470 f_init_bssgp();
6471
6472 /* Initialize the PCU interface abstraction */
6473 f_init_raw(testcasename(), info_ind);
6474
6475 /* Establish BSSGP connection to the PCU */
6476 f_bssgp_establish();
6477
6478 /* Clear sysinfo from the PCU */
6479 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);
6480 BTS.send(si1_data_ind);
6481 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);
6482 BTS.send(si3_data_ind);
6483 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);
6484 BTS.send(si16_data_ind);
6485 f_sleep(1.0);
6486
Pau Espin Pedrolfa64e282021-02-05 17:56:52 +01006487 var RIM_Routing_Address dst_addr;
6488 var RIM_Routing_Address src_addr;
6489 var template (value) RAN_Information_Request_RIM_Container req_cont;
6490 var template (value) PDU_BSSGP bssgp_rim_pdu;
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006491 var template PDU_BSSGP bssgp_rim_pdu_expect;
6492 var template RAN_Information_RIM_Container rim_cont_expect;
6493
6494 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 +01006495 src_addr := valueof(t_RIM_Routing_Address_cid(src_cid));
6496 dst_addr := valueof(t_RIM_Routing_Address_cid(mp_gb_cfg.bvc[0].cell_id));
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006497
6498 req_cont := ts_RAN_Information_Request_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
6499 ts_RIM_Sequence_Number(1),
6500 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6501 ts_RIM_Protocol_Version_Number(1),
6502 tsu_RAN_Information_Request_Application_Container_NACC(mp_gb_cfg.bvc[0].cell_id),
6503 omit);
6504 bssgp_rim_pdu := ts_RAN_INFORMATION_REQUEST(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6505 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6506 req_cont);
6507
6508
6509 rim_cont_expect := tr_RAN_Information_RIM_Container(tr_RIM_Application_Identity(RIM_APP_ID_NACC),
6510 tr_RIM_Sequence_Number(1),
6511 tr_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
6512 tr_RIM_Protocol_Version_Number(1),
6513 tru_ApplContainer_or_ApplErrContainer_NACC(tru_ApplContainer_NACC(mp_gb_cfg.bvc[0].cell_id, false, 0, ''O)),
6514 omit);
6515
6516 bssgp_rim_pdu_expect := tr_PDU_BSSGP_RAN_INFORMATION(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
6517 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
6518 rim_cont_expect);
6519 RIM.send(bssgp_rim_pdu);
6520 T.start;
6521 alt {
6522 [] RIM.receive(bssgp_rim_pdu_expect) { }
6523 [] RIM.receive {
6524 setverdict(fail, "Unexpected BSSGP RIM PDU received");
6525 }
6526 [] T.timeout {
6527 setverdict(fail, "No BSSGP RIM PDU received");
6528 mtc.stop;
6529 }
6530 }
6531
6532 f_shutdown(__BFILE__, __LINE__, final := true);
6533}
6534
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006535/* Verify PCU schedule idle blocks (len=0) if no TBF attached to it. See OS#4772, SYS#4919 */
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006536testcase TC_pdch_energy_saving() runs on RAW_PCU_Test_CT {
6537 var PCUIF_info_ind info_ind;
6538 var template (value) TsTrxBtsNum nr;
6539 var RlcmacDlBlock dl_block;
6540 var BTS_PDTCH_Block data_msg;
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006541 var integer ts;
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006542 timer T;
6543
6544 /* Initialize NS/BSSGP side */
6545 f_init_bssgp();
6546
6547 info_ind := valueof(ts_PCUIF_INFO_default);
6548 /* The 2 first TRX are enabled. */
6549 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (2 .. 7));
6550 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6551 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 1);
6552
6553 /* Initialize the PCU interface abstraction */
6554 f_init_raw(testcasename(), info_ind);
6555
6556 /* Establish BSSGP connection to the PCU */
6557 f_bssgp_establish();
6558
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006559 for (ts := 0; ts < 2; ts := ts + 1) {
6560 nr := ts_TsTrxBtsNum(ts_nr := 7, trx_nr := ts, bts_nr := 0, blk_nr := 0);
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006561
Pau Espin Pedrol332aba82021-09-22 14:50:35 +02006562 BTS.send(ts_PCUIF_RTS_REQ(nr.bts_nr, nr.trx_nr, nr.ts_nr,
6563 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
6564 arfcn := f_trxnr2arfcn(valueof(nr.trx_nr)), block_nr := nr.blk_nr));
6565 T.start(0.5);
6566 alt {
6567 [] BTS.receive(tr_PCUIF_DATA_PDTCH(nr.bts_nr,
6568 tr_PCUIF_DATA(nr.trx_nr, nr.ts_nr, sapi := PCU_IF_SAPI_PDTCH),
6569 omit)) -> value data_msg {
6570 setverdict(pass);
6571 T.stop;
6572 }
6573 [] as_rx_fail_dummy(nr);
6574 [] BTS.receive {
6575 setverdict(fail, "Unexpected block from BTS");
6576 f_shutdown(__BFILE__, __LINE__);
6577 }
6578 [] T.timeout {
6579 setverdict(fail, "Expected IDLE block from BTS");
6580 f_shutdown(__BFILE__, __LINE__);
6581 }
6582 }
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006583 }
6584
6585 f_shutdown(__BFILE__, __LINE__, final := true);
6586}
6587
Oliver Smith3d174882021-09-03 11:38:51 +02006588/* Test stats for available and occupied PDCHs */
6589testcase TC_stat_pdch_avail_occ() runs on RAW_PCU_Test_CT {
6590 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6591 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6592
6593 /* Initialize NS/BSSGP side */
6594 f_init_bssgp();
6595
Oliver Smithedcded22021-09-14 09:26:55 +02006596 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6597 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6598 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6599 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6600 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6601 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
Oliver Smith3d174882021-09-03 11:38:51 +02006602
Oliver Smith72d0c692021-09-08 10:03:52 +02006603 /* Allocate 4 GprsMS instances */
Oliver Smith3d174882021-09-03 11:38:51 +02006604 f_init_gprs_ms(4);
6605
6606 /* Initialize the PCU interface abstraction */
6607 f_init_raw(testcasename(), info_ind);
6608
6609 /* Reset stats */
6610 f_statsd_reset();
6611
6612 /* Establish BSSGP */
6613 f_bssgp_establish();
6614
6615 /* 8 PDCHs available, 0 occupied */
6616 var StatsDExpects expect := {
6617 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006618 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6619 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6620 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
Oliver Smith3d174882021-09-03 11:38:51 +02006621 };
6622 f_statsd_expect(expect);
6623
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006624 /* Establish an Uplink TBF for each GprsMS instance (3x GPRS, 1x EGPRS) */
Oliver Smith3d174882021-09-03 11:38:51 +02006625 f_multi_ms_bssgp_register();
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006626 f_ms_establish_ul_tbf(g_ms[0]);
6627 f_ms_establish_ul_tbf(g_ms[1]);
6628 f_ms_establish_ul_tbf(g_ms[2]);
6629 f_ms_establish_ul_tbf_2phase_access(g_ms[3], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[3].tlli, ms_racap_egprs_def));
Oliver Smith3d174882021-09-03 11:38:51 +02006630
6631 /* 4 PDCHs occupied */
6632 expect := {
6633 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
Oliver Smith4b2a89f2021-09-08 11:24:39 +02006634 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 4, max := 4 },
6635 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 3, max := 3 },
6636 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
Oliver Smith3d174882021-09-03 11:38:51 +02006637 };
6638 f_statsd_expect(expect);
6639
6640 f_shutdown(__BFILE__, __LINE__, final := true);
6641}
6642
Oliver Smithf04762d2021-09-14 17:20:38 +02006643/* Test stats for available and occupied PDCHs, for MS which is not known by
6644 * the PCU (e.g. because it was forgotten due to no interaction, and old DL
6645 * data arrives from SGSN) */
6646function f_tc_stat_pdch_avail_occ_ms_not_known(boolean egprs) runs on RAW_PCU_Test_CT {
6647 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
6648 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
6649
6650 /* Ensure a deterministic slot allocation of 1 PDCH with MS class 1 */
6651 const MultislotCap_GPRS_BSSGP bssgp_mscap_gprs := {
6652 gprsmultislotclass := '00001'B,
6653 gprsextendeddynalloccap := '0'B
6654 };
6655 const MultislotCap_EGPRS_BSSGP bssgp_mscap_egprs := {
6656 egprsmultislotclass := '00001'B,
6657 egprsextendeddynalloccap := '0'B
6658 };
6659 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_gprs := {
6660 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, omit)) };
6661 template (value) MSRadioAccessCapabilityV_BSSGP bssgp_ms_racap_egprs := {
6662 valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, bssgp_mscap_gprs, bssgp_mscap_egprs)) };
6663
6664 /* Initialize NS/BSSGP side */
6665 f_init_bssgp();
6666
6667 /* Only the 4 first TRX are enabled, each with 2 PDCHs. */
6668 f_PCUIF_PDCHMask_set(info_ind, '00000011'B, 0);
6669 f_PCUIF_PDCHMask_set(info_ind, '00001100'B, 1);
6670 f_PCUIF_PDCHMask_set(info_ind, '11000000'B, 2);
6671 f_PCUIF_PDCHMask_set(info_ind, '00110000'B, 3);
6672 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (4 .. 7));
6673
6674 /* Allocate 1 GprsMS instance */
6675 f_init_gprs_ms(1);
6676
6677 /* Initialize the PCU interface abstraction */
6678 f_init_raw(testcasename(), info_ind);
6679
6680 /* Reset stats */
6681 f_statsd_reset();
6682
6683 /* Establish BSSGP */
6684 f_bssgp_establish();
6685
6686 /* 8 PDCHs available, 0 occupied */
6687 var StatsDExpects expect := {
6688 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6689 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 0, max := 0 },
6690 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6691 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6692 };
6693 f_statsd_expect(expect);
6694
6695 var GprsMS ms := g_ms[0]; /* We only use first MS in this test */
6696 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
6697
6698 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
6699 var octetstring data := f_rnd_octstring(1400);
6700 if (egprs) {
6701 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_egprs));
6702 } else {
6703 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, bssgp_ms_racap_gprs));
6704 }
6705 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
6706
6707 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
6708 f_sleep(X2002);
6709
6710 /* 1 PDCH occupied */
6711 if (egprs) {
6712 expect := {
6713 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6714 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6715 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 0, max := 0 },
6716 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 1, max := 1 }
6717 };
6718 } else {
6719 expect := {
6720 { name := "TTCN3.bts.0.pdch.available", mtype := "g", min := 8, max := 8 },
6721 { name := "TTCN3.bts.0.pdch.occupied", mtype := "g", min := 1, max := 1 },
6722 { name := "TTCN3.bts.0.pdch.occupied.gprs", mtype := "g", min := 1, max := 1 },
6723 { name := "TTCN3.bts.0.pdch.occupied.egprs", mtype := "g", min := 0, max := 0 }
6724 };
6725 }
6726 f_statsd_expect(expect);
6727
6728 /* Clean up */
6729 f_shutdown(__BFILE__, __LINE__, final := true);
6730}
6731testcase TC_stat_pdch_avail_occ_ms_not_known_gprs() runs on RAW_PCU_Test_CT {
6732 f_tc_stat_pdch_avail_occ_ms_not_known(false);
6733}
6734testcase TC_stat_pdch_avail_occ_ms_not_known_egprs() runs on RAW_PCU_Test_CT {
6735 f_tc_stat_pdch_avail_occ_ms_not_known(true);
6736}
6737
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006738/* Make sure that bts.0.pdch.all_allocated is set when we allocate all resources */
6739testcase TC_ratectr_all_available_allocated() runs on RAW_PCU_Test_CT {
6740 var PCUIF_info_ind info_ind;
6741 var template IARRestOctets rest;
6742 var BIT11 ra11;
6743
6744 info_ind := valueof(ts_PCUIF_INFO_default);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006745
6746 /* Only the first TRX is enabled. */
6747 f_PCUIF_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
6748 f_PCUIF_PDCHMask_set(info_ind, '00000001'B, 0);
6749
6750 /* Initialize the PCU interface abstraction */
6751 f_init_raw(testcasename(), info_ind);
6752 f_statsd_reset();
6753
6754 var EGPRSPktChRequest req := {
6755 one_phase := {
6756 tag := '0'B,
6757 multislot_class := '10101'B,
6758 priority := '01'B,
6759 random_bits := '101'B
6760 }
6761 };
6762
6763 /* We send 7 requests, the IUT gives us all available USFs (0..6) */
6764 for (var integer i := 0; i < 7; i := i + 1) {
6765 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
6766 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
6767 }
6768
6769 ra11 := enc_EGPRSPktChRequest2bits(req);
6770 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
6771
6772 /* At this point, the IUT should run out of free USFs */
Pau Espin Pedrol209dc7d2021-11-15 16:25:08 +01006773 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006774
6775 /* bts.0.pdch.all_allocated is updated once per second, wait some time to make sure it was updated. */
6776 f_sleep(2.0);
6777 var StatsDExpects expect := {
6778 { name := "TTCN3.bts.0.pdch.all_allocated", mtype := "c", min := 1, max := 1 }
6779 };
6780 f_statsd_expect(expect);
6781
6782 f_shutdown(__BFILE__, __LINE__, final := true);
6783}
6784
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006785control {
6786 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01006787 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006788 execute( TC_ta_ptcch_idle() );
6789 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy866f8702021-05-26 14:50:27 +02006790 execute( TC_ta_ul_ack_nack_first_block() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006791 execute( TC_ta_idle_dl_tbf_ass() );
6792 execute( TC_ta_ptcch_ul_multi_tbf() );
6793 execute( TC_cs_lqual_ul_tbf() );
6794 execute( TC_cs_initial_ul() );
6795 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01006796 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01006797 execute( TC_cs_max_dl() );
6798 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01006799 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01006800 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01006801 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01006802 execute( TC_mcs_max_dl() );
Pau Espin Pedrol1451f9f2021-05-11 11:52:37 +02006803 execute( TC_t3141() );
Pau Espin Pedrolf30fa1d2021-03-03 19:55:11 +01006804 execute( TC_n3101_max_t3169() );
Pau Espin Pedrolcc895df2021-04-20 12:58:32 +02006805 execute( TC_n3103_max_t3169() );
Pau Espin Pedrol84a8c3c2021-03-01 17:22:29 +01006806 execute( TC_x2031_t3191() );
6807 execute( TC_zero_x2031_t3191() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006808 execute( TC_t3193() );
Pau Espin Pedrol14ca7e32021-03-01 17:41:21 +01006809 execute( TC_n3105_max_t3195() );
Pau Espin Pedrole8a94442021-11-15 17:05:46 +01006810 execute( TC_t3172_wait_ind_size0() );
6811 execute( TC_t3172_wait_ind_size1() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02006812 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02006813 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02006814 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006815 execute( TC_mo_ping_pong() );
6816 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02006817 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006818 execute( TC_mt_ping_pong() );
6819 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006820 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006821 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07006822 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02006823 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol90fdfed2021-03-02 17:29:32 +01006824 execute( TC_dl_no_ack_retrans_imm_ass() );
Pau Espin Pedrol6844c162022-04-01 15:40:06 +02006825 execute( TC_dl_llc_sapi_priority() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006826 execute( TC_paging_cs_from_bts() );
6827 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
6828 execute( TC_paging_cs_from_sgsn_sign() );
6829 execute( TC_paging_cs_from_sgsn_ptp() );
6830 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
6831 execute( TC_paging_ps_from_sgsn_sign() );
6832 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrol1538c3b2021-11-16 19:19:07 +01006833 execute( TC_paging_pch_timeout() );
6834
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07006835 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
6836 execute( TC_paging_cs_multi_ms_imsi() );
6837 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02006838 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
6839 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01006840 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
6841 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006842
6843 /* EGPRS specific test cases */
6844 execute( TC_egprs_pkt_chan_req_signalling() );
6845 execute( TC_egprs_pkt_chan_req_one_phase() );
6846 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07006847 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07006848 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07006849 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02006850
6851 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07006852
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006853 /* Immediate Assignment on AGCH/PCH */
6854 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
6855 execute( TC_pcuif_fh_imm_ass_ul() );
6856 execute( TC_pcuif_fh_imm_ass_dl() );
6857 /* Packet Uplink/Downlink Assignment on PACCH */
6858 execute( TC_pcuif_fh_pkt_ass_ul() );
6859 execute( TC_pcuif_fh_pkt_ass_dl() );
6860 execute( TC_multitrx_multims_alloc() );
6861 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
6862 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
6863 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrol37604572021-10-15 14:36:16 +02006864 execute( TC_ul_tbf_reestablish_with_pkt_resource_req() );
Pau Espin Pedrold658f342021-10-15 14:52:22 +02006865 execute( TC_ul_tbf_reestablish_with_pkt_resource_req_n3105_max() );
Pau Espin Pedrol59aa1092021-11-15 18:53:34 +01006866 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack() );
6867 execute( TC_ul_tbf_reestablish_with_pkt_dl_ack_nack_egprs() );
Vadim Yanitskiy1da1fef2021-03-23 04:28:18 +01006868
Pau Espin Pedrole1303052020-11-16 11:13:51 +01006869 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07006870
6871 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01006872 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol2abbba92021-02-02 11:52:57 +01006873 execute( TC_nacc_outbound_success_no_ctrl_ack() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01006874 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrol85366682021-01-27 19:04:54 +01006875 execute( TC_nacc_outbound_success_twice_nocache() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01006876 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01006877 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol6a715482021-02-10 18:40:46 +01006878 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup() );
6879 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup2() );
Pau Espin Pedrol0d6ebb72021-02-11 14:53:24 +01006880 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup3() );
6881 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup4() );
6882 execute( TC_nacc_outbound_pkt_cell_chg_notif_dup5() );
Pau Espin Pedrold4ed3602021-02-11 12:37:22 +01006883 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice() );
6884 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice2() );
Pau Espin Pedrol179ddef2021-02-11 16:03:46 +01006885 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice3() );
6886 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice4() );
6887 execute( TC_nacc_outbound_pkt_cell_chg_notif_twice5() );
Pau Espin Pedrol13035772021-02-18 16:07:06 +01006888 execute( TC_nacc_outbound_pkt_cell_chg_notif_unassigned_dl_tbf() );
Pau Espin Pedrolf28fd082021-09-07 20:02:25 +02006889 if (mp_ctrl_neigh_ip != "") { /* PCU using old CTRL neigh addr resolution iface */
6890 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
6891 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
6892 }
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006893
6894 execute( TC_rim_ran_info_req_single_rep() );
Pau Espin Pedrol436e2bd2021-05-06 20:07:08 +02006895 execute( TC_rim_ran_info_req_single_rep_eutran() );
Philipp Maierd55fe7e2021-02-01 17:23:40 +01006896 execute( TC_rim_ran_info_req_single_rep_no_si() );
Pau Espin Pedrol3aa61c62021-08-25 19:24:03 +02006897
6898 execute (TC_pdch_energy_saving() );
Oliver Smith3d174882021-09-03 11:38:51 +02006899
6900 execute( TC_stat_pdch_avail_occ() );
Oliver Smithf04762d2021-09-14 17:20:38 +02006901 execute( TC_stat_pdch_avail_occ_ms_not_known_gprs() );
6902 execute( TC_stat_pdch_avail_occ_ms_not_known_egprs() );
Pau Espin Pedrol6eb4d252021-11-15 11:53:40 +01006903 execute( TC_ratectr_all_available_allocated() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02006904}
6905
Harald Weltea419df22019-03-21 17:23:04 +01006906}