blob: 6a789757b3024454bd840ba9bf21ff0db2e63266 [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;
60import from Osmocom_CTRL_Adapter all;
61import from Osmocom_CTRL_Functions all;
62
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020063modulepar {
64 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
65
66 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Daniel Willmann535aea62020-09-21 13:27:08 +020067
68 charstring mp_pcu_statsd_ip := "127.0.0.1";
69 integer mp_pcu_statsd_port := 8125;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +010070
71 charstring mp_ctrl_neigh_ip := "127.0.0.1";
72 integer mp_ctrl_neigh_port := 4248;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020073}
74
75
76/* 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 +010077friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default(template (value) PCUIF_Flags flags := c_PCUIF_Flags_default)
78:= {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070079 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +010080 flags := flags,
Pau Espin Pedrol2aead382020-10-29 20:46:47 +010081 trx := f_PCUIF_ver_INFO_Trxs(GPRS_Components.mp_base_arfcn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020082 bsic := 7,
83 mcc := 262,
84 mnc := 42,
85 mnc_3_digits := 0,
86 lac := 13135,
87 rac := 0,
88 nsei := mp_nsconfig.nsei,
89 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
90 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
91 cell_id := 20960,
92 repeat_time := 5 * 50,
93 repeat_count := 3,
Harald Welte5339b2e2020-10-04 22:52:56 +020094 bvci := mp_gb_cfg.bvc[0].bvci,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020095 t3142 := 20,
96 t3169 := 5,
97 t3191 := 5,
98 t3193_10ms := 160,
99 t3195 := 5,
100 t3101 := 10,
101 t3103 := 4,
102 t3105 := 8,
103 cv_countdown := 15,
104 dl_tbf_ext := 250 * 10, /* ms */
105 ul_tbf_ext := 250 * 10, /* ms */
106 initial_cs := 2,
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +0100107 initial_mcs := 1,
Harald Welte90f19742020-11-06 19:34:40 +0100108 nsvci := { mp_nsconfig.nsvc[0].nsvci, 0 },
109 local_port := { mp_nsconfig.nsvc[0].provider.ip.remote_udp_port, 0 },
110 remote_port := { mp_nsconfig.nsvc[0].provider.ip.local_udp_port, 0 },
Alexander Couzens1e5dc482020-07-28 15:38:46 +0200111 remote_addr := f_PCUIF_ver_INFO_RemoteAddr(
Harald Welte90f19742020-11-06 19:34:40 +0100112 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 +0200113}
114
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100115/* Passed in RAN-INFO message from emulated neighbor using RIM */
116const octetstring si1_default := '198fb100000000000000000000000000007900002b'O;
117const octetstring si3_default := '1b753000f110236ec9033c2747407900003c0b2b2b'O;
118const octetstring si13_default := '009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b'O;
119const octetstring si_default := si1_default & si3_default & si13_default;
120
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200121type record lqual_range {
122 /* component reference to the IPA_Client component used for RSL */
123 uint8_t low,
124 uint8_t high
125}
126
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +0100127type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT, StatsD_ConnHdlr, CTRL_Adapter_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700128 /* PCU interface abstraction component */
129 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700130
Daniel Willmann535aea62020-09-21 13:27:08 +0200131 /* StatsD */
132 var StatsD_Checker_CT vc_STATSD;
133
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200134 /* Connection to the PCUIF component */
135 port RAW_PCU_MSG_PT PCUIF;
136 /* VTY connection to the PCU */
137 port TELNETasp_PT PCUVTY;
138
139 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
140 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
141 {low := 5, high := 8},
142 {low := 7, high := 13},
143 {low := 12,high := 35}};
144 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
145 {low := 5, high := 8},
146 {low := 7, high := 13},
147 {low := 12,high := 15},
148 {low := 14, high := 17},
149 {low := 16, high := 18},
150 {low := 17,high := 20},
151 {low := 19, high := 24},
152 {low := 23,high := 35}};
153 var uint8_t g_cs_initial_dl := 1;
154 var uint8_t g_cs_initial_ul := 1;
155 var uint8_t g_mcs_initial_dl := 1;
156 var uint8_t g_mcs_initial_ul := 1;
157 var uint8_t g_cs_max_dl := 4;
158 var uint8_t g_cs_max_ul := 4;
159 var uint8_t g_mcs_max_dl := 9;
160 var uint8_t g_mcs_max_ul := 9;
161
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200162 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200163
164 /* Guard timeout */
165 timer g_T_guard := 60.0;
166};
167
168private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
169 [] g_T_guard.timeout {
170 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700171 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200172 }
173}
174
175private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
176 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
177 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
178
179 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
180 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
181}
182
183private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
184 var charstring cmd;
185
186 cmd := "cs link-quality-ranges" &
187 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
188 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
189 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
190 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
191 f_vty_config2(PCUVTY, {"pcu"}, cmd);
192
193 cmd := "mcs link-quality-ranges" &
194 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
195 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
196 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
197 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
198 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
199 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
200 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
201 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
202 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
203 f_vty_config2(PCUVTY, {"pcu"}, cmd);
204}
205
Pau Espin Pedrol43be4252021-01-27 16:40:54 +0100206private function f_pcuvty_flush_neigh_caches() runs on RAW_PCU_Test_CT {
207 f_pcuvty_set_neigh_caches(0, 0);
208}
209
210private function f_pcuvty_set_neigh_caches(integer neigh_cache_secs := -1, integer si_cache_secs := -1)
211runs on RAW_PCU_Test_CT {
212 if (neigh_cache_secs == -1) {
213 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 default");
214 } else {
215 f_vty_config2(PCUVTY, {"pcu"}, "timer X10 " & int2str(neigh_cache_secs));
216 }
217 if (si_cache_secs == -1) {
218 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 default");
219 } else {
220 f_vty_config2(PCUVTY, {"pcu"}, "timer X11 " & int2str(si_cache_secs));
221 }
222}
223
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100224private function f_init_vty(charstring id, boolean egprs_only) runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200225 map(self:PCUVTY, system:PCUVTY);
226 f_vty_set_prompts(PCUVTY);
227 f_vty_transceive(PCUVTY, "enable");
228
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100229 /* This will be removed soon, not needed. EGPRS support is controlled through pcu_ind flags */
230 if (egprs_only) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200231 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
232 } else {
233 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
234 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200235
236 if (g_force_two_phase_access) {
237 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
238 } else {
239 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
240 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200241}
242
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200243function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200244runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200245 /* Start the guard timer */
246 g_T_guard.start;
247 activate(as_Tguard_RAW());
248
249 /* Init PCU interface component */
Harald Welte5339b2e2020-10-04 22:52:56 +0200250 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200251 connect(vc_PCUIF:MTC, self:PCUIF);
252 map(vc_PCUIF:PCU, system:PCU);
253
254 /* Create one BTS component (we may want more some day) */
Harald Welte5339b2e2020-10-04 22:52:56 +0200255 vc_BTS := RAW_PCU_BTS_CT.create("BTS");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200256 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
257 connect(vc_BTS:TC, self:BTS);
258
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100259 f_init_vty(id, f_pcuif_ind_flags_egprs_enabled(valueof(info_ind.flags)));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200260
Daniel Willmann535aea62020-09-21 13:27:08 +0200261 f_init_statsd(id, vc_STATSD, mp_pcu_statsd_ip, mp_pcu_statsd_port);
262 /* This is normally done in the ConnHdlr component, but here
263 * the Test_CT doubles as ConnHdlr */
264 connect(self:STATSD_PROC, vc_STATSD:STATSD_PROC);
265
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200266 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
267 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
268
269 /* Wait until the BTS is ready (SI13 negotiated) */
270 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
271}
272
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +0700273/* Register TLLI of each allocated GprsMS instance */
274private function f_multi_ms_bssgp_register()
275runs on RAW_PCU_Test_CT {
276 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
277 f_bssgp_client_llgmm_assign(TLLI_UNUSED, g_ms[i].tlli);
278 }
279}
280
281/* Allocate [and activate] an Uplink TBF for each allocated GprsMS instance */
282private function f_multi_ms_establish_tbf(boolean do_activate := false)
283runs on RAW_PCU_Test_CT {
284 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
285 /* Establish an Uplink TBF */
286 f_ms_establish_ul_tbf(g_ms[i]);
287
288 /* Send a random block, so this TBF becomes "active" */
289 if (do_activate) {
290 /* FIXME: use the new APU by Pau to get correct TRX/TS here */
291 var template TsTrxBtsNum nr := ts_TsTrxBtsNum(7, i mod 8);
292 var octetstring dummy := f_rnd_octstring(12);
293 var RlcmacDlBlock dl_block;
294 var uint32_t poll_fn;
295
296 f_ms_tx_ul_data_block(g_ms[i], dummy, with_tlli := true, nr := nr);
297 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := nr);
298 }
299 }
300}
301
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +0100302private function f_ms_establish_ul_tbf_2phase_access(inout GprsMS ms,
303 template (omit) RlcmacUlCtrlMsg pkt_res_req := omit)
304runs on RAW_PCU_Test_CT return PollFnCtx {
305 var PollFnCtx pollctx;
306
307 /* Single block (two phase) packet access */
308 var uint16_t ra := bit2int(chan_req_sb);
309 if (g_force_two_phase_access) {
310 /* If 2phase access is enforced by the network, then let's
311 * request a One phase packet access, we'll receive a single block
312 * anyway
313 */
314 ra := bit2int(chan_req_def);
315 }
316
317 /* Establish an Uplink TBF */
318 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
319 f_ms_establish_ul_tbf(ms);
320
321 /* Make sure we've got an Uplink TBF assignment */
322 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
323 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
324 f_shutdown(__BFILE__, __LINE__);
325 }
326
327 /* Send PACKET RESOURCE REQUEST
328 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
329 */
330 if (istemplatekind(pkt_res_req, "omit")) {
331 pkt_res_req := ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit);
332 }
333
334 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(pkt_res_req), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
335 /* Store 1st UlTBF context before receiving next one, will will
336 * overwrite the TS allocation on MS with info from new UL TBF:
337 */
338 pollctx.tstrxbts := f_ms_tx_TsTrxBtsNum(ms);
339 f_ms_rx_pkt_ass_pacch(ms, pollctx.fn, tr_RLCMAC_UL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
340 return pollctx;
341}
342
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200343testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +0200344 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
Pau Espin Pedrol2889f872021-01-11 14:43:35 +0100345 var GprsTlli tlli := TLLI_UNUSED;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200346 timer T;
347
348 /* Initialize NS/BSSGP side */
349 f_init_bssgp();
350
351 /* Initialize the PCU interface abstraction */
352 f_init_raw(testcasename());
353
354 /* Establish BSSGP connection to the PCU */
355 f_bssgp_establish();
356
357 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
358
359 T.start(2.0);
360 alt {
Harald Welte9b461a92020-12-10 23:41:14 +0100361 [] 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 +0200362 setverdict(pass);
363 }
364 [] T.timeout {
365 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
366 }
367 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700368
369 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200370}
371
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +0100372/* Make sure TBF is released and no data is sent for in after reciving a Suspend Request from that MS. See OS#4761 */
373testcase TC_pcuif_suspend_active_tbf() runs on RAW_PCU_Test_CT {
374 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.bvc[0].cell_id.ra_id);
375 var RlcmacDlBlock dl_block;
376 var octetstring data := f_rnd_octstring(10);
377 var uint32_t sched_fn;
378 var uint32_t dl_fn;
379 var GprsMS ms;
380 timer T;
381
382 /* Initialize NS/BSSGP side */
383 f_init_bssgp();
384 /* Initialize GPRS MS side */
385 f_init_gprs_ms();
386 ms := g_ms[0]; /* We only use first MS in this test */
387
388 /* Initialize the PCU interface abstraction */
389 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
390
391 /* Establish BSSGP connection to the PCU */
392 f_bssgp_establish();
393 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
394
395 /* Establish an Uplink TBF */
396 f_ms_establish_ul_tbf(ms);
397
398 /* Send one UL block (with TLLI since we are in One-Phase Access
399 contention resoultion) and make sure it is ACKED fine */
400 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
401 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
402 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
403 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
404
405 /* UL block should be received in SGSN */
406 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
407
408 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
409 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
410 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
411
412 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
413 f_sleep(X2002);
414 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
415
416 /* MS has moved to CS, it sent SUSP REQ to BTS and PCU gets it, TBF is freed: */
417 BTS.send(ts_PCUIF_SUSP_REQ(0, ms.tlli, ra_id, 0));
418
419 T.start(2.0);
420 alt {
421 [] BSSGP_GLOBAL[0].receive(tr_BSSGP_SUSPEND(ms.tlli, mp_gb_cfg.bvc[0].cell_id.ra_id)) {
422 setverdict(pass);
423 }
424 [] T.timeout {
425 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
426 f_shutdown(__BFILE__, __LINE__);
427 }
428 }
429
430 /* Make sure we don't receive data for that TBF since it was released
431 * before. Also check our TBF is not polled for UL. */
432 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
433 if (dl_block.ctrl.mac_hdr.usf != USF_UNUSED) {
434 setverdict(fail, "Unexpected USF ", dl_block.ctrl.mac_hdr.usf);
435 f_shutdown(__BFILE__, __LINE__);
436 }
437
438 /* New data arrives, PCU should page the MS since no TBF active exists: */
439 /* Send some more data, it will never reach the MS */
440 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
441 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
442
443 f_shutdown(__BFILE__, __LINE__, final := true);
444}
445
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200446/* Test of correct Timing Advance at the time of TBF establishment
447 * (derived from timing offset of the Access Burst). */
448testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200449 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200450
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200451 /* Initialize GPRS MS side */
452 f_init_gprs_ms();
453 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200454 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100455 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200456
457 /* We cannot send too many TBF requests in a short time because
458 * at some point the PCU will fail to allocate a new TBF. */
459 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
460 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200461 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700462 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200463
464 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200465 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700466 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200467 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700468 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700469 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200470 }
471 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700472
473 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200474}
475
476/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
477 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
478 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
479 * no active TBF exists at the moment of establishment (idle mode). */
480testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700481 var OCT4 tlli := f_rnd_octstring(4);
482 var GsmRrMessage rr_imm_ass;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200483
484 /* Initialize NS/BSSGP side */
485 f_init_bssgp();
486
487 /* Initialize the PCU interface abstraction */
488 f_init_raw(testcasename());
489
490 /* Establish BSSGP connection to the PCU */
491 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +0100492 f_bssgp_client_llgmm_assign(TLLI_UNUSED, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200493
494 /* SGSN sends some DL data, PCU will initiate Packet Downlink
495 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700496 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
497 rr_imm_ass := f_pcuif_rx_imm_ass(PCU_IF_SAPI_PCH, tr_IMM_TBF_ASS(dl := true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200498
499 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
500 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
501 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700502 if (rr_imm_ass.payload.imm_ass.timing_advance != 0) {
503 setverdict(fail, "Timing Advance value doesn't match");
504 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700505
506 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200507}
508
509/* Verify that the PCU generates valid PTCCH/D messages
510 * while neither Uplink nor Downlink TBF is established. */
511testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
512 var PTCCHDownlinkMsg ptcch_msg;
513 var PCUIF_Message pcu_msg;
514 timer T;
515
516 /* Initialize the PCU interface abstraction */
517 f_init_raw(testcasename());
518
519 /* Sent an RTS.req for PTCCH/D */
520 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
521 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
522 arfcn := 871, block_nr := 0));
523 T.start(5.0);
524 alt {
525 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
526 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
527 log("Rx DATA.req message: ", pcu_msg);
528 setverdict(pass);
529 }
530 [] BTS.receive(PCUIF_Message:?) { repeat; }
531 [] T.timeout {
532 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700533 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200534 }
535 }
536
537 ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
538 log("Decoded PTCCH/D message: ", ptcch_msg);
539
540 /* Make sure the message is encoded correctly
541 * TODO: do we expect all TA values to be equal '1111111'B? */
542 if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
543 setverdict(fail, "Malformed PTCCH/D message");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200544 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700545
546 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200547}
548
549/* Test of correct Timing Advance during an active Uplink TBF.
550 *
551 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
552 * are not continuous and there can be long time gaps between them. This happens
553 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
554 * significantly change between such rare Uplink transmissions, so GPRS introduces
555 * additional mechanisms to control Timing Advance, and thus reduce interference
556 * between neighboring TDMA time-slots.
557 *
558 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
559 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
560 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
561 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
562 * among with the initial Timing Advance value. And here PTCCH comes to play.
563 *
564 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
565 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
566 * continuously. To ensure continuous measurements of the signal propagation
567 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
568 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
569 *
570 * The purpose of this test case is to verify the assignment of Timing Advance
571 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
572 * first establishes several Uplink TBFs, but does not transmit any Uplink
573 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
574 * indications to the PCU, checking the correctness of two received PTCCH/D
575 * messages (period of PTCCH/D is two multi-frames).
576 */
577
578/* List of ToA values for Access Bursts to be sent on PTCCH/U,
579 * each ToA (Timing of Arrival) value is in units of 1/4 of
580 * a symbol (i.e. 1 symbol is 4 QTA units). */
581type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
582const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
583 0, 0, 0, 0,
584 0, 0, 0, 0,
585 0, 0, 0, 0,
586 0, 0, 0, 0
587};
588
589private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
590 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
591runs on RAW_PCU_Test_CT {
592 var RAW_PCU_Event event;
593 var integer ss;
594
595 /* Send Access Bursts on PTCCH/U for every TA Index */
596 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
597 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700598 if (ss < 0) { /* Shall not happen */
599 f_shutdown(__BFILE__, __LINE__);
600 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200601
602 log("Sending an Access Burst on PTCCH/U",
603 ", sub-slot=", ss, " (TAI)",
604 ", fn=", event.data.tdma_fn,
605 ", ToA=", toa_map[ss], " (QTA)");
606 /* TODO: do we care about RA and burst format? */
607 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
608 ra := oct2int('3A'O),
609 is_11bit := 0,
610 burst_type := BURST_TYPE_0,
611 fn := event.data.tdma_fn,
612 arfcn := 871,
613 qta := toa_map[ss],
614 sapi := PCU_IF_SAPI_PTCCH));
615 repeat;
616 }
617}
618
619private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
620 template PTCCHDownlinkMsg t_ta_msg)
621runs on RAW_PCU_Test_CT {
622 var PTCCHDownlinkMsg ta_msg;
623 var PCUIF_Message pcu_msg;
624 timer T;
625
626 /* First, send an RTS.req for the upcoming PTCCH/D block */
627 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
628 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
629 arfcn := 871, block_nr := 0));
630 T.start(2.0);
631 alt {
632 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
633 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
634 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
635 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
636 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
637 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
638 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
639 log("Rx PTCCH/D message: ", ta_msg);
640
641 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700642 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200643 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
644 }
645 }
646 [] BTS.receive { repeat; }
647 [] T.timeout {
648 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200649 }
650 }
651}
652
653testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
654 var template PacketUlAssign t_ul_tbf_ass;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200655 var GprsMS ms;
656
657 /* Initialize GPRS MS side */
658 f_init_gprs_ms();
659 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200660
661 /* Initialize the PCU interface abstraction */
662 f_init_raw(testcasename());
663
664 /* Enable forwarding of PTCCH/U TDMA events to us */
665 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
666
667 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
668 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200669 /* Establish an Uplink TBF */
670 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200671
672 /* We expect incremental TFI/USF assignment (dynamic allocation) */
673 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200674 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200675 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700676 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200677 }
678
679 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200680 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200681 setverdict(fail, "Failed to match Timing Advance Index for #", i);
682 /* Keep going, the current OsmoPCU does not assign TA Index */
683 }
684 }
685
686 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
687 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
688 for (var integer i := 0; i < 7; i := i + 1) {
689 /* ToA in units of 1/4 of a symbol */
690 toa_map[i] := (i + 1) * 7 * 4;
691 }
692
693 /* Now we have all 7 TBFs established in one-phase access mode,
694 * however we will not be sending any data on them. Instead, we
695 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
696 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
697 *
698 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
699 * time-slots, so at the moment of scheduling a PTCCH/D block
700 * the PCU has odd number of PTCCH/U Access Bursts received. */
701 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
702 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
703 /* Other values are not known (yet) */
704 tai3_ta := ?));
705 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
706 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
707 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
708 /* Other values are out of our interest */
709 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700710
711 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200712}
713
714/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
715 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
716 *
717 * NOTE: the ranges are intentionally overlapping because OsmoPCU
718 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
719private template integer CS1_lqual_dB_range := (-infinity .. 6);
720private template integer CS2_lqual_dB_range := (5 .. 8);
721private template integer CS3_lqual_dB_range := (7 .. 13);
722private template integer CS4_lqual_dB_range := (12 .. infinity);
723
724testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200725 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200726 var GprsMS ms;
727 var uint32_t unused_fn, sched_fn;
728 var uint4_t cv;
729
730 /* Initialize GPRS MS side */
731 f_init_gprs_ms();
732 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200733
734 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100735 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200736
737 f_pcuvty_set_allowed_cs_mcs();
738 f_pcuvty_set_link_quality_ranges();
739
740 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200741 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200742
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200743
744 /* The actual / old link quality values. We need to keep track of the old
745 * (basically previous) link quality value, because OsmoPCU actually
746 * changes the coding scheme if not only the actual, but also the old
747 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200748 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200749 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200750
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200751 /* Send one UL block (with TLLI since we are in One-Phase Access
752 contention resoultion) and make sure it is ACKED fine. */
753 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
754 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
755 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
756 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
757 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
758 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200759
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200760 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
761 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200762 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200763 lqual_old := ms.lqual_cb;
764 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200765
766 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200767 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
768 if (i > g_bs_cv_max) {
769 cv := 15;
770 } else {
771 cv := i;
772 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200773
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200774 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
775
776 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
777 f_rx_rlcmac_dl_block(dl_block, unused_fn);
778 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
779 continue;
780 }
781 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
782 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
783 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
784 f_shutdown(__BFILE__, __LINE__);
785 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200786
787 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
788 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
789
790 /* Match the received Channel Coding Command. Since we are increasing
791 * the link quality value on each iteration and not decreasing, there
792 * is no need to check the both old and current link quality values. */
793 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200794 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200795 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
796 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
797 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
798 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
799 }
800
801 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
802 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200803 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200804 }
805 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700806
807 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200808}
809
810/* Test the max UL CS set by VTY works fine */
811testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200812 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200813 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200814 var uint32_t unused_fn, sched_fn;
815 var GprsMS ms;
816
817 /* Initialize GPRS MS side */
818 f_init_gprs_ms();
819 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200820
821 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100822 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200823
824 /* Set initial UL CS to 3 */
825 g_cs_initial_ul := 3;
826 f_pcuvty_set_allowed_cs_mcs();
827 f_pcuvty_set_link_quality_ranges();
828
829 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200830 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200831
832 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200833 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200834
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200835 /* Send one UL block (with TLLI since we are in One-Phase Access
836 contention resoultion) and make sure it is ACKED fine. */
837 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
838 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
839 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
840 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
841 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
842 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200843
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200844 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
845 while (true) {
846 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
847 f_rx_rlcmac_dl_block(dl_block, unused_fn);
848 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
849 continue;
850 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200851
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200852 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
853 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
854 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
855 f_shutdown(__BFILE__, __LINE__);
856 break;
857 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200858
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200859 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200860 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200861 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200862 if (last_ch_coding != CH_CODING_CS3) {
863 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200864 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200865 }
866
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200867 /* Remaining UL blocks are used to make sure regardless of initial
868 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200869 /* 0 dB, make sure we downgrade CS */
870 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200871 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200872 f_ms_tx_ul_data_block_multi(ms, 5);
873 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
874 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
875 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200876
877 if (last_ch_coding != CH_CODING_CS1) {
878 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200879 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200880 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700881
882 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200883}
884
885/* Test the max UL CS set by VTY works fine */
886testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200887 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200888 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200889 var uint32_t unused_fn, sched_fn;
890 var GprsMS ms;
891
892 /* Initialize GPRS MS side */
893 f_init_gprs_ms();
894 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200895
896 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +0100897 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200898
899 /* Set maximum allowed UL CS to 3 */
900 g_cs_max_ul := 3;
901 f_pcuvty_set_allowed_cs_mcs();
902 f_pcuvty_set_link_quality_ranges();
903
904 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200905 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200906
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200907 /* Send one UL block (with TLLI since we are in One-Phase Access
908 contention resoultion) and make sure it is ACKED fine. */
909 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
910 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
911 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
912 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
913 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
914 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200915
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200916 ms.lqual_cb := 40*10; /* 40 dB */
917 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200918
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200919 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
920 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200921
922 if (last_ch_coding != CH_CODING_CS3) {
923 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200924 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200925 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700926
927 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200928}
929
Pau Espin Pedrol75122592020-11-03 15:22:59 +0100930/* Test the initial DL CS set by VTY works fine */
931testcase TC_cs_initial_dl() runs on RAW_PCU_Test_CT {
932 var octetstring data := f_rnd_octstring(10);
933 var CodingScheme exp_dl_cs_mcs;
934 var RlcmacDlBlock dl_block;
935 var uint32_t poll_fn;
936 var GprsMS ms;
937
938 /* Initialize NS/BSSGP side */
939 f_init_bssgp();
940 /* Initialize GPRS MS side */
941 f_init_gprs_ms();
942 ms := g_ms[0]; /* We only use first MS in this test */
943
944 /* Initialize the PCU interface abstraction */
945 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
946
947 /* Set initial allowed DL CS to 3 */
948 g_cs_initial_dl := 3;
949 exp_dl_cs_mcs := CS_3;
950 /* Set maximum allowed UL CS to 4 */
951 g_cs_max_dl := 4;
952 f_pcuvty_set_allowed_cs_mcs();
953 f_pcuvty_set_link_quality_ranges();
954
955 /* Establish BSSGP connection to the PCU */
956 f_bssgp_establish();
957 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
958
959 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
960 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
961 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
962
963 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
964 f_sleep(X2002);
965 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
966
967 /* ACK the DL block */
968 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
969 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
970 f_dl_block_ack_fn(dl_block, poll_fn));
971
972 f_shutdown(__BFILE__, __LINE__, final := true);
973}
974
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +0100975/* Verify scheduling of multiple Downlink data blocks, enough to reach CS4 */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +0100976function f_dl_data_exp_cs(template CodingScheme exp_final_cs := ?, template MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
977 var octetstring data := f_rnd_octstring(1400);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +0100978 var RlcmacDlBlock prev_dl_block, dl_block;
979 var uint32_t ack_fn;
980 var uint32_t fn;
981 var GprsMS ms;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +0100982 var integer tx_data_remain := 10;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +0100983 var integer bsn := 0;
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +0100984 var boolean using_egprs := f_rlcmac_cs_mcs_is_mcs(valueof(exp_final_cs));
985 var integer bsn_mod;
986 var template CodingScheme exp_tmp_csmcs;
987
988 if (using_egprs) {
989 exp_tmp_csmcs := mcs_egprs_any;
990 bsn_mod := 2048;
991 } else {
992 exp_tmp_csmcs := cs_gprs_any;
993 bsn_mod := 128;
994 }
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +0100995
996 /* Establish BSSGP connection to the PCU */
997 f_bssgp_establish();
998
999 ms := g_ms[0]; /* We only use first MS in this test */
1000 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1001
1002 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001003 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001004 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1005
1006 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1007 f_sleep(X2002);
1008
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001009 for (var integer i := 0; i < 800; i := i + 1) {
1010 bsn := i mod bsn_mod;
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001011 f_rx_rlcmac_dl_block(dl_block, fn);
1012
1013 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
1014 /* No more data to receive, done */
1015 break;
1016 }
1017
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001018 f_rlcmac_dl_block_exp_data(dl_block, ?, bsn, exp_tmp_csmcs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001019
1020 /* Keep Ack/Nack description updated */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001021 f_dltbf_ack_block(ms.dl_tbf, dl_block);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001022
1023 /* TDMA frame number on which we are supposed to send the ACK */
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001024 if (f_dl_block_rrbp_valid(dl_block)) {
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001025 ack_fn := f_dl_block_ack_fn(dl_block, fn);
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001026 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 +01001027 if (tx_data_remain != 0) {
1028 /* Submit more data from time to time to keep the TBF ongoing */
1029 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1030 tx_data_remain := tx_data_remain - 1;
1031 }
1032 }
1033 prev_dl_block := dl_block;
1034 }
1035
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001036 bsn := (bsn + (bsn_mod-1)) mod bsn_mod; /* previous bsn: bsn -1 */
1037 f_rlcmac_dl_block_exp_data(prev_dl_block, ?, bsn, exp_final_cs);
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01001038
1039
1040 f_shutdown(__BFILE__, __LINE__, final := true);
1041}
1042
1043/* Verify DL CS above "cs max" set by VTY is never used */
1044testcase TC_cs_max_dl() runs on RAW_PCU_Test_CT {
1045 /* Initialize NS/BSSGP side */
1046 f_init_bssgp();
1047 /* Initialize GPRS MS side */
1048 f_init_gprs_ms();
1049
1050 /* Initialize the PCU interface abstraction */
1051 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1052
1053 /* Set maximum allowed DL CS to 3 */
1054 g_cs_initial_dl := 1;
1055 g_cs_max_dl := 3;
1056 f_pcuvty_set_allowed_cs_mcs();
1057 f_pcuvty_set_link_quality_ranges();
1058
1059 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1060}
1061
1062/* Check DL CS4 is used in good link conditions if allowed by config */
1063testcase TC_dl_cs1_to_cs4() runs on RAW_PCU_Test_CT {
1064 /* Initialize NS/BSSGP side */
1065 f_init_bssgp();
1066 /* Initialize GPRS MS side */
1067 f_init_gprs_ms();
1068
1069 /* Initialize the PCU interface abstraction */
1070 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
1071
1072 /* Set initial DL CS to 1 & maximum allowed DL CS to 4 */
1073 g_cs_initial_dl := 1;
1074 g_cs_max_dl := 4;
1075 f_pcuvty_set_allowed_cs_mcs();
1076 f_pcuvty_set_link_quality_ranges();
1077
1078 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_cs_max_dl, false));
1079}
1080
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01001081/* Test the initial UL MCS set by VTY works fine */
1082testcase TC_mcs_initial_ul() runs on RAW_PCU_Test_CT {
1083 var RlcmacDlBlock dl_block;
1084 var PollFnCtx pollctx;
1085 var EgprsChCodingCommand last_ch_coding;
1086 var uint32_t unused_fn, sched_fn;
1087 var GprsMS ms;
1088 var CodingScheme exp_ul_mcs;
1089 var MultislotCap_GPRS mscap_gprs := {
1090 gprsmultislotclass := '00011'B,
1091 gprsextendeddynalloccap := '0'B
1092 };
1093 var MultislotCap_EGPRS mscap_egprs := {
1094 egprsmultislotclass := '00011'B,
1095 egprsextendeddynalloccap := '0'B
1096 };
1097 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1098
1099 /* Initialize GPRS MS side */
1100 f_init_gprs_ms();
1101 ms := g_ms[0]; /* We only use first MS in this test */
1102
1103 /* Initialize the PCU interface abstraction */
1104 f_init_raw(testcasename());
1105
1106 /* Set initial UL MCS to 3 */
1107 g_mcs_initial_ul := 3;
1108 exp_ul_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1109 f_pcuvty_set_allowed_cs_mcs();
1110 f_pcuvty_set_link_quality_ranges();
1111
1112 /* Take lqual (dB->cB) so that we stay in that MCS */
1113 ms.lqual_cb := g_mcs_lqual_ranges[2].low * 10;
1114
1115 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
1116 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
1117
1118 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_mcs)) {
1119 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_mcs);
1120 f_shutdown(__BFILE__, __LINE__);
1121 }
1122
1123 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1124 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1125
1126 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
1127 while (true) {
1128 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
1129 f_rx_rlcmac_dl_block(dl_block, unused_fn);
1130 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1131 continue;
1132 }
1133
1134 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1135 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1136 f_shutdown(__BFILE__, __LINE__);
1137 break;
1138 }
1139
1140 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1141 break;
1142 }
1143 if (f_rlcmac_block_EgprsChCodingCommand2cs_mcs(last_ch_coding) != exp_ul_mcs) {
1144 setverdict(fail, "Channel Coding does not match our expectations ", exp_ul_mcs, ": ", last_ch_coding);
1145 f_shutdown(__BFILE__, __LINE__);
1146 }
1147
1148 /* Remaining UL blocks are used to make sure regardless of initial
1149 * lqual, we can go lower at any time
1150 * 0 dB, make sure we downgrade MCS */
1151 ms.lqual_cb := 0;
1152 /* 5 UL blocks, check we are in same initial MCS: */
1153 f_ms_tx_ul_data_block_multi(ms, 5);
1154 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1155 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1156 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1157
1158 if (last_ch_coding != CH_CODING_MCS1) {
1159 setverdict(fail, "Channel Coding does not match our expectations (MCS-1): ", last_ch_coding);
1160 f_shutdown(__BFILE__, __LINE__);
1161 }
1162
1163 f_shutdown(__BFILE__, __LINE__, final := true);
1164}
1165
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01001166/* Test the maximum UL MCS set by VTY works fine */
1167testcase TC_mcs_max_ul() runs on RAW_PCU_Test_CT {
1168 var RlcmacDlBlock dl_block;
1169 var EgprsChCodingCommand last_ch_coding;
1170 var PollFnCtx pollctx;
1171 var uint32_t unused_fn, sched_fn;
1172 var GprsMS ms;
1173 var MultislotCap_GPRS mscap_gprs := {
1174 gprsmultislotclass := '00011'B,
1175 gprsextendeddynalloccap := '0'B
1176 };
1177 var MultislotCap_EGPRS mscap_egprs := {
1178 egprsmultislotclass := '00011'B,
1179 egprsextendeddynalloccap := '0'B
1180 };
1181 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1182
1183
1184 /* Initialize GPRS MS side */
1185 f_init_gprs_ms();
1186 ms := g_ms[0]; /* We only use first MS in this test */
1187
1188 /* Initialize the PCU interface abstraction */
1189 f_init_raw(testcasename());
1190
1191 /* Set maximum allowed UL MCS to 5 */
1192 g_mcs_max_ul := 5;
1193 f_pcuvty_set_allowed_cs_mcs();
1194 f_pcuvty_set_link_quality_ranges();
1195
1196 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
1197 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
1198 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
1199 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
1200
1201 ms.lqual_cb := 40*10; /* 40 dB */
1202 f_ms_tx_ul_data_block_multi(ms, 16);
1203
1204 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1205 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.egprs.ch_coding_cmd;
1206
1207 if (last_ch_coding != CH_CODING_MCS5) {
1208 setverdict(fail, "Channel Coding does not match our expectations (MCS-5): ", last_ch_coding);
1209 f_shutdown(__BFILE__, __LINE__);
1210 }
1211
1212 f_shutdown(__BFILE__, __LINE__, final := true);
1213}
1214
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01001215/* Test the initial DL CS set by VTY works fine */
1216testcase TC_mcs_initial_dl() runs on RAW_PCU_Test_CT {
1217 var octetstring data := f_rnd_octstring(10);
1218 var CodingScheme exp_dl_cs_mcs;
1219 var RlcmacDlBlock dl_block;
1220 var uint32_t poll_fn;
1221 var GprsMS ms;
1222 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1223 gprsmultislotclass := '00011'B,
1224 gprsextendeddynalloccap := '0'B
1225 };
1226 var MultislotCap_EGPRS_BSSGP mscap_egprs := {
1227 egprsmultislotclass := '00011'B,
1228 egprsextendeddynalloccap := '0'B
1229 };
1230 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1231
1232 /* Initialize NS/BSSGP side */
1233 f_init_bssgp();
1234 /* Initialize GPRS MS side */
1235 f_init_gprs_ms();
1236 ms := g_ms[0]; /* We only use first MS in this test */
1237
1238 /* Initialize the PCU interface abstraction */
1239 f_init_raw(testcasename());
1240
1241 /* Set initial allowed DL MCS to 3 */
1242 g_mcs_initial_dl := 3;
1243 exp_dl_cs_mcs := MCS_3;
1244 /* Set maximum allowed DL MCS to 4 */
1245 g_mcs_max_dl := 4;
1246 f_pcuvty_set_allowed_cs_mcs();
1247 f_pcuvty_set_link_quality_ranges();
1248
1249 /* Establish BSSGP connection to the PCU */
1250 f_bssgp_establish();
1251 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
1252
1253 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1254 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
1255 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1256
1257 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1258 f_sleep(X2002);
1259 f_rx_rlcmac_dl_block_exp_data(dl_block, poll_fn, data, 0, exp_dl_cs_mcs);
1260
1261 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001262 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1263 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 +01001264 f_dl_block_ack_fn(dl_block, poll_fn));
1265
1266 f_shutdown(__BFILE__, __LINE__, final := true);
1267}
1268
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01001269/* Verify DL MCS above "mcs max" set by VTY is never used */
1270testcase TC_mcs_max_dl() runs on RAW_PCU_Test_CT {
1271 /* Initialize NS/BSSGP side */
1272 f_init_bssgp();
1273 /* Initialize GPRS MS side */
1274 f_init_gprs_ms();
1275
1276 /* Initialize the PCU interface abstraction */
1277 f_init_raw(testcasename());
1278
1279 /* Set maximum allowed DL CS to 3 */
1280 g_mcs_initial_dl := 1;
1281 g_mcs_max_dl := 3;
1282 f_pcuvty_set_allowed_cs_mcs();
1283 f_pcuvty_set_link_quality_ranges();
1284
1285 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1286 gprsmultislotclass := '00011'B,
1287 gprsextendeddynalloccap := '0'B
1288 };
1289 var MultislotCap_EGPRS_BSSGP mscap_egprs := {
1290 egprsmultislotclass := '00011'B,
1291 egprsextendeddynalloccap := '0'B
1292 };
1293 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1294
1295 f_dl_data_exp_cs(f_rlcmac_block_int2cs_mcs(g_mcs_max_dl, true), ms_racap);
1296}
1297
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001298/* Verify PCU drops TBF after some time of inactivity. */
1299testcase TC_t3169() runs on RAW_PCU_Test_CT {
1300 var PCUIF_info_ind info_ind;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001301 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001302 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001303 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001304
1305 /* Initialize NS/BSSGP side */
1306 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001307 /* Initialize GPRS MS side */
1308 f_init_gprs_ms();
1309 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001310
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001311 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001312 /* Set timer to 1 sec (default 5) to speedup test: */
1313 info_ind.t3169 := 1;
1314
1315 /* Initialize the PCU interface abstraction */
1316 f_init_raw(testcasename(), info_ind);
1317
1318 /* Establish BSSGP connection to the PCU */
1319 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001320 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001321
1322 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001323 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001324
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001325 /* Send one UL block (with TLLI since we are in One-Phase Access
1326 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001327 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 1, with_tlli := true)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001328 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001329 /* UL block should NOT be received in SGSN, since we didn't get CV=0 */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001330
1331 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
1332 f_sleep(int2float(info_ind.t3169) + 1.0);
1333
1334 /* Send an UL block once again, the TBF should be gone by now so no ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001335 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 0)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001336 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001337
1338 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001339}
1340
1341/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1342 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1343 * T3193) after DL TBF release */
1344testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001345 var RlcmacDlBlock dl_block;
1346 var octetstring data := f_rnd_octstring(10);
1347 var boolean ok;
1348 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001349 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001350 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001351 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1352
1353 /* Initialize NS/BSSGP side */
1354 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001355 /* Initialize GPRS MS side */
1356 f_init_gprs_ms();
1357 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001358
1359 /* Initialize the PCU interface abstraction */
1360 f_init_raw(testcasename());
1361
1362 /* Establish BSSGP connection to the PCU */
1363 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001364 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001365
1366 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001367 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1368 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001369
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001370 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1371 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001372 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001373
1374 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001375 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1376 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1377 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001378
1379 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001380 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001381 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001382 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001383 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001384
1385 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001386
1387 /* 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 +07001388 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001389 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1390 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1391 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001392
1393 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001394}
1395
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001396/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
1397testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001398 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001399 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001400 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001401 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001402
1403 /* Initialize NS/BSSGP side */
1404 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001405 /* Initialize GPRS MS side */
1406 f_init_gprs_ms();
1407 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001408
1409 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001410 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001411
1412 /* Establish BSSGP connection to the PCU */
1413 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001414 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001415
1416 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001417 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001418
1419 /* Send one UL block (with TLLI since we are in One-Phase Access
1420 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001421 total_payload := f_rnd_octstring(f_ultbf_payload_fill_length(ms.ul_tbf, true));
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001422 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
1423 f_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true)
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001424 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1425 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001426 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001427
1428 /* Send enough blocks to test whole procedure: Until Nth block
1429 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
1430 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001431 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001432 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1433 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001434 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001435
1436 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02001437 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 +07001438
1439 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001440}
1441
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001442/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
1443testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
1444 var RlcmacDlBlock dl_block;
1445 var uint32_t dl_fn, sched_fn;
1446 var octetstring payload;
1447 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001448 var template (value) LlcBlockHdr blk_hdr;
1449 var template (value) LlcBlocks blocks;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001450 var integer blk_len;
1451 var CodingScheme tx_cs;
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001452 var GprsMS ms;
1453
1454 /* Initialize NS/BSSGP side */
1455 f_init_bssgp();
1456 /* Initialize GPRS MS side */
1457 f_init_gprs_ms();
1458 ms := g_ms[0]; /* We only use first MS in this test */
1459
1460 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001461 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001462
1463 /* Establish BSSGP connection to the PCU */
1464 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001465 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001466
1467 /* Establish an Uplink TBF */
1468 f_ms_establish_ul_tbf(ms);
1469
1470 /* Send one UL block (with TLLI since we are in One-Phase Access
1471 contention resoultion) and make sure it is ACKED fine. */
1472 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001473 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
1474 more := false, e := true);
1475 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001476 /* 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 +01001477 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := ms.ul_tbf.tx_cs_mcs,
1478 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001479 cv := 15,
1480 bsn := ms.ul_tbf.bsn,
1481 blocks := blocks,
1482 tlli := ms.tlli);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001483 f_ultbf_inc_bsn(ms.ul_tbf);
1484 f_ms_tx_ul_block(ms, ul_data);
1485
1486 /* ACK and check it was received fine */
1487 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1488 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1489 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1490 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02001491 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 +02001492
1493 /* Test sending LLC PDUS of incrementing size */
1494 var integer max_size := 49;
1495 for (var integer i := 1; i <= max_size; i := i + 1) {
1496 var integer cv;
1497 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1498 log("Sending DATA.ind with LLC payload size ", i);
1499 if (i < max_size - g_bs_cv_max) {
1500 cv := 15;
1501 } else {
1502 cv := max_size - i;
1503 }
1504
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001505 blk_len := 3 + 1 + i; /* 3 Header bytes + LI byte + payload length */
1506 tx_cs := f_rlcmac_block_len_required_cs_mcs(blk_len, false);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001507 payload := f_rnd_octstring(i);
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001508 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
1509 more := false, e := true);
1510 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001511 /* 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 +01001512 ul_data := t_RLCMAC_UL_DATA(cs := tx_cs,
1513 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001514 cv := cv,
1515 bsn := ms.ul_tbf.bsn,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001516 blocks := blocks);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001517 f_ultbf_inc_bsn(ms.ul_tbf);
1518 f_ms_tx_ul_block(ms, ul_data);
1519
1520 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02001521 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 +02001522
1523 /* we will receive UL ACK/NACK from time to time, handle it. */
1524 f_rx_rlcmac_dl_block(dl_block, dl_fn);
1525 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
1526 continue;
1527 }
1528 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
1529 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
1530 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
1531 f_shutdown(__BFILE__, __LINE__);
1532 }
1533
1534 log("Rx Packet Uplink ACK / NACK");
1535 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
1536 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1537 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1538 }
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07001539
1540 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02001541}
1542
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001543function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
1544 var octetstring payload;
1545 var template (value) RlcmacUlBlock ul_data;
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001546 var template (value) LlcBlockHdr blk_hdr;
1547 var template (value) LlcBlocks blocks;
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001548 var integer block_len, max_valid_data_len;
1549 timer T;
1550
1551 block_len := f_rlcmac_cs_mcs2block_len(cs);
1552 /* We need to send with TLLI since we are in One-Phase Access Contenion
1553 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
1554 * indicator, -1 for spare bits octet at the end */
1555 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
1556 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 +07001557 blk_hdr := t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload),
1558 more := false, e := true);
1559 blocks := { t_RLCMAC_LLCBLOCK(payload, blk_hdr) };
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001560 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := cs,
1561 tfi := ms.ul_tbf.tfi,
Vadim Yanitskiyceb1f982020-10-17 15:58:19 +07001562 cv := cv,
1563 bsn := ms.ul_tbf.bsn,
1564 blocks := blocks,
1565 tlli := ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001566 f_ultbf_inc_bsn(ms.ul_tbf);
1567 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
1568
1569 T.start(0.5);
1570 alt {
Harald Welte5339b2e2020-10-04 22:52:56 +02001571 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, ?)) {
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001572 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
1573 f_shutdown(__BFILE__, __LINE__);
1574 }
1575 [] T.timeout {
1576 setverdict(pass);
1577 }
1578 }
1579}
1580/* Verify PCU finds out incorrectly formated RLC block and discards it. This
1581 blocks intentionally contain last byte of data placed in last byte of RLC
1582 containing padding/spare bits, which is incorrect. Spare bits exist and are
1583 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
1584 discounting padding in octet" */
1585testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
1586 var GprsMS ms;
1587 var integer block_len, max_valid_data_len;
1588
1589 /* Initialize NS/BSSGP side */
1590 f_init_bssgp();
1591 /* Initialize GPRS MS side */
1592 f_init_gprs_ms();
1593 ms := g_ms[0]; /* We only use first MS in this test */
1594
1595 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001596 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001597
1598 /* Establish BSSGP connection to the PCU */
1599 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001600 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001601
1602 /* Establish an Uplink TBF */
1603 f_ms_establish_ul_tbf(ms);
1604
1605 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
1606 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
1607 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
1608
Vadim Yanitskiy8e6df0c2020-10-18 00:13:15 +07001609 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02001610}
1611
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001612/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1613 * answered, so TBFs for uplink and later for downlink are created.
1614 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001615private 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 +02001616 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001617 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001618 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001619 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001620 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001621
1622 /* Initialize NS/BSSGP side */
1623 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001624 /* Initialize GPRS MS side */
1625 f_init_gprs_ms();
1626 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001627
1628 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001629 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001630
1631 /* Establish BSSGP connection to the PCU */
1632 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001633 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001634
1635 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001636 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001637
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001638 /* Send one UL block (with TLLI since we are in One-Phase Access
1639 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001640 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001641 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1642 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001643 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001644
1645 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02001646 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001647
1648 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001649 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1650 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001651
1652 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1653 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001654 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001655
1656 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001657 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1658 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1659 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001660
1661 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001662}
1663
1664/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1665 * answered, so TBFs for uplink and later for downlink are created.
1666 */
1667testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001668 var template CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001669 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001670}
1671
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001672/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1673 * answered, so TBFs for uplink and later for downlink are created.
1674 */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001675private function f_TC_mo_ping_pong_2phase_access(PCUIF_Flags ind_flags,
1676 template (value) MSRadioAccessCapabilityV ms_racap,
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001677 template (present) CodingScheme exp_ul_cs_mcs := ?,
1678 template (present) CodingScheme exp_dl_cs_mcs := ?)
1679runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001680 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001681 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01001682 var PollFnCtx pollctx;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001683 var uint32_t sched_fn;
1684 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001685 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001686 var GprsMS ms;
1687
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001688 /* Initialize NS/BSSGP side */
1689 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001690 /* Initialize GPRS MS side */
1691 f_init_gprs_ms();
1692 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001693
1694 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001695 f_init_raw(testcasename(), ts_PCUIF_INFO_default(ind_flags));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001696
1697 /* Establish BSSGP connection to the PCU */
1698 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001699 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001700
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01001701 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS */
1702 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 +02001703
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001704 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
1705 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 +02001706 f_shutdown(__BFILE__, __LINE__);
1707 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001708
1709 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1710 and make sure it is ACKED fine */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001711 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001712
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001713 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01001714 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 +02001715
1716 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02001717 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001718
1719 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001720 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001721 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001722 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001723 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001724
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001725 /* PCU acks the UL data after having received CV=0) */
1726 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1727
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001728 /* 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 +02001729 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 +02001730
1731 /* ACK the DL block */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001732 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1733 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 +02001734 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001735
1736 f_shutdown(__BFILE__, __LINE__, final := true);
1737}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001738
1739testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1740 var MultislotCap_GPRS mscap_gprs := {
1741 gprsmultislotclass := '00011'B,
1742 gprsextendeddynalloccap := '0'B
1743 };
1744 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001745 var template CodingScheme exp_ul_cs_mcs := cs_gprs_any;
1746 var template CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001747
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001748 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001749}
1750
1751testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001752 var MultislotCap_GPRS mscap_gprs := {
1753 gprsmultislotclass := '00011'B,
1754 gprsextendeddynalloccap := '0'B
1755 };
1756 var MultislotCap_EGPRS mscap_egprs := {
1757 egprsmultislotclass := '00011'B,
1758 egprsextendeddynalloccap := '0'B
1759 };
1760 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001761 var template CodingScheme exp_ul_cs_mcs := mcs_egprs_any;
1762 var template CodingScheme exp_dl_cs_mcs := mcs_egprs_any;
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001763
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001764 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_default, ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001765}
1766
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001767testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
1768 /* Configure PCU to force two phase access */
1769 g_force_two_phase_access := true;
1770
1771 var MultislotCap_GPRS mscap_gprs := {
1772 gprsmultislotclass := '00011'B,
1773 gprsextendeddynalloccap := '0'B
1774 };
1775 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1776 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001777 var template CodingScheme exp_dl_cs_mcs := cs_gprs_any;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001778
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001779 f_TC_mo_ping_pong_2phase_access(c_PCUIF_Flags_noMCS, ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001780}
1781
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001782/* Test scenario where SGSN wants to send some data against MS and it is
1783 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1784 */
Vadim Yanitskiyc67240a2020-10-17 15:59:37 +07001785private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit,
1786 template (present) CodingScheme exp_cs_mcs := ?)
1787runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001788 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001789 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001790 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001791 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001792 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001793
1794 /* Initialize NS/BSSGP side */
1795 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001796 /* Initialize GPRS MS side */
1797 f_init_gprs_ms();
1798 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001799
1800 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001801 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001802
1803 /* Establish BSSGP connection to the PCU */
1804 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001805 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001806
1807 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001808 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
1809 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001810
1811 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1812 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001813 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001814
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02001815 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrole8db6732020-11-12 21:06:41 +01001816 f_dltbf_ack_block(ms.dl_tbf, dl_block, '1'B);
1817 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 +02001818 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001819
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02001820 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001821 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001822
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001823 /* Send one UL block (with TLLI since we are in One-Phase Access
1824 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001825 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001826 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1827 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001828 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001829
1830 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02001831 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001832
1833 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001834}
1835
1836testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001837 var template CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001838 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1839}
1840
1841/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1842/* information about the MS */
1843testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1844 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1845 gprsmultislotclass := '00011'B,
1846 gprsextendeddynalloccap := '0'B
1847 } ;
1848 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol4fbeefd2020-11-05 13:47:24 +01001849 var template CodingScheme exp_cs_mcs := cs_gprs_any;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001850 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1851}
1852
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001853/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
1854 * TBF, it will request retransmission through UL ACK/NACK (with missing block
1855 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
1856 * be transferred).
1857 */
1858testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001859 var RlcmacDlBlock dl_block;
1860 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001861 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001862 var octetstring total_payload;
1863 var octetstring payload;
1864 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001865 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001866 var GprsMS ms;
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001867 var uint32_t payload_fill_len;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001868
1869 /* Initialize NS/BSSGP side */
1870 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001871 /* Initialize GPRS MS side */
1872 f_init_gprs_ms();
1873 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001874
1875 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01001876 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001877
1878 /* Establish BSSGP connection to the PCU */
1879 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001880 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001881
1882 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001883 f_ms_establish_ul_tbf(ms);
1884 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001885
1886 /* Send one UL block (with TLLI since we are in One-Phase Access
1887 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001888 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 Pedrol4f7b8fd2020-05-18 18:28:17 +02001889 f_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001890
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001891 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1892 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001893 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001894 total_payload := payload;
1895
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001896 payload_fill_len := f_ultbf_payload_fill_length(ms.ul_tbf);
1897
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001898 /* Send 2 packets, skip 1 (inc bsn) and send another one */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001899 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001900 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001901 total_payload := total_payload & payload;
1902
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001903 payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001904 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001905 total_payload := total_payload & payload;
1906
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001907 lost_payload := f_rnd_octstring(payload_fill_len);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001908 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 +02001909 total_payload := total_payload & lost_payload;
1910
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001911 payload := f_rnd_octstring(payload_fill_len)
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001912 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001913 total_payload := total_payload & payload;
1914
1915 /* 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 +02001916 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001917
1918 /* On CV=0, we'll receive a UL ACK asking about missing block */
1919 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1920 /* TODO: check ack ack bitmap (URBB) */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01001921 ul_data := t_RLCMAC_UL_DATA(cs := ms.ul_tbf.tx_cs_mcs,
1922 tfi := tfi,
1923 cv := 15,
1924 bsn := 3,
1925 blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001926 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001927
1928 /* Now final ack is recieved */
1929 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1930 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001931 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001932
1933 /* receive one message on BSSGP with all aggregated data in payload: */
Harald Welte5339b2e2020-10-04 22:52:56 +02001934 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 +07001935
1936 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001937}
1938
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001939/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1940 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1941 * timeout occurs (specified by sent RRBP on DL block). */
1942testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001943 var RlcmacDlBlock dl_block;
1944 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001945 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001946 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001947
1948 /* Initialize NS/BSSGP side */
1949 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001950 /* Initialize GPRS MS side */
1951 f_init_gprs_ms();
1952 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001953
1954 /* Initialize the PCU interface abstraction */
1955 f_init_raw(testcasename());
1956
1957 /* Establish BSSGP connection to the PCU */
1958 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01001959 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001960
1961 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001962 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1963 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001964
1965 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1966 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001967 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001968
1969 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1970 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1971 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001972 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001973
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001974 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1975 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001976 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001977
1978 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001979 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1980 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1981 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001982
1983 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001984}
1985
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001986/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1987testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1988 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1989 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001990 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001991 var RlcmacDlBlock dl_block;
1992 var uint32_t ack_fn;
1993 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001994 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001995 timer T := 5.0;
1996
1997 /* Initialize NS/BSSGP side */
1998 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001999 /* Initialize GPRS MS side */
2000 f_init_gprs_ms();
2001 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002002
2003 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002004 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002005
Daniel Willmann535aea62020-09-21 13:27:08 +02002006 f_statsd_reset();
2007
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002008 /* Establish BSSGP connection to the PCU */
2009 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002010 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002011
2012 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002013 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2014 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002015
2016 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2017 f_sleep(X2002);
2018
2019 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2020 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002021 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002022
2023 /* TDMA frame number on which we are supposed to send the ACK */
2024 ack_fn := f_dl_block_ack_fn(dl_block, fn);
2025
2026 /* SGSN sends more blocks during the indicated RRBP */
2027 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
2028 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002029 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002030
2031 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
2032
2033 /* Make sure this block has the same TFI as was assigned
2034 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002035 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002036 setverdict(fail, "Rx DL data block with unexpected TFI: ",
2037 dl_block.data.mac_hdr.hdr_ext.tfi);
2038 f_shutdown(__BFILE__, __LINE__);
2039 }
2040
2041 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002042 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002043
2044 /* Break if this is the end of RRBP */
2045 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002046 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002047 break;
2048 }
2049 }
2050
2051 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002052 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 +07002053
2054 /* Make sure that the next block (after the Ack) is dummy */
2055 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2056
Daniel Willmann535aea62020-09-21 13:27:08 +02002057 var StatsDExpects expect := {
2058 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 0, max := 0},
2059 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2060 { name := "TTCN3.bts.0.immediate.assignment_UL", mtype := "c", min := 0, max := 0},
2061 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2062 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 0, max := 0},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002063 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 64, max := 64},
Daniel Willmann535aea62020-09-21 13:27:08 +02002064 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 0, max := 0}
2065 };
2066 f_statsd_expect(expect);
2067
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002068 f_shutdown(__BFILE__, __LINE__, final := true);
2069}
2070
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002071/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
2072 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
2073 * Check "3GPP TS 44.060" Annex B. */
2074testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
2075 var RlcmacDlBlock dl_block;
2076 var octetstring dataA := f_rnd_octstring(20);
2077 var octetstring dataB := f_rnd_octstring(13);
2078 var octetstring dataC := f_rnd_octstring(3);
2079 var octetstring dataD := f_rnd_octstring(12);
2080 var uint32_t sched_fn;
2081 var GprsMS ms;
2082 var template (value) RlcmacUlBlock ul_data;
2083
2084 /* Initialize NS/BSSGP side */
2085 f_init_bssgp();
2086 /* Initialize GPRS MS side */
2087 f_init_gprs_ms();
2088 ms := g_ms[0]; /* We only use first MS in this test */
2089
2090 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002091 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002092
2093 /* Establish BSSGP connection to the PCU */
2094 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002095 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002096
2097 /* Establish an Uplink TBF */
2098 f_ms_establish_ul_tbf(ms);
2099
2100 /* Summary of what's transmitted:
2101 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
2102 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
2103 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
2104 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
2105 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
2106 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
2107 */
2108
2109 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002110 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2111 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002112 cv := 3,
2113 bsn := ms.ul_tbf.bsn,
2114 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
2115 tlli := ms.tlli);
2116 /* Indicate no llc header, meaning first LLC block doesn't finish in current
2117 * RLCMAC block being sent. */
2118 ul_data.data.mac_hdr.e := true;
2119 f_ultbf_inc_bsn(ms.ul_tbf);
2120 f_ms_tx_ul_block(ms, ul_data);
2121
2122 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002123 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2124 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002125 cv := 2,
2126 bsn := ms.ul_tbf.bsn,
2127 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
2128 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
2129 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
2130 },
2131 tlli := ms.tlli);
2132 f_ultbf_inc_bsn(ms.ul_tbf);
2133 f_ms_tx_ul_block(ms, ul_data);
2134
2135 /* UL block dataA should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002136 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 +02002137
2138 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002139 ul_data := t_RLCMAC_UL_DATA_TLLI(cs := CS_1,
2140 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002141 cv := 1,
2142 bsn := ms.ul_tbf.bsn,
2143 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
2144 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
2145 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
2146 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
2147 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
2148 },
2149 tlli := ms.tlli);
2150 f_ultbf_inc_bsn(ms.ul_tbf);
2151 f_ms_tx_ul_block(ms, ul_data);
2152
2153 /* UL block dataB and dataC should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002154 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id, dataB));
2155 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 +02002156
2157 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
Pau Espin Pedrolcb00c522020-11-06 19:52:05 +01002158 ul_data := t_RLCMAC_UL_DATA_TLLI(
2159 cs := CS_1,
2160 tfi := ms.ul_tbf.tfi,
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02002161 cv := 0,
2162 bsn := ms.ul_tbf.bsn,
2163 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
2164 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
2165 },
2166 tlli := ms.tlli);
2167 f_ultbf_inc_bsn(ms.ul_tbf);
2168 f_ms_tx_ul_block(ms, ul_data);
2169
2170 /* UL block dataB and dataD should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002171 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 +02002172
2173 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2174 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2175 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2176
2177 f_shutdown(__BFILE__, __LINE__, final := true);
2178}
2179
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002180/* Verify allocation and use of multislot tbf, triggered by MS class provided in SGSN. SYS#5131 */
2181testcase TC_dl_multislot_tbf_ms_class_from_sgsn() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002182 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01002183 var octetstring data := f_rnd_octstring(10);
2184 var PacketDlAssign dl_tbf_ass;
2185 var RlcmacDlBlock dl_block;
2186 var uint32_t poll_fn;
2187 var uint32_t sched_fn;
2188 var GprsMS ms;
2189 timer T := 5.0;
2190
2191 /* Initialize NS/BSSGP side */
2192 f_init_bssgp();
2193 /* Initialize GPRS MS side */
2194 f_init_gprs_ms();
2195 ms := g_ms[0]; /* We only use first MS in this test */
2196
2197 /* Only 1 TRX with 8 PDCH */
2198 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '11111111'B, 0);
2199 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2200
2201 /* Initialize the PCU interface abstraction */
2202 f_init_raw(testcasename(), info_ind);
2203
2204 /* Establish BSSGP connection to the PCU */
2205 f_bssgp_establish();
2206 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2207
2208 /* Establish an Uplink TBF, this way the PCU can send DL Assignment
2209 through PDCH (no multiblock assignment possible through PCH) */
2210 f_ms_establish_ul_tbf(ms);
2211
2212 /* Send one UL block (with TLLI since we are in One-Phase Access
2213 contention resoultion) and make sure it is ACKED fine */
2214 f_ms_tx_ul_data_block(ms, data, with_tlli := true, nr := f_ms_tx_TsTrxBtsNum(ms));
2215 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2216 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2217
2218 /* SGSN sends some DL data, PCU will assign DL TBF through PACCH */
2219 var MultislotCap_GPRS_BSSGP mscap_gprs := {
2220 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2221 gprsextendeddynalloccap := '0'B
2222 };
2223 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
2224 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2225 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
2226 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
2227 setverdict(fail, "Expected 8 PDCH slots allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
2228 f_shutdown(__BFILE__, __LINE__);
2229 }
2230 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2231
2232 f_shutdown(__BFILE__, __LINE__, final := true);
2233}
2234
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002235testcase TC_dl_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002236 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01002237 var RlcmacDlBlock dl_block;
2238 var octetstring data := f_rnd_octstring(10);
2239 var PollFnCtx pollctx;
2240 var uint32_t sched_fn;
2241 var GprsMS ms;
2242
2243 var MultislotCap_GPRS mscap_gprs := {
2244 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2245 gprsextendeddynalloccap := '0'B
2246 };
2247 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
2248
2249
2250 /* Initialize NS/BSSGP side */
2251 f_init_bssgp();
2252 /* Initialize GPRS MS side */
2253 f_init_gprs_ms();
2254 ms := g_ms[0]; /* We only use first MS in this test */
2255
2256 /* Only 1 TRX with 8 PDCH */
2257 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '11111111'B, 0);
2258 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2259
2260 /* Initialize the PCU interface abstraction */
2261 f_init_raw(testcasename(), info_ind);
2262
2263 /* Establish BSSGP connection to the PCU */
2264 f_bssgp_establish();
2265 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2266
2267 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
2268 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
2269
2270 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
2271 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
2272
2273 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2274 dl_block := f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS, nr := f_ms_tx_TsTrxBtsNum(ms));
2275 if (f_dltbf_num_slots(ms.dl_tbf) != 8) {
2276 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_dltbf_num_slots(ms.dl_tbf));
2277 f_shutdown(__BFILE__, __LINE__);
2278 }
2279 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn, nr := f_ms_tx_TsTrxBtsNum(ms));
2280
2281 f_shutdown(__BFILE__, __LINE__, final := true);
2282}
2283
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01002284testcase TC_ul_multislot_tbf_ms_class_from_2phase() runs on RAW_PCU_Test_CT {
2285 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
2286 var RlcmacDlBlock dl_block;
2287 var octetstring data := f_rnd_octstring(10);
2288 var PollFnCtx pollctx;
2289 var uint32_t sched_fn;
2290 var GprsMS ms;
2291
2292 var MultislotCap_GPRS mscap_gprs := {
2293 gprsmultislotclass := '10010'B, /* MS class 18, supports 8 DL and 8 UL */
2294 gprsextendeddynalloccap := '0'B
2295 };
2296 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
2297
2298
2299 /* Initialize NS/BSSGP side */
2300 f_init_bssgp();
2301 /* Initialize GPRS MS side */
2302 f_init_gprs_ms();
2303 ms := g_ms[0]; /* We only use first MS in this test */
2304
2305 /* Only 1 TRX with 8 PDCH */
2306 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '11111111'B, 0);
2307 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2308
2309 /* Initialize the PCU interface abstraction */
2310 f_init_raw(testcasename(), info_ind);
2311
2312 /* Establish BSSGP connection to the PCU */
2313 f_bssgp_establish();
2314 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2315
2316 /* Send PACKET RESOURCE REQUEST to notify the MultiSlot Class */
2317 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
2318
2319 if (f_ultbf_num_slots(ms.ul_tbf) != 8) {
2320 setverdict(fail, "Expected 8 PDCH slot allocated but got ", f_ultbf_num_slots(ms.ul_tbf));
2321 f_shutdown(__BFILE__, __LINE__);
2322 }
2323
2324 f_shutdown(__BFILE__, __LINE__, final := true);
2325}
2326
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002327/* Test scenario where MS wants to request a new TBF once the current one is
2328 * ending, by means of sending a Packet Resource Request on ul slot provided by
2329 * last Pkt Ul ACK's RRBP.
2330 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
2331testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002332 var RlcmacDlBlock dl_block;
2333 var octetstring data := f_rnd_octstring(10);
2334 var uint32_t sched_fn;
2335 var uint32_t dl_fn;
2336 var template RlcmacDlBlock acknack_tmpl;
2337 var GprsMS ms;
2338
2339 /* Initialize NS/BSSGP side */
2340 f_init_bssgp();
2341 /* Initialize GPRS MS side */
2342 f_init_gprs_ms();
2343 ms := g_ms[0]; /* We only use first MS in this test */
2344
2345 /* Initialize the PCU interface abstraction */
2346 f_init_raw(testcasename());
2347
2348 /* Establish BSSGP connection to the PCU */
2349 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002350 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002351
2352 /* Establish an Uplink TBF */
2353 f_ms_establish_ul_tbf(ms);
2354
2355 /* Send one UL block (with TLLI since we are in One-Phase Access
2356 contention resoultion) and make sure it is ACKED fine */
2357 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
2358
2359 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002360 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002361
2362 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
2363 tr_UlAckNackGprs(ms.tlli,
2364 tr_AckNackDescription(final_ack := '1'B),
2365 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
2366 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
2367
2368 /* TODO: verify TBF_EST and FinalACK are both '1' above */
2369
2370 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07002371 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 +07002372 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002373 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2374 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2375
2376 /* Send one UL block (without TLLI since we are in Second-Phase Access)
2377 and make sure it is ACKED fine */
2378 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
2379
2380 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002381 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02002382
2383 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
2384 /* ACK the ACK */
2385 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2386
2387 f_shutdown(__BFILE__, __LINE__, final := true);
2388}
2389
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002390/* Test CS paging over the BTS<->PCU socket.
2391 * 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.
2392 * Paging should be send on the PACCH.
2393 *
2394 * 1. Send a Paging Request over PCU socket.
2395 * 2. Send a Ready-To-Send message over PCU socket
2396 * 3. Expect a Paging Frame
2397 */
2398testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002399 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002400 var MobileIdentityLV mi;
2401 var octetstring mi_enc_lv;
2402 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002403 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002404
2405 /* Initialize NS/BSSGP side */
2406 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002407 /* Initialize GPRS MS side */
2408 f_init_gprs_ms();
2409 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002410
2411 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002412 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002413
2414 /* Establish BSSGP connection to the PCU */
2415 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002416 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002417
2418 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002419 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002420
2421 /* build mobile Identity */
2422 mi := valueof(ts_MI_IMSI_LV(imsi));
2423 mi_enc_lv := enc_MobileIdentityLV(mi);
2424 /* Send paging request */
2425 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
2426 sapi :=PCU_IF_SAPI_PDTCH));
2427
2428 /* Receive it on BTS side towards MS */
2429 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
2430
2431 /* Make sure that Packet Paging Request contains the same IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07002432 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
2433 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
2434 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
2435 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002436
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002437 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002438}
2439
2440/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
2441 */
2442private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
2443runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002444 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002445 var hexstring imsi := f_gen_imsi(42);
2446 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002447 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002448
2449 /* Initialize NS/BSSGP side */
2450 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002451 /* Initialize GPRS MS side */
2452 f_init_gprs_ms();
2453 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002454
2455 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002456 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002457
2458 /* Establish BSSGP connection to the PCU */
2459 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002460 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002461
2462 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002463 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002464
2465 /* Send paging request with or without TMSI */
2466 if (use_ptmsi) {
2467 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
2468 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
2469 } else {
2470 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
2471 }
2472
2473 /* Receive it on BTS side towards MS */
2474 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
2475
2476 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07002477 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002478 if (use_ptmsi) {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07002479 if (not f_pkt_paging_match_tmsi(req, tmsi, ps_domain := false)) {
2480 setverdict(fail, "Failed to match P-TMSI ", tmsi, " in ", req);
2481 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002482 } else {
Vadim Yanitskiy3e5f0742020-11-01 03:30:18 +07002483 if (not f_pkt_paging_match_imsi(req, imsi, ps_domain := false)) {
2484 setverdict(fail, "Failed to match IMSI ", imsi, " in ", req);
2485 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002486 }
2487
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002488 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002489}
2490
2491testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
2492 f_tc_paging_cs_from_sgsn(0, true);
2493}
2494
2495testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
2496 f_tc_paging_cs_from_sgsn(0);
2497}
2498
2499testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02002500 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002501}
2502
2503/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
2504 */
2505private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
2506runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002507 var integer imsi_suff_tx := 423;
2508 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002509 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002510
2511 /* Initialize NS/BSSGP side */
2512 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02002513 /* Initialize GPRS MS side */
2514 f_init_gprs_ms();
2515 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002516
2517 /* Initialize the PCU interface abstraction */
2518 f_init_raw(testcasename());
2519
2520 /* Establish BSSGP connection to the PCU */
2521 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002522 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002523
2524 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
2525 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
2526 if (use_ptmsi) {
2527 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
2528 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
2529 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
2530 } else {
2531 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
2532 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
2533 }
2534
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002535 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002536}
2537
2538testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
2539 f_tc_paging_ps_from_sgsn(0, true);
2540}
2541
2542testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
2543 f_tc_paging_ps_from_sgsn(0);
2544}
2545
2546testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
Harald Welte5339b2e2020-10-04 22:52:56 +02002547 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvc[0].bvci);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002548}
2549
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002550/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
2551testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
2552 var RlcmacDlBlock dl_block;
2553 var octetstring data := f_rnd_octstring(10);
2554 var uint32_t sched_fn;
2555 var uint32_t dl_fn;
2556 var GprsMS ms;
2557
2558 /* Initialize NS/BSSGP side */
2559 f_init_bssgp();
2560 /* Initialize GPRS MS side */
2561 f_init_gprs_ms();
2562 ms := g_ms[0]; /* We only use first MS in this test */
2563
2564 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002565 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002566
Daniel Willmann535aea62020-09-21 13:27:08 +02002567 f_statsd_reset();
2568
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002569 /* Establish BSSGP connection to the PCU */
2570 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002571 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002572
2573 /* Establish an Uplink TBF */
2574 f_ms_establish_ul_tbf(ms);
2575
2576 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
2577 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
2578 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2579 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2580 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2581
2582 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002583 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002584
2585 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
2586 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
2587 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2588
2589 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
2590 f_sleep(X2002);
2591 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
2592
2593 /* ACK the DL block */
2594 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
2595 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
2596 f_dl_block_ack_fn(dl_block, dl_fn));
2597
Daniel Willmann535aea62020-09-21 13:27:08 +02002598 var StatsDExpects expect := {
2599 { name := "TTCN3.bts.0.rach.requests", mtype := "c", min := 1, max := 1},
2600 { name := "TTCN3.bts.0.immediate.assignment_DL", mtype := "c", min := 1, max := 1},
2601 { name := "TTCN3.bts.0.tbf.dl.alloc", mtype := "c", min := 1, max := 1},
2602 { name := "TTCN3.bts.0.tbf.ul.alloc", mtype := "c", min := 1, max := 1},
Pau Espin Pedrol0bf74e52020-12-11 19:25:42 +01002603 { name := "TTCN3.bts.0.rlc.dl_payload_bytes", mtype := "c", min := 10, max := 10},
Pau Espin Pedrol599d56b2020-11-17 12:01:46 +01002604 { name := "TTCN3.bts.0.rlc.ul_payload_bytes", mtype := "c", min := 26, max := 26}
Daniel Willmann535aea62020-09-21 13:27:08 +02002605 };
2606 f_statsd_expect(expect);
2607
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002608 f_shutdown(__BFILE__, __LINE__, final := true);
2609}
2610
2611/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
2612testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
2613 var RlcmacDlBlock dl_block;
2614 var octetstring data := f_rnd_octstring(10);
2615 var uint32_t sched_fn;
2616 var uint32_t dl_fn;
2617 var GprsMS ms;
2618
2619 /* Initialize NS/BSSGP side */
2620 f_init_bssgp();
2621 /* Initialize GPRS MS side */
2622 f_init_gprs_ms();
2623 ms := g_ms[0]; /* We only use first MS in this test */
2624
2625 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01002626 f_init_raw(testcasename(), ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002627
2628 /* Establish BSSGP connection to the PCU */
2629 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01002630 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002631
2632 /* Establish an Uplink TBF */
2633 f_ms_establish_ul_tbf(ms);
2634
2635 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
2636 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
2637 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
2638 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2639 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
2640
2641 /* UL block should be received in SGSN */
Harald Welte5339b2e2020-10-04 22:52:56 +02002642 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.bvc[0].cell_id));
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002643
2644 /* Now SGSN sends some DL data with an invalid IMSI */
2645 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
2646
2647 BSSGP_SIG[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
2648
2649 /* TODO: make sure no data is sent over PCU -> MS */
2650
2651 f_shutdown(__BFILE__, __LINE__, final := true);
2652}
2653
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01002654private function f_tc_dl_data_no_llc_ui_dummy(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit) runs on RAW_PCU_Test_CT {
2655 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
2656 var octetstring data := f_rnd_octstring(6);
2657 var RlcmacDlBlock dl_block;
2658 var GprsMS ms;
2659 var uint32_t fn;
2660
2661 /* Initialize NS/BSSGP side */
2662 f_init_bssgp();
2663 /* Initialize GPRS MS side */
2664 f_init_gprs_ms();
2665 ms := g_ms[0]; /* We only use first MS in this test */
2666
2667 /* Initialize the PCU interface abstraction */
2668 f_init_raw(testcasename());
2669
2670 /* Establish BSSGP connection to the PCU */
2671 f_bssgp_establish();
2672 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
2673
2674 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2675 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
2676 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2677
2678 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
2679 f_sleep(X2002);
2680
2681 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
2682 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
2683
2684 if (ischosen(dl_block.data_egprs)) {
2685 if (lengthof(dl_block.data_egprs.blocks) != 2) {
2686 setverdict(fail, "DL EGPRS block has unexpected number of LLC frames: ", dl_block.data_egprs);
2687 f_shutdown(__BFILE__, __LINE__);
2688 }
2689 if (dl_block.data_egprs.blocks[1].hdr.length_ind != 127) {
2690 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
2691 f_shutdown(__BFILE__, __LINE__);
2692 }
2693 if (not match(dl_block.data_egprs.blocks[1].payload,
2694 f_pad_oct(''O, lengthof(dl_block.data_egprs.blocks[1].payload), '2B'O))) {
2695 setverdict(fail, "DL EGPRS block 2nd llc frame is not padding!: ", dl_block.data_egprs);
2696 f_shutdown(__BFILE__, __LINE__);
2697 }
2698 } else if (lengthof(dl_block.data.blocks) > 1) {
2699 setverdict(fail, "DL GPRS block has extra unexpected LLC frames: ", dl_block.data);
2700 f_shutdown(__BFILE__, __LINE__);
2701 }
2702
2703 f_shutdown(__BFILE__, __LINE__, final := true);
2704}
2705
2706/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
2707 * containing llc data. See OS#4849 */
2708testcase TC_dl_gprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
2709 f_tc_dl_data_no_llc_ui_dummy(omit);
2710}
2711
2712/* Verify osmo-pcu Doesn't append LLC UI dummy frames to rlcmac blocks
2713 * containing llc data. See OS#4849 */
2714testcase TC_dl_egprs_data_no_llc_ui_dummy() runs on RAW_PCU_Test_CT {
2715
2716 var MultislotCap_GPRS_BSSGP mscap_gprs := {
2717 gprsmultislotclass := '00011'B,
2718 gprsextendeddynalloccap := '0'B
2719 };
2720 var MultislotCap_EGPRS_BSSGP mscap_egprs := {
2721 egprsmultislotclass := '00011'B,
2722 egprsextendeddynalloccap := '0'B
2723 };
2724 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
2725
2726 f_tc_dl_data_no_llc_ui_dummy(ms_racap);
2727}
2728
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002729private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07002730 template GsmRrMessage t_imm_ass := ?,
2731 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002732runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07002733 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002734 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002735
2736 ra11 := enc_EGPRSPktChRequest2uint(req);
2737 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
2738
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07002739 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07002740 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002741 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002742 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002743 }
2744
2745 setverdict(pass);
2746}
2747
2748testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
2749 var template GsmRrMessage imm_ass;
2750 var template IaRestOctets rest;
2751 var template EgprsUlAss ul_ass;
2752
2753 /* Initialize the PCU interface abstraction */
2754 f_init_raw(testcasename());
2755
2756 var EGPRSPktChRequest req := {
2757 /* NOTE: other fields are set in the loop */
2758 signalling := { tag := '110011'B }
2759 };
2760
2761 for (var integer i := 0; i < 6; i := i + 1) {
2762 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2763 req.signalling.random_bits := ext_ra;
2764
2765 /* For signalling, do we expect Multiblock UL TBF Assignment? */
2766 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2767 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2768 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2769
2770 f_TC_egprs_pkt_chan_req(req, imm_ass);
2771 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002772
2773 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002774}
2775
2776testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
2777 var template GsmRrMessage imm_ass;
2778 var template IaRestOctets rest;
2779 var template EgprsUlAss ul_ass;
2780
2781 /* Initialize the PCU interface abstraction */
2782 f_init_raw(testcasename());
2783
2784 var EGPRSPktChRequest req := {
2785 /* NOTE: other fields are set in the loop */
2786 one_phase := { tag := '0'B }
2787 };
2788
2789 for (var integer i := 0; i < 6; i := i + 1) {
2790 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2791 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
2792 var BIT2 priority := substr(ext_ra, 0, 2);
2793 var BIT3 rand := substr(ext_ra, 2, 3);
2794
2795 req.one_phase.multislot_class := mslot_class;
2796 req.one_phase.priority := priority;
2797 req.one_phase.random_bits := rand;
2798
2799 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
2800 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
2801 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2802 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2803
2804 f_TC_egprs_pkt_chan_req(req, imm_ass);
2805 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002806
2807 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002808}
2809
2810testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
2811 var template GsmRrMessage imm_ass;
2812 var template IaRestOctets rest;
2813 var template EgprsUlAss ul_ass;
2814
2815 /* Initialize the PCU interface abstraction */
2816 f_init_raw(testcasename());
2817
2818 var EGPRSPktChRequest req := {
2819 /* NOTE: other fields are set in the loop */
2820 two_phase := { tag := '110000'B }
2821 };
2822
2823 for (var integer i := 0; i < 6; i := i + 1) {
2824 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2825 var BIT2 priority := substr(ext_ra, 0, 2);
2826 var BIT3 rand := substr(ext_ra, 2, 3);
2827
2828 req.two_phase.priority := priority;
2829 req.two_phase.random_bits := rand;
2830
2831 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
2832 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2833 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2834 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2835
2836 f_TC_egprs_pkt_chan_req(req, imm_ass);
2837 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002838
2839 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002840}
2841
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002842private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
2843 template IARRestOctets rest := ?,
2844 PCUIF_BurstType bt := BURST_TYPE_1)
2845runs on RAW_PCU_Test_CT {
2846 var template ReqRefWaitInd tr_ref;
2847 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002848
2849 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
2850 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
2851 ra := bit2int(ra11), is_11bit := 1,
2852 burst_type := bt, fn := fn,
2853 arfcn := 871));
2854
2855 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07002856 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002857
2858 /* Just to have a short-name reference to the actual message */
2859 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
2860
2861 /* Make sure that Request Reference list contains at least one entry
2862 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
2863 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn));
2864 if (not match(iar.payload, { *, tr_ref, * })) {
2865 setverdict(fail, "Request Reference list does not match");
2866 f_shutdown(__BFILE__, __LINE__);
2867 }
2868
2869 /* Match Feature Indicator (must indicate PS domain) */
2870 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
2871 setverdict(fail, "Feature Indicator does not match");
2872 f_shutdown(__BFILE__, __LINE__);
2873 }
2874
2875 /* Match IAR Rest Octets */
2876 if (not match(iar.rest_octets, rest)) {
2877 setverdict(fail, "IAR Rest Octets does not match: ",
2878 iar.rest_octets, " vs expected ", rest);
2879 f_shutdown(__BFILE__, __LINE__);
2880 }
2881
2882 setverdict(pass);
2883}
2884
2885/* Verify the contents of RR Immediate Assignment Reject message and its
2886 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
2887testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
2888 var template IARRestOctets rest;
2889 var BIT5 ext_ra;
2890
2891 /* Initialize the PCU interface abstraction */
2892 f_init_raw(testcasename());
2893
2894 for (var integer i := 0; i < 6; i := i + 1) {
2895 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
2896 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
2897
2898 /* Intentionally incorrect message (see table 11.2.5a.2) */
2899 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
2900 }
2901
2902 f_shutdown(__BFILE__, __LINE__, final := true);
2903}
2904
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07002905/* At the moment, the IUT does not support any emergency services. Make sure
2906 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
2907testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
2908 var template IARRestOctets rest;
2909 var BIT5 ext_ra;
2910 var BIT11 ra11;
2911
2912 /* Initialize the PCU interface abstraction */
2913 f_init_raw(testcasename());
2914
2915 var EGPRSPktChRequest req := {
2916 /* NOTE: other fields are set in the loop */
2917 emergency := { tag := '110111'B }
2918 };
2919
2920 for (var integer i := 0; i < 6; i := i + 1) {
2921 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
2922 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
2923
2924 req.emergency.random_bits := ext_ra;
2925 ra11 := enc_EGPRSPktChRequest2bits(req);
2926
2927 /* Intentionally incorrect message (see table 11.2.5a.2) */
2928 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
2929 }
2930
2931 f_shutdown(__BFILE__, __LINE__, final := true);
2932}
2933
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002934/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
2935testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01002936 var PCUIF_info_ind info_ind;
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002937 var template IARRestOctets rest;
2938 var BIT11 ra11;
2939
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01002940 info_ind := valueof(ts_PCUIF_INFO_default);
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07002941
2942 /* Only the first TRX is enabled. */
2943 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
2944 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000001'B, 0);
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01002945
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002946 /* Initialize the PCU interface abstraction */
Pau Espin Pedrol7ebc1122020-10-29 13:33:39 +01002947 f_init_raw(testcasename(), info_ind);
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002948
2949 var EGPRSPktChRequest req := {
2950 one_phase := {
2951 tag := '0'B,
2952 multislot_class := '10101'B,
2953 priority := '01'B,
2954 random_bits := '101'B
2955 }
2956 };
2957
2958 /* We send 7 requests, the IUT gives us all available USFs (0..6).
2959 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
2960 for (var integer i := 0; i < 7; i := i + 1) {
2961 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2962 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2963 }
2964
2965 ra11 := enc_EGPRSPktChRequest2bits(req);
2966 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
2967
2968 /* At this point, the IUT should run out of free USFs */
2969 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
2970
2971 f_shutdown(__BFILE__, __LINE__, final := true);
2972}
2973
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002974/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07002975private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002976return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07002977 /* Pick a random MA length in range 2 .. max_ma_len */
2978 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
2979
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002980 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
2981 hsn := f_rnd_int(63),
2982 maio := f_rnd_int(63),
2983 ma := f_rnd_bitstring(ma_len));
2984}
2985
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002986private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
2987 in GsmRrMessage rr_msg)
2988{
2989 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
2990 var PCUIF_InfoTrxTs ts := info_ind.trx.v10[0].ts[ia.pkt_chan_desc.tn];
2991
2992 var template PacketChannelDescription tr_pkt_chan_desc := {
2993 channel_Type_spare := ?,
2994 tn := ?,
2995 tsc := ts.tsc,
2996 presence := '1'B,
2997 zero := omit,
2998 one := {
2999 maio := ts.maio,
3000 hsn := ts.hsn
3001 }
3002 };
3003
3004 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
3005 setverdict(fail, "Packet Channel Description does not match: ",
3006 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
3007 }
3008
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07003009 /* Mobile Allocation is expected to be octet-aligned */
3010 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
3011 var template MobileAllocationLV tr_ma := {
3012 len := ma_oct_len, /* in bytes */
3013 ma := substr(ts.ma, 0, ma_oct_len * 8)
3014 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003015
3016 if (not match(ia.mobile_allocation, tr_ma)) {
3017 setverdict(fail, "Mobile Allocation does not match: ",
3018 ia.mobile_allocation, " vs ", tr_ma);
3019 }
3020
3021 setverdict(pass);
3022}
3023
3024/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
3025testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
3026 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
3027 var GprsMS ms := valueof(t_GprsMS_def);
3028
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003029 /* Enable frequency hopping on TRX0/TS7 */
3030 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003031
3032 /* Initialize the PCU interface abstraction */
3033 f_init_raw(testcasename(), info_ind);
3034
3035 /* EGPRS Packet Channel Request (cause=Signalling) */
3036 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
3037
3038 /* Establish an Uplink EGPRS TBF */
3039 f_ms_establish_ul_tbf(ms);
3040
3041 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
3042 f_shutdown(__BFILE__, __LINE__, final := true);
3043}
3044
3045/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
3046testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003047 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003048 var GprsMS ms := valueof(t_GprsMS_def);
3049
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003050 /* Enable frequency hopping on TRX0/TS7 */
3051 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003052
3053 /* Initialize the PCU interface abstraction */
3054 f_init_raw(testcasename(), info_ind);
3055
3056 /* Establish an Uplink TBF */
3057 f_ms_establish_ul_tbf(ms);
3058
3059 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
3060 f_shutdown(__BFILE__, __LINE__, final := true);
3061}
3062
3063/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
3064testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003065 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003066 var GprsMS ms := valueof(t_GprsMS_def);
3067
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003068 /* Enable frequency hopping on TRX0/TS7 */
3069 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003070
3071 /* Initialize NS/BSSGP side */
3072 f_init_bssgp();
3073
3074 /* Initialize the PCU interface abstraction */
3075 f_init_raw(testcasename(), info_ind);
3076
3077 /* Establish BSSGP connection to the PCU */
3078 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003079 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003080
3081 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
3082 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
3083 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
3084
3085 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
3086 f_shutdown(__BFILE__, __LINE__, final := true);
3087}
3088
3089private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
3090 in FrequencyParameters fp)
3091{
3092 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
3093 var PCUIF_InfoTrxTs ts := info_ind.trx.v10[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003094
3095 /* Table 12.8.1: Frequency Parameters information elements */
3096 var template FrequencyParameters tr_fp := {
3097 tsc := ts.tsc,
3098 presence := '10'B, /* Direct encoding 1 */
3099 arfcn := omit,
3100 indirect := omit,
3101 direct1 := {
3102 maio := ts.maio,
3103 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
3104 mobile_allocation := {
3105 hsn := ts.hsn,
3106 rfl_number_list_present := '0'B,
3107 rfl_number_list := omit,
3108 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07003109 ma_length := ts.ma_bit_len,
3110 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003111 }
3112 },
3113 direct2 := omit
3114 };
3115
3116 if (not match(fp, tr_fp)) {
3117 setverdict(fail, "Frequency Parameters IE does not match: ",
3118 fp, " vs ", tr_fp);
3119 }
3120
3121 setverdict(pass);
3122}
3123
3124/* Make sure that Packet Uplink Assignment contains hopping parameters */
3125testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003126 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003127 var GprsMS ms := valueof(t_GprsMS_def);
3128 var uint32_t poll_fn;
3129
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003130 /* Enable frequency hopping on TRX0/TS7 */
3131 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003132
3133 /* Initialize the PCU interface abstraction */
3134 f_init_raw(testcasename(), info_ind);
3135
3136 /* Establish an Uplink TBF */
3137 f_ms_establish_ul_tbf(ms);
3138
3139 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
3140 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)));
3141
3142 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01003143 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
3144 var PacketUlAssignment ua := ms.ul_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003145
3146 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
3147 var template (omit) FrequencyParameters fp;
3148 if (ua.is_egprs == '1'B) {
3149 fp := ua.egprs.freq_par;
3150 } else {
3151 fp := ua.gprs.freq_par;
3152 }
3153
3154 /* This is an optional IE, so it's worth to check its presence */
3155 if (istemplatekind(fp, "omit")) {
3156 setverdict(fail, "Frequency Parameters IE is not present");
3157 f_shutdown(__BFILE__, __LINE__);
3158 }
3159
3160 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
3161 f_shutdown(__BFILE__, __LINE__, final := true);
3162}
3163
3164/* Make sure that Packet Downlink Assignment contains hopping parameters */
3165testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003166 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003167 var octetstring data := f_rnd_octstring(10);
3168 var GprsMS ms := valueof(t_GprsMS_def);
3169 var RlcmacDlBlock dl_block;
3170 var uint32_t poll_fn;
3171
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07003172 /* Enable frequency hopping on TRX0/TS7 */
3173 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003174
3175 /* Initialize NS/BSSGP side */
3176 f_init_bssgp();
3177
3178 /* Initialize the PCU interface abstraction */
3179 f_init_raw(testcasename(), info_ind);
3180
3181 /* Establish BSSGP connection to the PCU */
3182 f_bssgp_establish();
Pau Espin Pedrol7b761e22021-01-11 14:43:35 +01003183 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003184
3185 /* Establish an Uplink TBF */
3186 f_ms_establish_ul_tbf(ms);
3187
3188 /* Send an Uplink block, so this TBF becomes "active" */
3189 f_ms_tx_ul_data_block(ms, data, with_tlli := true);
3190
3191 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
3192 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
3193 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
3194
3195 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
3196 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
3197
3198 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
Pau Espin Pedrol46e36042020-10-29 21:27:43 +01003199 f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
3200 var PacketDlAssignment da := ms.dl_tbf.ass.pacch;
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07003201
3202 /* This is an optional IE, so it's worth to check its presence */
3203 if (not ispresent(da.freq_par)) {
3204 setverdict(fail, "Frequency Parameters IE is not present");
3205 f_shutdown(__BFILE__, __LINE__);
3206 }
3207
3208 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
3209 f_shutdown(__BFILE__, __LINE__, final := true);
3210}
3211
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07003212/* Check if the IUT handles subsequent INFO.ind messages */
3213testcase TC_pcuif_info_ind_subsequent() runs on RAW_PCU_Test_CT {
3214 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
3215 var PCUIF_Message pcu_msg;
3216
3217 /* Initialize the PCU interface abstraction */
3218 f_init_raw(testcasename(), info_ind);
3219
3220 /* Send 16 conseqtive INFO.ind messages and check that the IUT stays alive */
3221 for (var integer i := 0; i < 16; i := i + 1) {
3222 BTS.send(ts_PCUIF_INFO_IND(0, info_ind));
3223 f_pcuif_rx_data_req(pcu_msg);
3224 }
3225
3226 f_shutdown(__BFILE__, __LINE__, final := true);
3227}
3228
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003229/* Verify allocation of several MS along PDCH ts of several TRX. See OS#1775, SYS#5030 */
3230testcase TC_multitrx_multims_alloc() runs on RAW_PCU_Test_CT {
3231 var PCUIF_info_ind info_ind;
3232 var integer i;
3233 const integer num_ms := 8;
3234
3235 /* Initialize NS/BSSGP side */
3236 f_init_bssgp();
3237 /* Initialize GPRS MS side */
3238 f_init_gprs_ms(num_ms);
3239
Pau Espin Pedrol745a48b2020-10-30 15:31:07 +01003240 info_ind := valueof(ts_PCUIF_INFO_default(c_PCUIF_Flags_noMCS));
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003241 /* Only the 3 first TRX are enabled. The enabled ones all have same
3242 amount of resources, hence same amount of initial resources. */
Vadim Yanitskiyd5321fb2020-10-31 20:23:47 +07003243 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (3 .. 7));
3244 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000011'B, 0);
3245 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00001100'B, 1);
3246 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '11000000'B, 2);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003247
3248 /* Initialize the PCU interface abstraction */
3249 f_init_raw(testcasename(), info_ind);
3250
3251 /* Establish BSSGP connection to the PCU */
3252 f_bssgp_establish();
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07003253 f_multi_ms_bssgp_register();
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003254
Vadim Yanitskiy8a02b922020-10-31 21:57:10 +07003255 /* Establish an Uplink TBF for each GprsMS instance */
3256 f_multi_ms_establish_tbf(do_activate := false);
3257
3258 /* Check if all TBFs are allocated on different TRX in an uniform way */
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003259 for (i := 0; i < num_ms; i := i + 1) {
Pau Espin Pedrolb20b7e52020-10-28 21:28:45 +01003260 if (g_ms[i].ul_tbf.arfcn != info_ind.trx.v10[i mod 3].arfcn) {
3261 setverdict(fail, "Got assigned ARFCN ", g_ms[i].ul_tbf.arfcn,
3262 " vs exp ", info_ind.trx.v10[i mod 3].arfcn);
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02003263 f_shutdown(__BFILE__, __LINE__);
3264 }
3265 }
3266
3267 f_shutdown(__BFILE__, __LINE__, final := true);
3268}
3269
Pau Espin Pedrole1303052020-11-16 11:13:51 +01003270/* Verify concurrent PDCH use of EGPRS and GPRS (EGPRS dl rlcmac blk is
3271 * downgraded to CS1-4 so that GPRS can read the USF).
3272 * See 3GPP TS 44.060 5.2.4a "Multiplexing of GPRS, EGPRS and EGPRS2 capable mobile stations"
3273 */
3274testcase TC_multiplex_dl_gprs_egprs() runs on RAW_PCU_Test_CT {
3275 var PCUIF_info_ind info_ind;
3276 const integer num_ms := 2; /* 2 MS, first one is GPRS-only, second one is EGPRS */
3277 var PollFnCtx pollctx;
3278 var MSRadioAccessCapabilityV ms_racap;
3279 var uint32_t sched_fn, dl_fn, ack_fn;
3280 var octetstring data := f_rnd_octstring(10);
3281 var RlcmacDlBlock dl_block;
3282 var integer tx_data_remain := 5;
3283 var integer tgt_ms;
3284 var integer ms_gprs_usf_count[num_ms] := { 0, 0 };
3285 var integer ms_egprs_usf_count[num_ms] := { 0, 0 };
3286
3287 /* Initialize NS/BSSGP side */
3288 f_init_bssgp();
3289 /* Initialize GPRS MS side */
3290 f_init_gprs_ms(num_ms);
3291
3292 info_ind := valueof(ts_PCUIF_INFO_default);
3293 /* Only use 1 PDCH to make sure both end up in the same slot: */
3294 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000001'B, 0);
3295 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, '00000000'B, (1 .. 7));
3296
3297 /* Initialize the PCU interface abstraction */
3298 f_init_raw(testcasename(), info_ind);
3299
3300 /* Set Initial MCS > 4 and maintain it non-variable to simplify test */
3301 g_mcs_initial_dl := 5;
3302 g_mcs_max_dl := 5;
3303 f_pcuvty_set_allowed_cs_mcs();
3304
3305 /* Establish BSSGP connection to the PCU */
3306 f_bssgp_establish();
3307 f_multi_ms_bssgp_register();
3308
3309 var MultislotCap_GPRS mscap_gprs := {
3310 gprsmultislotclass := '00011'B,
3311 gprsextendeddynalloccap := '0'B
3312 };
3313 var MultislotCap_EGPRS mscap_egprs := {
3314 egprsmultislotclass := '00011'B,
3315 egprsextendeddynalloccap := '0'B
3316 };
3317
3318 /* Establish UL TBF for MS0 (GPRS-only) */
3319 ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3320 pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[0], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[0].tlli, ms_racap));
3321 if (not match(g_ms[0].ul_tbf.tx_cs_mcs, cs_gprs_any)) {
3322 setverdict(fail, "Wrong CS_MCS ", g_ms[0].ul_tbf.tx_cs_mcs, " received vs exp ", cs_gprs_any);
3323 f_shutdown(__BFILE__, __LINE__);
3324 }
3325 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3326 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), pollctx.fn, nr := pollctx.tstrxbts);
3327
3328 /* Establish UL TBF for MS1 (EGPRS) */
3329 ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
3330 pollctx := f_ms_establish_ul_tbf_2phase_access(g_ms[1], ts_RlcMacUlCtrl_PKT_RES_REQ(g_ms[1].tlli, ms_racap));
3331 if (not match(g_ms[1].ul_tbf.tx_cs_mcs, mcs_egprs_any)) {
3332 setverdict(fail, "Wrong CS_MCS ", g_ms[1].ul_tbf.tx_cs_mcs, " received vs exp ", mcs_egprs_any);
3333 f_shutdown(__BFILE__, __LINE__);
3334 }
3335 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3336 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), pollctx.fn, nr := pollctx.tstrxbts);
3337
3338 /* Now SGSN sends some DL data to MS0, PCU will assign a GPRS DL TBF on PACCH */
3339 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
3340 f_sleep(0.1);
3341 f_ms_rx_pkt_ass_pacch(g_ms[0], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
3342 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
3343 f_ms_tx_ul_block(g_ms[0], ts_RLCMAC_CTRL_ACK(g_ms[0].tlli), sched_fn);
3344 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
3345 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, cs_gprs_any);
3346 /* ACK the DL block */
3347 f_dltbf_ack_block(g_ms[0].dl_tbf, dl_block, '0'B);
3348 f_ms_tx_ul_block(g_ms[0], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[0].dl_tbf, false),
3349 f_dl_block_ack_fn(dl_block, dl_fn));
3350
3351 /* Now SGSN sends some DL data to MS1, PCU will assign a EGPRS DL TBF on PACCH */
3352 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
3353 f_sleep(0.1);
3354 f_ms_rx_pkt_ass_pacch(g_ms[1], sched_fn, tr_RLCMAC_DL_PACKET_ASS);
3355 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
3356 f_ms_tx_ul_block(g_ms[1], ts_RLCMAC_CTRL_ACK(g_ms[1].tlli), sched_fn);
3357 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
3358 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, mcs_egprs_any);
3359 /* ACK the DL block */
3360 f_dltbf_ack_block(g_ms[1].dl_tbf, dl_block, '0'B);
3361 f_ms_tx_ul_block(g_ms[1], f_dltbf_ts_RLCMAC_DL_ACK_NACK(g_ms[1].dl_tbf, true),
3362 f_dl_block_ack_fn(dl_block, dl_fn));
3363
3364 data := f_rnd_octstring(1400);
3365 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
3366 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
3367
3368 for (var integer i := 0; i < 800; i := i + 1) {
3369 f_rx_rlcmac_dl_block(dl_block, dl_fn);
3370
3371 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL)) {
3372 /* No more data to receive, done */
3373 break;
3374 }
3375
3376 if (ischosen(dl_block.ctrl)) {
3377 setverdict(fail, "Unexpected DL CTRL block ", dl_block);
3378 f_shutdown(__BFILE__, __LINE__);
3379 } else if (ischosen(dl_block.data_egprs)) {
3380 if (not match(dl_block.data_egprs.mac_hdr.tfi, g_ms[1].dl_tbf.tfi)) {
3381 setverdict(fail, "EGPRS DL DATA not matching EGPRS MS TFI (", g_ms[1].dl_tbf.tfi, "): ", dl_block.data_egprs.mac_hdr.tfi);
3382 f_shutdown(__BFILE__, __LINE__);
3383 }
3384 tgt_ms := 1;
3385 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
3386 if (dl_block.data_egprs.mcs > MCS_4) {
3387 setverdict(fail, "Signalling USF ", dl_block.data_egprs.mac_hdr.usf, " for GPRS-only MS using MCS > 4: ", dl_block);
3388 f_shutdown(__BFILE__, __LINE__);
3389 }
3390 ms_egprs_usf_count[0] := ms_egprs_usf_count[0] + 1;
3391 } else {
3392 if (dl_block.data_egprs.mcs <= MCS_4) {
3393 setverdict(fail, "Using too-low MCS for EGPRS MS: ", dl_block.data_egprs.mcs);
3394 f_shutdown(__BFILE__, __LINE__);
3395 }
3396 if (match(dl_block.data_egprs.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
3397 ms_egprs_usf_count[1] := ms_egprs_usf_count[1] + 1;
3398 }
3399 }
3400 } else {
3401 if (not match(dl_block.data.mac_hdr.hdr_ext.tfi, g_ms[0].dl_tbf.tfi)) {
3402 setverdict(fail, "GPRS DL DATA not matching GPRS MS TFI (", g_ms[0].dl_tbf.tfi, "): ", dl_block.data.mac_hdr.hdr_ext.tfi);
3403 f_shutdown(__BFILE__, __LINE__);
3404 }
3405 tgt_ms := 0;
3406 if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[0].ul_tbf.usf[7])) {
3407 ms_gprs_usf_count[0] := ms_gprs_usf_count[0] + 1;
3408 } else if (match(dl_block.data.mac_hdr.mac_hdr.usf, g_ms[1].ul_tbf.usf[7])) {
3409 ms_gprs_usf_count[1] := ms_gprs_usf_count[1] + 1;
3410 }
3411 }
3412
3413 /* Keep Ack/Nack description updated */
3414 f_dltbf_ack_block(g_ms[tgt_ms].dl_tbf, dl_block);
3415
3416 /* TDMA frame number on which we are supposed to send the ACK */
3417 if (f_dl_block_rrbp_valid(dl_block)) {
3418 ack_fn := f_dl_block_ack_fn(dl_block, dl_fn);
3419 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);
3420 if (tx_data_remain != 0) {
3421 /* Submit more data from time to time to keep the TBF ongoing */
3422 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[0].tlli, data));
3423 BSSGP[0].send(ts_BSSGP_DL_UD(g_ms[1].tlli, data));
3424 tx_data_remain := tx_data_remain - 1;
3425 }
3426 }
3427 }
3428
3429 log("results: ms_gprs_usf_count=", ms_gprs_usf_count, " / ms_egprs_usf_count=", ms_egprs_usf_count);
3430 if (ms_gprs_usf_count[0] == 0 or ms_gprs_usf_count[1] == 0 or
3431 ms_egprs_usf_count[0] == 0 or ms_egprs_usf_count[1] == 0) {
3432 setverdict(fail, "USF thresholds not met!");
3433 f_shutdown(__BFILE__, __LINE__);
3434 }
3435
3436 f_shutdown(__BFILE__, __LINE__, final := true);
3437}
3438
3439
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07003440private function f_TC_paging_cs_multi_ms(template (value) TsTrxBtsNum nr,
3441 boolean exp_imsi, boolean exp_tmsi)
3442runs on RAW_PCU_Test_CT {
3443 var bitstring mask := f_pad_bit(''B, lengthof(g_ms), '0'B);
3444 var integer pending := lengthof(g_ms);
3445 var RlcmacDlBlock dl_block;
3446 var boolean f1, f2;
3447
3448 while (pending > 0) {
3449 var uint32_t poll_fn;
3450
3451 /* Obtain a Downlink block and make sure it is a paging request */
3452 f_rx_rlcmac_dl_block(dl_block, poll_fn, nr := nr);
3453 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ)) {
3454 setverdict(fail, "Rx unexpected DL block: ", dl_block);
3455 break;
3456 }
3457
3458 /* This should not happen in general, but who knows... */
3459 var PacketPagingReq req := dl_block.ctrl.payload.u.paging;
3460 if (not ispresent(req.repeated_pageinfo)) {
3461 setverdict(fail, "Repeated Page Info IE is absent?!?");
3462 break;
3463 }
3464
3465 /* A single message may contain several MIs depending on their type */
3466 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
3467 f1 := exp_imsi and f_pkt_paging_match_imsi(req, g_ms[i].imsi,
3468 ps_domain := false);
3469 f2 := exp_tmsi and f_pkt_paging_match_tmsi(req, oct2int(g_ms[i].tlli),
3470 ps_domain := false);
3471 if (not f1 and not f2)
3472 { continue; }
3473
3474 /* Detect duplicate MIs */
3475 if (mask[i] == '1'B) {
3476 setverdict(fail, "MS is paged twice: ", g_ms[i].imsi);
3477 continue;
3478 }
3479
3480 mask[i] := '1'B;
3481 }
3482
3483 pending := pending - lengthof(req.repeated_pageinfo);
3484 }
3485
3486 for (var integer i := 0; i < lengthof(mask); i := i + 1) {
3487 if (mask[i] != '1'B) {
3488 setverdict(fail, "MS was not paged at all: ", g_ms[i].imsi);
3489 log("===== mask := ", mask);
3490 }
3491 }
3492
3493 /* All messages must have been received by now, expect a dummy block */
3494 f_rx_rlcmac_dl_block_exp_dummy(dl_block, nr := nr);
3495}
3496
3497private function f_TC_paging_cs_multi_ms_init(BIT8 pdch_mask)
3498runs on RAW_PCU_Test_CT {
3499 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3500 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
3501
3502 /* Initialize NS/BSSGP side */
3503 f_init_bssgp();
3504
3505 /* Explicitly set the given PDCH slot-mask to all transceivers */
3506 f_PCUIF_ver_INFO_PDCHMask_set(info_ind, pdch_mask);
3507
3508 /* Allocate 56 GprsMS instances (maximum for 8 PDCH slots) */
3509 f_init_gprs_ms(7 * 8);
3510
3511 /* Initialize the PCU interface abstraction */
3512 f_init_raw(testcasename(), info_ind);
3513
3514 /* Establish BSSGP connection to the PCU */
3515 f_bssgp_establish();
3516 f_multi_ms_bssgp_register();
3517
3518 /* Establish an Uplink TBF for each GprsMS instance */
3519 f_multi_ms_establish_tbf(do_activate := true);
3520}
3521
3522testcase TC_paging_cs_multi_ms_imsi() runs on RAW_PCU_Test_CT {
3523 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
3524
3525 /* Common part: send INFO.ind, establish TBFs... */
3526 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
3527
3528 /* Enqueue multiple CS PAGING requests at a time (IMSI only) */
3529 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
3530 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
3531 }
3532
3533 /* FIXME: work around a race condition between PCUIF and BSSGP */
3534 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
3535
3536 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
3537 * The IUT is expected to page on all PDCH slots of all transceivers. */
3538 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
3539 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
3540 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := false);
3541 }
3542
3543 f_shutdown(__BFILE__, __LINE__, final := true);
3544}
3545
3546testcase TC_paging_cs_multi_ms_tmsi() runs on RAW_PCU_Test_CT {
3547 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
3548
3549 /* Common part: send INFO.ind, establish TBFs... */
3550 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
3551
3552 /* Enqueue multiple CS PAGING requests at a time (P-TMSI only) */
3553 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
3554 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
3555 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
3556 }
3557
3558 /* FIXME: work around a race condition between PCUIF and BSSGP */
3559 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
3560
3561 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
3562 * The IUT is expected to page on all PDCH slots of all transceivers. */
3563 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
3564 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
3565 f_TC_paging_cs_multi_ms(nr, exp_imsi := false, exp_tmsi := true);
3566 }
3567
3568 f_shutdown(__BFILE__, __LINE__, final := true);
3569}
3570
3571testcase TC_paging_cs_multi_ms_imsi_tmsi() runs on RAW_PCU_Test_CT {
3572 const BssgpBvci bvci := mp_gb_cfg.bvc[0].bvci;
3573
3574 /* Common part: send INFO.ind, establish TBFs... */
3575 f_TC_paging_cs_multi_ms_init(pdch_mask := '00000001'B);
3576
3577 /* Enqueue multiple CS PAGING requests at a time (IMSI & P-TMSI) */
3578 for (var integer i := 0; i < lengthof(g_ms); i := i + 1) {
3579 var GsmTmsi tmsi := oct2int(g_ms[i].tlli); /* P-TMSI == TLLI */
3580 if (i mod 3 == 0) { /* One PDU fits: 1 IMSI and 2 P-TMSI MIs */
3581 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, g_ms[i].imsi, tmsi));
3582 } else {
3583 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, g_ms[i].imsi));
3584 }
3585 }
3586
3587 /* FIXME: work around a race condition between PCUIF and BSSGP */
3588 f_sleep(0.2); /* i.e. give the IUT some time to process everything */
3589
3590 /* Check what the IUT sends on PACCH, all GprsMS instances must be paged.
3591 * The IUT is expected to page on all PDCH slots of all transceivers. */
3592 for (var integer trx_nr := 0; trx_nr < 8; trx_nr := trx_nr + 1) {
3593 var template (value) TsTrxBtsNum nr := ts_TsTrxBtsNum(7, trx_nr);
3594 f_TC_paging_cs_multi_ms(nr, exp_imsi := true, exp_tmsi := true);
3595 }
3596
3597 f_shutdown(__BFILE__, __LINE__, final := true);
3598}
3599
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003600private function f_skip_dummy(integer max_num_iter)
3601runs on RAW_PCU_Test_CT return RlcmacDlBlock {
3602 var RlcmacDlBlock dl_block;
3603 var uint32_t sched_fn;
3604 var integer i := 0;
3605 while (true) {
3606 f_rx_rlcmac_dl_block(dl_block, sched_fn);
3607 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
3608 break;
3609 }
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01003610 if (max_num_iter > 0 and i > max_num_iter) {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003611 setverdict(fail, "Rx unexpected DL block: ", dl_block);
3612 f_shutdown(__BFILE__, __LINE__);
3613 }
3614 i := i + 1;
3615 }
3616 return dl_block;
3617}
3618
3619/* Handle groups of PKT NEIGHBOUR CELL DATA packets */
3620private function f_handle_pkt_neighbor_cell_data(inout GprsMS ms, octetstring exp_si)
3621runs on RAW_PCU_Test_CT {
3622 var RlcmacDlBlock dl_block;
3623 var uint32_t sched_fn;
3624 var integer i := 0;
3625 var uint5_t exp_container_idx := 0;
3626 var integer si_offset := 0;
3627 var integer len;
3628 var octetstring exp_si_chunk;
3629 var GlobalTfi gtfi := { is_dl_tfi := false, tfi := ms.ul_tbf.tfi };
3630
3631 dl_block := f_skip_dummy(50);
3632
3633 while (true) {
3634 var template RlcmacDlCtrlMsg exp_msg; exp_msg :=
3635 tr_RlcMacDlCtrl_PKT_NEIGH_CELL_DATA(gtfi, exp_container_idx);
3636
3637 /* Make sure last Dl block is a Pkt Neighbour Cell Data */
3638 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, exp_msg))) {
3639 setverdict(fail, "Rx unexpected DL block: ", dl_block, " vs exp ", tr_RLCMAC_DL_CTRL(?, exp_msg));
3640 f_shutdown(__BFILE__, __LINE__);
3641 }
3642 var PacketNeighbourCellData neigh_data := dl_block.ctrl.payload.u.neighbour_cell_data;
3643 var PacketNeighbourCellDataContainer cont := neigh_data.container_list[0];
3644
3645 if (cont.cd_length == 31) { /* continues on next message */
3646 len := lengthof(cont.container_data);
3647 exp_si_chunk := substr(exp_si, si_offset, len);
3648 if (cont.container_data != exp_si_chunk) {
3649 setverdict(fail, "Rx unexpected SI chunk at offset ", si_offset, ": ",
3650 cont.container_data, " vs exp ", exp_si_chunk);
3651 f_shutdown(__BFILE__, __LINE__);
3652 }
3653 si_offset := si_offset + len;
3654 } else if (cont.cd_length == 0) {
3655 /* we are done */
3656 if (si_offset != lengthof(exp_si)) {
3657 setverdict(fail, "Rx unexpectd SI length ", si_offset,
3658 " vs exp ", lengthof(exp_si));
3659 f_shutdown(__BFILE__, __LINE__);
3660 }
3661 break;
3662 } else { /* data length, last message */
3663 len := cont.cd_length;
3664 exp_si_chunk := substr(exp_si, si_offset, len);
3665 if (cont.container_data != exp_si_chunk) {
3666 setverdict(fail, "Rx unexpected SI chunk at offset ", si_offset, ": ",
3667 cont.container_data, " vs exp ", exp_si_chunk);
3668 f_shutdown(__BFILE__, __LINE__);
3669 return;
3670 }
3671 si_offset := si_offset + len;
3672 /* we are done */
3673 if (si_offset != lengthof(exp_si)) {
3674 setverdict(fail, "Rx unexpectd SI length ", si_offset,
3675 " vs exp ", lengthof(exp_si));
3676 f_shutdown(__BFILE__, __LINE__);
3677 }
3678 break;
3679 }
3680
3681 exp_container_idx := exp_container_idx + 1;
3682 f_rx_rlcmac_dl_block(dl_block, sched_fn);
3683 }
3684 return;
3685}
3686
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003687/* Start NACC from MS side */
3688private function f_outbound_nacc_success(inout GprsMS ms, PCUIF_info_ind info_ind,
3689 boolean exp_rac_ci_query := true, boolean exp_si_query := true)
3690runs on RAW_PCU_Test_CT {
3691 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
3692 var RlcmacDlBlock dl_block;
3693 var uint32_t sched_fn;
3694 var GsmArfcn req_arfcn := 862;
3695 var uint6_t req_bsic := 43;
3696
3697 /* Start NACC from MS side */
3698 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
3699 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
3700
3701 if (exp_rac_ci_query == true) {
3702 /* osmo-pcu should now ask for resolution: */
3703 f_ipa_ctrl_wait_link_up();
3704 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
3705 int2str(info_ind.lac) & "." &
3706 int2str(info_ind.cell_id) & "." &
3707 int2str(req_arfcn) & "." &
3708 int2str(req_bsic);
3709 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
3710 }
3711
3712 if (exp_si_query == true) {
3713 /* RIM procedure: */
3714 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 */
3715 info_ind.lac),
3716 info_ind.rac),
3717 info_ind.cell_id));
3718 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
3719 423),
3720 2),
3721 5));
3722 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
3723 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
3724 var template RAN_Information_RIM_Container res_cont;
3725 res_cont := ts_RAN_Information_RIM_Container(ts_RIM_Application_Identity(RIM_APP_ID_NACC),
3726 ts_RIM_Sequence_Number(2),
3727 ts_RIM_PDU_Indications(false, RIM_PDU_TYPE_SING_REP),
3728 ts_RIM_Protocol_Version_Number(1),
3729 tsu_ApplContainer_or_ApplErrContainer_NACC(tsu_ApplContainer_NACC(dst, false, 3, si_default)),
3730 omit);
3731 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3732 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3733 tr_RAN_Information_Request_RIM_Container));
3734 RIM.send(ts_PDU_BSSGP_RAN_INFORMATION(ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
3735 ts_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
3736 res_cont));
3737 }
3738
3739 /* Announce SI back to MS, continue NACC procedure */
3740 f_handle_pkt_neighbor_cell_data(ms, si_default);
3741
3742 /* Obtain a Downlink block and make sure it is a Pkt Cell Chg Continue */
3743 f_rx_rlcmac_dl_block(dl_block, sched_fn);
3744 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
3745 setverdict(fail, "Rx unexpected DL block: ", dl_block);
3746 f_shutdown(__BFILE__, __LINE__);
3747 }
3748
3749}
3750
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003751/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8). */
3752testcase TC_nacc_outbound_success() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003753 var PollFnCtx pollctx;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003754 var GprsMS ms;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003755 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3756 var MultislotCap_GPRS mscap_gprs := {
3757 gprsmultislotclass := '00011'B,
3758 gprsextendeddynalloccap := '0'B
3759 };
3760 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003761
3762 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
3763 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
3764
3765 /* Initialize NS/BSSGP side */
3766 f_init_bssgp();
3767 /* Initialize GPRS MS side */
3768 f_init_gprs_ms();
3769 ms := g_ms[0]; /* We only use first MS in this test */
3770
3771 /* Initialize the PCU interface abstraction */
3772 f_init_raw(testcasename(), info_ind);
3773
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003774 /* Make sure we are not affected by full cache from previous tests */
3775 f_pcuvty_flush_neigh_caches();
3776
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003777 /* Establish BSSGP connection to the PCU */
3778 f_bssgp_establish();
3779 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3780
3781 /* Send PACKET RESOURCE REQUEST */
3782 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3783 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3784 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3785
3786 /* Start NACC from MS side */
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003787 f_outbound_nacc_success(ms, info_ind);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003788
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003789 f_shutdown(__BFILE__, __LINE__, final := true);
3790}
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003791
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003792/* Verify PCU handles outbound Network Assisted Cell Change Cell Change (NACC, TS 44.060 sec 8.8) twice, the second time using the caches */
3793testcase TC_nacc_outbound_success_twice() runs on RAW_PCU_Test_CT {
3794 var PollFnCtx pollctx;
3795 var GprsMS ms;
3796 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3797 var MultislotCap_GPRS mscap_gprs := {
3798 gprsmultislotclass := '00011'B,
3799 gprsextendeddynalloccap := '0'B
3800 };
3801 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3802 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003803
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003804 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
3805 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003806
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003807 /* Initialize NS/BSSGP side */
3808 f_init_bssgp();
3809 /* Initialize GPRS MS side */
3810 f_init_gprs_ms();
3811 ms := g_ms[0]; /* We only use first MS in this test */
3812
3813 /* Initialize the PCU interface abstraction */
3814 f_init_raw(testcasename(), info_ind);
3815
3816 /* Make sure we are not affected by full cache from previous tests */
3817 f_pcuvty_flush_neigh_caches();
3818 /* Set timeout values for caches so that entries will be in cache during second try */
3819 f_pcuvty_set_neigh_caches(10, 10);
3820
3821 /* Establish BSSGP connection to the PCU */
3822 f_bssgp_establish();
3823 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3824
3825 /* Send PACKET RESOURCE REQUEST */
3826 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3827 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3828 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3829
3830 /* Start NACC from MS side */
3831 f_outbound_nacc_success(ms, info_ind);
3832
3833 /* First NACC procedure is done, let's try to start a new one now that previous queries are cached: */
3834 f_outbound_nacc_success(ms, info_ind, false, false);
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01003835
3836 f_shutdown(__BFILE__, __LINE__, final := true);
3837}
3838
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01003839/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01003840testcase TC_nacc_outbound_rac_ci_resolve_conn_refused() runs on RAW_PCU_Test_CT {
3841 var RlcmacDlBlock dl_block;
3842 var PollFnCtx pollctx;
3843 var uint32_t sched_fn;
3844 var GprsMS ms;
3845 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
3846 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3847 var MultislotCap_GPRS mscap_gprs := {
3848 gprsmultislotclass := '00011'B,
3849 gprsextendeddynalloccap := '0'B
3850 };
3851 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3852 var GsmArfcn req_arfcn := 862;
3853 var uint6_t req_bsic := 43;
3854
3855 /* In here we explicitly avoid starting osmo-bsc emulation neighbor
3856 * resolution CTRL port, to trigger Conn Refused by socket:
3857 * f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
3858 */
3859
3860 /* Initialize NS/BSSGP side */
3861 f_init_bssgp();
3862 /* Initialize GPRS MS side */
3863 f_init_gprs_ms();
3864 ms := g_ms[0]; /* We only use first MS in this test */
3865
3866 /* Initialize the PCU interface abstraction */
3867 f_init_raw(testcasename(), info_ind);
3868
3869 /* Make sure we are not affected by full cache from previous tests */
3870 f_pcuvty_flush_neigh_caches();
3871
3872 /* Establish BSSGP connection to the PCU */
3873 f_bssgp_establish();
3874 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3875
3876 /* Send PACKET RESOURCE REQUEST */
3877 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3878 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3879 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3880
3881 /* Start NACC from MS side */
3882 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
3883 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
3884
3885 /* Wait until we receive something non-dummy */
3886 dl_block := f_skip_dummy(0);
3887 /* Make sure it is a Pkt Cell Chg Continue */
3888 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
3889 setverdict(fail, "Rx unexpected DL block: ", dl_block);
3890 }
3891
3892 f_shutdown(__BFILE__, __LINE__, final := true);
3893}
3894
3895/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01003896testcase TC_nacc_outbound_rac_ci_resolve_timeout() runs on RAW_PCU_Test_CT {
3897 var RlcmacDlBlock dl_block;
3898 var PollFnCtx pollctx;
3899 var uint32_t sched_fn;
3900 var GprsMS ms;
3901 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
3902 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3903 var MultislotCap_GPRS mscap_gprs := {
3904 gprsmultislotclass := '00011'B,
3905 gprsextendeddynalloccap := '0'B
3906 };
3907 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3908 var GsmArfcn req_arfcn := 862;
3909 var uint6_t req_bsic := 43;
3910
3911 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
3912 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
3913
3914 /* Initialize NS/BSSGP side */
3915 f_init_bssgp();
3916 /* Initialize GPRS MS side */
3917 f_init_gprs_ms();
3918 ms := g_ms[0]; /* We only use first MS in this test */
3919
3920 /* Initialize the PCU interface abstraction */
3921 f_init_raw(testcasename(), info_ind);
3922
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003923 /* Make sure we are not affected by full cache from previous tests */
3924 f_pcuvty_flush_neigh_caches();
3925
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01003926 /* Establish BSSGP connection to the PCU */
3927 f_bssgp_establish();
3928 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3929
3930 /* Send PACKET RESOURCE REQUEST */
3931 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3932 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3933 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3934
3935 /* Start NACC from MS side */
3936 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
3937 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
3938
3939 /* osmo-pcu should now ask for resolution: */
3940 f_ipa_ctrl_wait_link_up();
3941 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
3942 int2str(info_ind.lac) & "." &
3943 int2str(info_ind.cell_id) & "." &
3944 int2str(req_arfcn) & "." &
3945 int2str(req_bsic);
3946 /* we receive RAC+CI resolution request, but we never answer to it, timeout should occur */
3947 f_ctrl_exp_get(IPA_CTRL, ctrl_var, omit);
3948
3949 /* Wait until we receive something non-dummy */
3950 dl_block := f_skip_dummy(0);
3951 /* Make sure it is a Pkt Cell Chg Continue */
3952 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
3953 setverdict(fail, "Rx unexpected DL block: ", dl_block);
3954 }
3955
3956 f_shutdown(__BFILE__, __LINE__, final := true);
3957}
3958
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01003959/* Verify PCU transmits Pkt Cell Change Continue if RAC+CI resolution fails during outbound NACC procedure */
3960testcase TC_nacc_outbound_rac_ci_resolve_fail_parse_response() runs on RAW_PCU_Test_CT {
3961 var RlcmacDlBlock dl_block;
3962 var PollFnCtx pollctx;
3963 var uint32_t sched_fn;
3964 var GprsMS ms;
3965 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
3966 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
3967 var MultislotCap_GPRS mscap_gprs := {
3968 gprsmultislotclass := '00011'B,
3969 gprsextendeddynalloccap := '0'B
3970 };
3971 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
3972 var GsmArfcn req_arfcn := 862;
3973 var uint6_t req_bsic := 43;
3974
3975 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
3976 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
3977
3978 /* Initialize NS/BSSGP side */
3979 f_init_bssgp();
3980 /* Initialize GPRS MS side */
3981 f_init_gprs_ms();
3982 ms := g_ms[0]; /* We only use first MS in this test */
3983
3984 /* Initialize the PCU interface abstraction */
3985 f_init_raw(testcasename(), info_ind);
3986
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01003987 /* Make sure we are not affected by full cache from previous tests */
3988 f_pcuvty_flush_neigh_caches();
3989
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01003990 /* Establish BSSGP connection to the PCU */
3991 f_bssgp_establish();
3992 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
3993
3994 /* Send PACKET RESOURCE REQUEST */
3995 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
3996 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
3997 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
3998
3999 /* Start NACC from MS side */
4000 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4001 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4002
4003 /* osmo-pcu should now ask for resolution: */
4004 f_ipa_ctrl_wait_link_up();
4005 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4006 int2str(info_ind.lac) & "." &
4007 int2str(info_ind.cell_id) & "." &
4008 int2str(req_arfcn) & "." &
4009 int2str(req_bsic);
4010 /* we receive RAC+CI resolution request and we send incorrectlt formated response */
4011 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "foobar-error");
4012
4013 /* Wait until we receive something non-dummy */
4014 dl_block := f_skip_dummy(0);
4015 /* Make sure it is a Pkt Cell Chg Continue */
4016 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4017 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4018 }
4019
4020 f_shutdown(__BFILE__, __LINE__, final := true);
4021}
4022
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004023/* Verify PCU transmits Pkt Cell Change Continue if SI resolution fails during outbound NACC procedure */
4024testcase TC_nacc_outbound_si_resolve_timeout() runs on RAW_PCU_Test_CT {
4025 var RlcmacDlBlock dl_block;
4026 var PollFnCtx pollctx;
4027 var uint32_t sched_fn;
4028 var GprsMS ms;
4029 var template (value) RlcmacUlCtrlMsg cell_chf_notif;
4030 var PCUIF_info_ind info_ind := valueof(ts_PCUIF_INFO_default);
4031 var MultislotCap_GPRS mscap_gprs := {
4032 gprsmultislotclass := '00011'B,
4033 gprsextendeddynalloccap := '0'B
4034 };
4035 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
4036 var GsmArfcn req_arfcn := 862;
4037 var uint6_t req_bsic := 43;
4038 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 */
4039 info_ind.lac),
4040 info_ind.rac),
4041 info_ind.cell_id));
4042 var BssgpCellId dst := valueof(ts_BssgpCellId(ts_RAI(ts_LAI('023F43'H, /* Decided by test itself (emulating BSC) */
4043 423),
4044 2),
4045 5));
4046 var template RIM_Routing_Address src_addr := t_RIM_Routing_Address_cid(src);
4047 var template RIM_Routing_Address dst_addr := t_RIM_Routing_Address_cid(dst);
4048
4049 /* Initialize osmo-bsc emulation neighbor resolution CTRL port */
4050 f_ipa_ctrl_start_server(mp_ctrl_neigh_ip, mp_ctrl_neigh_port);
4051
4052 /* Initialize NS/BSSGP side */
4053 f_init_bssgp();
4054 /* Initialize GPRS MS side */
4055 f_init_gprs_ms();
4056 ms := g_ms[0]; /* We only use first MS in this test */
4057
4058 /* Initialize the PCU interface abstraction */
4059 f_init_raw(testcasename(), info_ind);
4060
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004061 /* Make sure we are not affected by full cache from previous tests */
4062 f_pcuvty_flush_neigh_caches();
4063
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004064 /* Establish BSSGP connection to the PCU */
4065 f_bssgp_establish();
4066 f_bssgp_client_llgmm_assign(TLLI_UNUSED, ms.tlli);
4067
4068 /* Send PACKET RESOURCE REQUEST */
4069 pollctx := f_ms_establish_ul_tbf_2phase_access(ms, ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap));
4070 /* Pkt Uplink Assignment above sets poll+rrbp requesting PACKET CONTROL ACK */
4071 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), pollctx.fn, nr := pollctx.tstrxbts);
4072
4073 /* Start NACC from MS side */
4074 cell_chf_notif := ts_RlcMacUlCtrl_PKT_CELL_CHG_NOTIF(ms.ul_tbf.tfi, req_arfcn, req_bsic);
4075 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(cell_chf_notif), 0, nr := f_ms_tx_TsTrxBtsNum(ms));
4076
4077 /* osmo-pcu should now ask for resolution: */
4078 f_ipa_ctrl_wait_link_up();
4079 var charstring ctrl_var := "neighbor_resolve_cgi_ps_from_lac_ci." &
4080 int2str(info_ind.lac) & "." &
4081 int2str(info_ind.cell_id) & "." &
4082 int2str(req_arfcn) & "." &
4083 int2str(req_bsic);
4084 f_ctrl_exp_get(IPA_CTRL, ctrl_var, "023-43-423-2-5");
4085
4086 /* RIM procedure: */
4087 RIM.receive(tr_RAN_INFORMATION_REQUEST(tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, dst_addr),
4088 tr_RIM_Routing_Information(RIM_ADDR_GERAN_CELL_ID, src_addr),
4089 tr_RAN_Information_Request_RIM_Container));
4090 /* We never answer the RIM procude -> PCU timeouts and should send Pkt Cell Chg continue */
4091
4092 /* Wait until we receive something non-dummy */
4093 dl_block := f_skip_dummy(0);
4094 /* Make sure it is a Pkt Cell Chg Continue */
4095 if (not match(dl_block, tr_RLCMAC_DL_CTRL(?, tr_RlcMacDlCtrl_PKT_CELL_CHG_CONTINUE))) {
4096 setverdict(fail, "Rx unexpected DL block: ", dl_block);
4097 }
4098
4099 f_shutdown(__BFILE__, __LINE__, final := true);
4100}
4101
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004102control {
4103 execute( TC_pcuif_suspend() );
Pau Espin Pedrol9e04d5e2021-01-11 15:03:50 +01004104 execute( TC_pcuif_suspend_active_tbf() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004105 execute( TC_ta_ptcch_idle() );
4106 execute( TC_ta_rach_imm_ass() );
4107 execute( TC_ta_idle_dl_tbf_ass() );
4108 execute( TC_ta_ptcch_ul_multi_tbf() );
4109 execute( TC_cs_lqual_ul_tbf() );
4110 execute( TC_cs_initial_ul() );
4111 execute( TC_cs_max_ul() );
Pau Espin Pedrol75122592020-11-03 15:22:59 +01004112 execute( TC_cs_initial_dl() );
Pau Espin Pedrol5d07ae62020-11-05 17:59:30 +01004113 execute( TC_cs_max_dl() );
4114 execute( TC_dl_cs1_to_cs4() );
Pau Espin Pedrol2354d6a2020-11-05 18:36:59 +01004115 execute( TC_mcs_initial_ul() );
Pau Espin Pedroldb15fa72020-11-11 12:58:34 +01004116 execute( TC_mcs_max_ul() );
Pau Espin Pedrole4fa45b2020-11-11 13:28:31 +01004117 execute( TC_mcs_initial_dl() );
Pau Espin Pedrol1b9aa782020-11-12 21:14:16 +01004118 execute( TC_mcs_max_dl() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004119 execute( TC_t3169() );
4120 execute( TC_t3193() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02004121 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02004122 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02004123 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004124 execute( TC_mo_ping_pong() );
4125 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02004126 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004127 execute( TC_mt_ping_pong() );
4128 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02004129 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004130 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07004131 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02004132 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004133 execute( TC_paging_cs_from_bts() );
4134 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
4135 execute( TC_paging_cs_from_sgsn_sign() );
4136 execute( TC_paging_cs_from_sgsn_ptp() );
4137 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
4138 execute( TC_paging_ps_from_sgsn_sign() );
4139 execute( TC_paging_ps_from_sgsn_ptp() );
Vadim Yanitskiydbd4b242020-10-31 05:44:58 +07004140 execute( TC_paging_cs_multi_ms_imsi_tmsi() );
4141 execute( TC_paging_cs_multi_ms_imsi() );
4142 execute( TC_paging_cs_multi_ms_tmsi() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02004143 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
4144 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol2e459d62020-11-30 19:34:16 +01004145 execute( TC_dl_gprs_data_no_llc_ui_dummy() );
4146 execute( TC_dl_egprs_data_no_llc_ui_dummy() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004147
4148 /* EGPRS specific test cases */
4149 execute( TC_egprs_pkt_chan_req_signalling() );
4150 execute( TC_egprs_pkt_chan_req_one_phase() );
4151 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07004152 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07004153 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07004154 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02004155
4156 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004157
4158 /* Frequency hopping specific test cases */
4159 if (PCUIF_Types.mp_pcuif_version >= 10) {
4160 /* Immediate Assignment on AGCH/PCH */
4161 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
4162 execute( TC_pcuif_fh_imm_ass_ul() );
4163 execute( TC_pcuif_fh_imm_ass_dl() );
4164 /* Packet Uplink/Downlink Assignment on PACCH */
4165 execute( TC_pcuif_fh_pkt_ass_ul() );
4166 execute( TC_pcuif_fh_pkt_ass_dl() );
Pau Espin Pedrolbfd69f62020-10-22 18:06:07 +02004167 execute( TC_multitrx_multims_alloc() );
Pau Espin Pedrol0ea8b6f2020-10-29 20:48:43 +01004168 execute( TC_dl_multislot_tbf_ms_class_from_sgsn() );
Pau Espin Pedrol8155bf42020-10-29 17:34:26 +01004169 execute( TC_dl_multislot_tbf_ms_class_from_2phase() );
Pau Espin Pedrola9f27fa2020-10-30 13:16:21 +01004170 execute( TC_ul_multislot_tbf_ms_class_from_2phase() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07004171 }
Pau Espin Pedrole1303052020-11-16 11:13:51 +01004172 execute( TC_multiplex_dl_gprs_egprs() );
Vadim Yanitskiyd53fb672020-10-09 16:41:02 +07004173
4174 execute( TC_pcuif_info_ind_subsequent() );
Pau Espin Pedrol0637ba02021-01-22 18:36:12 +01004175 execute( TC_nacc_outbound_success() );
Pau Espin Pedrol43be4252021-01-27 16:40:54 +01004176 execute( TC_nacc_outbound_success_twice() );
Pau Espin Pedrole51c17a2021-01-27 18:29:22 +01004177 execute( TC_nacc_outbound_rac_ci_resolve_conn_refused() );
Pau Espin Pedrol31e30642021-01-26 19:25:16 +01004178 execute( TC_nacc_outbound_rac_ci_resolve_timeout() );
Pau Espin Pedrol4b5227c2021-01-26 20:03:01 +01004179 execute( TC_nacc_outbound_rac_ci_resolve_fail_parse_response() );
Pau Espin Pedrol9076ee72021-01-26 19:38:26 +01004180 execute( TC_nacc_outbound_si_resolve_timeout() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02004181}
4182
Harald Weltea419df22019-03-21 17:23:04 +01004183}