blob: fb59c138b793297441e39a71c855d33a8c760c73 [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
54modulepar {
55 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
56
57 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
58}
59
60
61/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
62private template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
63 version := PCU_IF_VERSION,
64 flags := c_PCUIF_Flags_default,
65 trx := valueof(ts_PCUIF_InfoTrxs_def),
66 bsic := 7,
67 mcc := 262,
68 mnc := 42,
69 mnc_3_digits := 0,
70 lac := 13135,
71 rac := 0,
72 nsei := mp_nsconfig.nsei,
73 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
74 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
75 cell_id := 20960,
76 repeat_time := 5 * 50,
77 repeat_count := 3,
78 bvci := mp_gb_cfg.bvci,
79 t3142 := 20,
80 t3169 := 5,
81 t3191 := 5,
82 t3193_10ms := 160,
83 t3195 := 5,
84 t3101 := 10,
85 t3103 := 4,
86 t3105 := 8,
87 cv_countdown := 15,
88 dl_tbf_ext := 250 * 10, /* ms */
89 ul_tbf_ext := 250 * 10, /* ms */
90 initial_cs := 2,
91 initial_mcs := 6,
92 nsvci := { mp_nsconfig.nsvci, 0 },
93 local_pprt := { mp_nsconfig.remote_udp_port, 0 },
94 remote_port := { mp_nsconfig.local_udp_port, 0 },
95 remote_ip := { f_inet_haddr(mp_nsconfig.local_ip) , '00000000'O }
96}
97
98type record lqual_range {
99 /* component reference to the IPA_Client component used for RSL */
100 uint8_t low,
101 uint8_t high
102}
103
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +0200104type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700105 /* PCU interface abstraction component */
106 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700107
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200108 /* Connection to the PCUIF component */
109 port RAW_PCU_MSG_PT PCUIF;
110 /* VTY connection to the PCU */
111 port TELNETasp_PT PCUVTY;
112
113 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
114 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
115 {low := 5, high := 8},
116 {low := 7, high := 13},
117 {low := 12,high := 35}};
118 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
119 {low := 5, high := 8},
120 {low := 7, high := 13},
121 {low := 12,high := 15},
122 {low := 14, high := 17},
123 {low := 16, high := 18},
124 {low := 17,high := 20},
125 {low := 19, high := 24},
126 {low := 23,high := 35}};
127 var uint8_t g_cs_initial_dl := 1;
128 var uint8_t g_cs_initial_ul := 1;
129 var uint8_t g_mcs_initial_dl := 1;
130 var uint8_t g_mcs_initial_ul := 1;
131 var uint8_t g_cs_max_dl := 4;
132 var uint8_t g_cs_max_ul := 4;
133 var uint8_t g_mcs_max_dl := 9;
134 var uint8_t g_mcs_max_ul := 9;
135
136 var boolean g_egprs_only := false;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200137 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200138
139 /* Guard timeout */
140 timer g_T_guard := 60.0;
141};
142
143private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
144 [] g_T_guard.timeout {
145 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700146 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200147 }
148}
149
150private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
151 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
152 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
153
154 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
155 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
156}
157
158private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
159 var charstring cmd;
160
161 cmd := "cs link-quality-ranges" &
162 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
163 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
164 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
165 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
166 f_vty_config2(PCUVTY, {"pcu"}, cmd);
167
168 cmd := "mcs link-quality-ranges" &
169 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
170 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
171 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
172 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
173 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
174 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
175 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
176 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
177 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
178 f_vty_config2(PCUVTY, {"pcu"}, cmd);
179}
180
181private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
182 map(self:PCUVTY, system:PCUVTY);
183 f_vty_set_prompts(PCUVTY);
184 f_vty_transceive(PCUVTY, "enable");
185
186 if (g_egprs_only) {
187 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
188 } else {
189 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
190 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200191
192 if (g_force_two_phase_access) {
193 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
194 } else {
195 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
196 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200197}
198
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200199function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200200runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200201 /* Start the guard timer */
202 g_T_guard.start;
203 activate(as_Tguard_RAW());
204
205 /* Init PCU interface component */
206 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
207 connect(vc_PCUIF:MTC, self:PCUIF);
208 map(vc_PCUIF:PCU, system:PCU);
209
210 /* Create one BTS component (we may want more some day) */
211 vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
212 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
213 connect(vc_BTS:TC, self:BTS);
214
215 f_init_vty(id);
216
217 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
218 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
219
220 /* Wait until the BTS is ready (SI13 negotiated) */
221 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
222}
223
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200224testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
225 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
226 var GprsTlli tlli := 'FFFFFFFF'O;
227 timer T;
228
229 /* Initialize NS/BSSGP side */
230 f_init_bssgp();
231
232 /* Initialize the PCU interface abstraction */
233 f_init_raw(testcasename());
234
235 /* Establish BSSGP connection to the PCU */
236 f_bssgp_establish();
237
238 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
239
240 T.start(2.0);
241 alt {
242 [] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
243 setverdict(pass);
244 }
245 [] T.timeout {
246 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
247 }
248 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700249
250 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200251}
252
253/* Test of correct Timing Advance at the time of TBF establishment
254 * (derived from timing offset of the Access Burst). */
255testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
256 var GsmRrMessage rr_msg;
257 var boolean ok;
258
259 /* Initialize the PCU interface abstraction */
260 f_init_raw(testcasename());
261
262 /* We cannot send too many TBF requests in a short time because
263 * at some point the PCU will fail to allocate a new TBF. */
264 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
265 /* Establish an Uplink TBF (send RACH.ind with current TA) */
266 ok := f_establish_tbf(rr_msg, bts_nr := 0, ta := ta);
267 if (not ok) {
268 setverdict(fail, "Failed to establish an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700269 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200270 }
271
272 /* Make sure Timing Advance IE matches out expectations */
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700273 if (rr_msg.payload.imm_ass.timing_advance != ta) {
274 setverdict(fail, "Timing Advance mismatch: ",
275 rr_msg.payload.imm_ass.timing_advance,
276 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700277 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200278 }
279 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700280
281 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200282}
283
284/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
285 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
286 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
287 * no active TBF exists at the moment of establishment (idle mode). */
288testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
289 var OCT4 tlli := f_rnd_octstring(4);
290 var GsmRrMessage rr_imm_ass;
291
292 /* Initialize NS/BSSGP side */
293 f_init_bssgp();
294
295 /* Initialize the PCU interface abstraction */
296 f_init_raw(testcasename());
297
298 /* Establish BSSGP connection to the PCU */
299 f_bssgp_establish();
300 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
301
302 /* SGSN sends some DL data, PCU will initiate Packet Downlink
303 * Assignment on CCCH (PCH). We don't care about the payload. */
304 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
305 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass); // TODO: match by TLLI!
306
307 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
308 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
309 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
310 if (not match(rr_imm_ass, tr_IMM_TBF_ASS(ta := 0))) {
311 setverdict(fail, "Timing Advance value doesn't match");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200312 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700313
314 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200315}
316
317/* Verify that the PCU generates valid PTCCH/D messages
318 * while neither Uplink nor Downlink TBF is established. */
319testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
320 var PTCCHDownlinkMsg ptcch_msg;
321 var PCUIF_Message pcu_msg;
322 timer T;
323
324 /* Initialize the PCU interface abstraction */
325 f_init_raw(testcasename());
326
327 /* Sent an RTS.req for PTCCH/D */
328 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
329 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
330 arfcn := 871, block_nr := 0));
331 T.start(5.0);
332 alt {
333 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
334 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
335 log("Rx DATA.req message: ", pcu_msg);
336 setverdict(pass);
337 }
338 [] BTS.receive(PCUIF_Message:?) { repeat; }
339 [] T.timeout {
340 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700341 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200342 }
343 }
344
345 ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
346 log("Decoded PTCCH/D message: ", ptcch_msg);
347
348 /* Make sure the message is encoded correctly
349 * TODO: do we expect all TA values to be equal '1111111'B? */
350 if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
351 setverdict(fail, "Malformed PTCCH/D message");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200352 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700353
354 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200355}
356
357/* Test of correct Timing Advance during an active Uplink TBF.
358 *
359 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
360 * are not continuous and there can be long time gaps between them. This happens
361 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
362 * significantly change between such rare Uplink transmissions, so GPRS introduces
363 * additional mechanisms to control Timing Advance, and thus reduce interference
364 * between neighboring TDMA time-slots.
365 *
366 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
367 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
368 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
369 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
370 * among with the initial Timing Advance value. And here PTCCH comes to play.
371 *
372 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
373 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
374 * continuously. To ensure continuous measurements of the signal propagation
375 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
376 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
377 *
378 * The purpose of this test case is to verify the assignment of Timing Advance
379 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
380 * first establishes several Uplink TBFs, but does not transmit any Uplink
381 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
382 * indications to the PCU, checking the correctness of two received PTCCH/D
383 * messages (period of PTCCH/D is two multi-frames).
384 */
385
386/* List of ToA values for Access Bursts to be sent on PTCCH/U,
387 * each ToA (Timing of Arrival) value is in units of 1/4 of
388 * a symbol (i.e. 1 symbol is 4 QTA units). */
389type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
390const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
391 0, 0, 0, 0,
392 0, 0, 0, 0,
393 0, 0, 0, 0,
394 0, 0, 0, 0
395};
396
397private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
398 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
399runs on RAW_PCU_Test_CT {
400 var RAW_PCU_Event event;
401 var integer ss;
402
403 /* Send Access Bursts on PTCCH/U for every TA Index */
404 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
405 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700406 if (ss < 0) { /* Shall not happen */
407 f_shutdown(__BFILE__, __LINE__);
408 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200409
410 log("Sending an Access Burst on PTCCH/U",
411 ", sub-slot=", ss, " (TAI)",
412 ", fn=", event.data.tdma_fn,
413 ", ToA=", toa_map[ss], " (QTA)");
414 /* TODO: do we care about RA and burst format? */
415 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
416 ra := oct2int('3A'O),
417 is_11bit := 0,
418 burst_type := BURST_TYPE_0,
419 fn := event.data.tdma_fn,
420 arfcn := 871,
421 qta := toa_map[ss],
422 sapi := PCU_IF_SAPI_PTCCH));
423 repeat;
424 }
425}
426
427private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
428 template PTCCHDownlinkMsg t_ta_msg)
429runs on RAW_PCU_Test_CT {
430 var PTCCHDownlinkMsg ta_msg;
431 var PCUIF_Message pcu_msg;
432 timer T;
433
434 /* First, send an RTS.req for the upcoming PTCCH/D block */
435 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
436 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
437 arfcn := 871, block_nr := 0));
438 T.start(2.0);
439 alt {
440 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
441 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
442 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
443 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
444 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
445 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
446 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
447 log("Rx PTCCH/D message: ", ta_msg);
448
449 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700450 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200451 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
452 }
453 }
454 [] BTS.receive { repeat; }
455 [] T.timeout {
456 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200457 }
458 }
459}
460
461testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
462 var template PacketUlAssign t_ul_tbf_ass;
463 var PacketUlAssign ul_tbf_ass[7];
464 var GsmRrMessage rr_msg[7];
465 var boolean ok;
466
467 /* Initialize the PCU interface abstraction */
468 f_init_raw(testcasename());
469
470 /* Enable forwarding of PTCCH/U TDMA events to us */
471 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
472
473 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
474 for (var integer i := 0; i < 7; i := i + 1) {
475 ok := f_establish_tbf(rr_msg[i], ta := 0);
476 if (not ok) {
477 setverdict(fail, "Failed to establish an Uplink TBF #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700478 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200479 }
480
481 /* Make sure we received an UL TBF Assignment */
482 if (match(rr_msg[i], tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
483 ul_tbf_ass[i] := rr_msg[i].payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
484 log("Rx Uplink TBF assignment for #", i, ": ", ul_tbf_ass[i]);
485 } else {
486 setverdict(fail, "Failed to match UL TBF Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700487 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200488 }
489
490 /* We expect incremental TFI/USF assignment (dynamic allocation) */
491 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
492 if (not match(ul_tbf_ass[i], t_ul_tbf_ass)) {
493 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700494 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200495 }
496
497 /* We also expect Timing Advance Index to be a part of the assignment */
498 if (ul_tbf_ass[i].dynamic.ta_index != i) {
499 setverdict(fail, "Failed to match Timing Advance Index for #", i);
500 /* Keep going, the current OsmoPCU does not assign TA Index */
501 }
502 }
503
504 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
505 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
506 for (var integer i := 0; i < 7; i := i + 1) {
507 /* ToA in units of 1/4 of a symbol */
508 toa_map[i] := (i + 1) * 7 * 4;
509 }
510
511 /* Now we have all 7 TBFs established in one-phase access mode,
512 * however we will not be sending any data on them. Instead, we
513 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
514 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
515 *
516 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
517 * time-slots, so at the moment of scheduling a PTCCH/D block
518 * the PCU has odd number of PTCCH/U Access Bursts received. */
519 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
520 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
521 /* Other values are not known (yet) */
522 tai3_ta := ?));
523 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
524 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
525 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
526 /* Other values are out of our interest */
527 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700528
529 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200530}
531
532/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
533 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
534 *
535 * NOTE: the ranges are intentionally overlapping because OsmoPCU
536 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
537private template integer CS1_lqual_dB_range := (-infinity .. 6);
538private template integer CS2_lqual_dB_range := (5 .. 8);
539private template integer CS3_lqual_dB_range := (7 .. 13);
540private template integer CS4_lqual_dB_range := (12 .. infinity);
541
542testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
543 var GsmRrMessage rr_imm_ass;
544 var PacketUlAssign ul_tbf_ass;
545 var RlcmacDlBlock dl_block;
546 var PCUIF_Message pcu_msg;
547 var octetstring data;
548 var boolean ok;
549 var uint32_t unused_fn;
550
551 /* Initialize the PCU interface abstraction */
552 f_init_raw(testcasename());
553
554 f_pcuvty_set_allowed_cs_mcs();
555 f_pcuvty_set_link_quality_ranges();
556
557 /* Establish an Uplink TBF */
558 ok := f_establish_tbf(rr_imm_ass);
559 if (not ok) {
560 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700561 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200562 }
563
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700564 /* Make sure we've got an Uplink TBF assignment */
565 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200566
567 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
568 tfi := ul_tbf_ass.dynamic.tfi_assignment,
569 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
570 bsn := 0, /* TODO: what should be here? */
571 blocks := { /* To be generated in loop */ });
572
573 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
574 ul_data.data.tlli := '00000001'O;
575
576 /* The actual / old link quality values. We need to keep track of the old
577 * (basically previous) link quality value, because OsmoPCU actually
578 * changes the coding scheme if not only the actual, but also the old
579 * value leaves the current link quality range (window). */
580 var integer lqual := 0;
581 var integer lqual_old;
582
583 /* 16 UL blocks (0 .. 15 dB, step = 1 dB) */
584 for (var integer i := 0; i < 16; i := i + 1) {
585 /* Prepare a new UL block (CV, random payload) */
586 ul_data.data.mac_hdr.countdown := (15 - i);
587 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
588
589 /* Update the old / actual link quality */
590 lqual_old := lqual;
591 lqual := i;
592
593 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
594 log("Sending DATA.ind with link quality (dB): ", lqual);
595 f_tx_rlcmac_ul_block(ul_data, lqual * 10);
596
597 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
598 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
599
600 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
601 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
602
603 /* Match the received Channel Coding Command. Since we are increasing
604 * the link quality value on each iteration and not decreasing, there
605 * is no need to check the both old and current link quality values. */
606 var template ChCodingCommand ch_coding;
607 select (lqual_old) {
608 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
609 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
610 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
611 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
612 }
613
614 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
615 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200616 }
617 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700618
619 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200620}
621
622/* Test the max UL CS set by VTY works fine */
623testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
624 var GsmRrMessage rr_imm_ass;
625 var PacketUlAssign ul_tbf_ass;
626 var RlcmacDlBlock dl_block;
627 var boolean ok;
628 var integer lqual_cb;
629 var ChCodingCommand last_ch_coding;
630 var uint32_t unused_fn;
631
632 /* Initialize the PCU interface abstraction */
633 f_init_raw(testcasename());
634
635 /* Set initial UL CS to 3 */
636 g_cs_initial_ul := 3;
637 f_pcuvty_set_allowed_cs_mcs();
638 f_pcuvty_set_link_quality_ranges();
639
640 /* Take lqual (dB->cB) so that we stay in that CS */
641 lqual_cb := g_cs_lqual_ranges[2].low * 10;
642
643 /* Establish an Uplink TBF */
644 ok := f_establish_tbf(rr_imm_ass);
645 if (not ok) {
646 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700647 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200648 }
649
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700650 /* Make sure we've got an Uplink TBF assignment */
651 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200652
653 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
654 tfi := ul_tbf_ass.dynamic.tfi_assignment,
655 cv := 3, /* 8 UL blocks to be sent (to be overridden in loop) */
656 bsn := 0, /* TODO: what should be here? */
657 blocks := { /* To be generated in loop */ });
658
659 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
660 ul_data.data.tlli := '00000001'O;
661
662 /* 3 UL blocks, check we are in same initial CS: */
663 for (var integer i := 0; i < 3; i := i + 1) {
664 /* Prepare a new UL block (CV, random payload) */
665 ul_data.data.mac_hdr.countdown := (7 - i);
666 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
667
668 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
669 f_tx_rlcmac_ul_block(ul_data, lqual_cb);
670
671 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
672 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
673 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
674 }
675
676 if (last_ch_coding != CH_CODING_CS3) {
677 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200678 }
679
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200680 /* Remaining UL blocks are used to make sure regardless of initial
681 /* lqual, we can go lower at any time */
682
683 /* 5 UL blocks, check we are in same initial CS: */
684 for (var integer i := 3; i < 8; i := i + 1) {
685 /* Prepare a new UL block (CV, random payload) */
686 ul_data.data.mac_hdr.countdown := (7 - i);
687 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
688
689 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
690 f_tx_rlcmac_ul_block(ul_data, 0); /* 0 dB, make sure we downgrade CS */
691
692 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
693 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
694
695 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
696 }
697
698 if (last_ch_coding != CH_CODING_CS1) {
699 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200700 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700701
702 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200703}
704
705/* Test the max UL CS set by VTY works fine */
706testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
707 var GsmRrMessage rr_imm_ass;
708 var PacketUlAssign ul_tbf_ass;
709 var RlcmacDlBlock dl_block;
710 var boolean ok;
711 var ChCodingCommand last_ch_coding;
712 var uint32_t unused_fn;
713
714 /* Initialize the PCU interface abstraction */
715 f_init_raw(testcasename());
716
717 /* Set maximum allowed UL CS to 3 */
718 g_cs_max_ul := 3;
719 f_pcuvty_set_allowed_cs_mcs();
720 f_pcuvty_set_link_quality_ranges();
721
722 /* Establish an Uplink TBF */
723 ok := f_establish_tbf(rr_imm_ass);
724 if (not ok) {
725 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700726 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200727 }
728
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700729 /* Make sure we've got an Uplink TBF assignment */
730 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200731
732 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
733 tfi := ul_tbf_ass.dynamic.tfi_assignment,
734 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
735 bsn := 0, /* TODO: what should be here? */
736 blocks := { /* To be generated in loop */ });
737
738 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
739 ul_data.data.tlli := '00000001'O;
740
741 /* 16 UL blocks */
742 for (var integer i := 0; i < 16; i := i + 1) {
743 /* Prepare a new UL block (CV, random payload) */
744 ul_data.data.mac_hdr.countdown := (15 - i);
745 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
746
747 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
748 f_tx_rlcmac_ul_block(ul_data, 40*10); /* 40 dB */
749
750 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
751 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
752
753 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
754 }
755
756 if (last_ch_coding != CH_CODING_CS3) {
757 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200758 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700759
760 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200761}
762
763/* Verify PCU drops TBF after some time of inactivity. */
764testcase TC_t3169() runs on RAW_PCU_Test_CT {
765 var PCUIF_info_ind info_ind;
766 var GsmRrMessage rr_imm_ass;
767 var PacketUlAssign ul_tbf_ass;
768 var RlcmacDlBlock dl_block;
769 var PCUIF_Message pcu_msg;
770 var octetstring data;
771 var boolean ok;
772 var uint32_t unused_fn;
773 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200774 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200775
776 /* Initialize NS/BSSGP side */
777 f_init_bssgp();
778
779 info_ind := valueof(ts_PCUIF_INFO_default);
780 /* Set timer to 1 sec (default 5) to speedup test: */
781 info_ind.t3169 := 1;
782
783 /* Initialize the PCU interface abstraction */
784 f_init_raw(testcasename(), info_ind);
785
786 /* Establish BSSGP connection to the PCU */
787 f_bssgp_establish();
788 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
789
790 /* Establish an Uplink TBF */
791 ok := f_establish_tbf(rr_imm_ass);
792 if (not ok) {
793 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700794 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200795 }
796
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700797 /* Make sure we've got an Uplink TBF assignment */
798 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200799
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +0200800 /* Send one UL block (with TLLI since we are in One-Phase Access
801 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200802 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200803 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
804 /* UL block should be received in SGSN */
805 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
806
807 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
808 f_sleep(int2float(info_ind.t3169) + 1.0);
809
810 /* Send an UL block once again, the TBF should be gone by now so no ACK */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200811 bsn := 0;
812 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200813 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700814
815 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200816}
817
818/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
819 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
820 * T3193) after DL TBF release */
821testcase TC_t3193() runs on RAW_PCU_Test_CT {
822 var GsmRrMessage rr_imm_ass;
823 var PacketDlAssign dl_tbf_ass;
824 var RlcmacDlBlock dl_block;
825 var octetstring data := f_rnd_octstring(10);
826 var boolean ok;
827 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700828 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200829 var OCT4 tlli := '00000001'O;
830 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
831
832 /* Initialize NS/BSSGP side */
833 f_init_bssgp();
834
835 /* Initialize the PCU interface abstraction */
836 f_init_raw(testcasename());
837
838 /* Establish BSSGP connection to the PCU */
839 f_bssgp_establish();
840 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
841
842 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
843 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
844 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700845
846 /* Make sure we've got a Downlink TBF assignment */
847 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
848
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200849 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
850 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700851 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200852
853 /* ACK the DL block */
854 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700855 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
856 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200857 /* we are done with the DL-TBF here so far, let's clean up our local state: */
858 ack_nack_desc := valueof(t_AckNackDescription_init)
859
860 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
861 (T3192 in MS) was started and until it fires the MS will be abailable
862 on PDCH in case new data arrives from SGSN. Let's verify it: */
863 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
864 f_rx_rlcmac_dl_block_exp_pkt_ass(dl_block, sched_fn);
865 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
866
867 /* 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 +0700868 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200869 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700870 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
871 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700872
873 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200874}
875
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200876/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
877testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
878 var GsmRrMessage rr_imm_ass;
879 var PacketUlAssign ul_tbf_ass;
880 var RlcmacDlBlock dl_block;
881 var boolean ok;
882 var uint32_t sched_fn;
883 var OCT4 tlli := '00000001'O;
884 var uint14_t bsn := 1;
885 var PDU_BSSGP bssgp_pdu;
886 var octetstring total_payload;
887 var integer padding_len;
888
889 /* Initialize NS/BSSGP side */
890 f_init_bssgp();
891
892 /* Initialize the PCU interface abstraction */
893 f_init_raw(testcasename());
894
895 /* Establish BSSGP connection to the PCU */
896 f_bssgp_establish();
897 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
898
899 /* Establish an Uplink TBF */
900 ok := f_establish_tbf(rr_imm_ass);
901 if (not ok) {
902 setverdict(fail, "Failed to establish TBF");
903 f_shutdown(__BFILE__, __LINE__);
904 }
905 /* Make sure we've got an Uplink TBF assignment */
906 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
907
908 /* Send one UL block (with TLLI since we are in One-Phase Access
909 contention resoultion) and make sure it is ACKED fine. */
910 total_payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
911 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA_TLLI(
912 tfi := ul_tbf_ass.dynamic.tfi_assignment,
913 cv := 15, /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
914 bsn := 0,
915 blocks := { valueof(t_RLCMAC_LLCBLOCK(total_payload)) },
916 tlli := tlli);
917
918 f_tx_rlcmac_ul_block(ul_data, 0);
919 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
920 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
921 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
922
923 /* Send enough blocks to test whole procedure: Until Nth block
924 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
925 */
926 total_payload := total_payload & f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 20);
927 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
928 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
929 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
930
931 /* receive one message on BSSGP with all aggregated data in payload: */
932 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id, total_payload));
933}
934
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200935/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
936 * answered, so TBFs for uplink and later for downlink are created.
937 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200938private 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 +0200939 var GsmRrMessage rr_imm_ass;
940 var PacketUlAssign ul_tbf_ass;
941 var PacketDlAssign dl_tbf_ass;
942 var RlcmacDlBlock dl_block;
943 var PCUIF_Message pcu_msg;
944 var octetstring data := f_rnd_octstring(10);
945 var boolean ok;
946 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700947 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200948 var OCT4 tlli := '00000001'O;
949 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200950 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200951
952 /* Initialize NS/BSSGP side */
953 f_init_bssgp();
954
955 /* Initialize the PCU interface abstraction */
956 f_init_raw(testcasename());
957
958 /* Establish BSSGP connection to the PCU */
959 f_bssgp_establish();
960 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
961
962 /* Establish an Uplink TBF */
963 ok := f_establish_tbf(rr_imm_ass);
964 if (not ok) {
965 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700966 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200967 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700968
969 /* Make sure we've got an Uplink TBF assignment */
970 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200971
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +0200972 /* Send one UL block (with TLLI since we are in One-Phase Access
973 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200974 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200975 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
976 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
977 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
978
979 /* UL block should be received in SGSN */
980 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
981
982 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
983 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
984 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
985
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700986 /* Make sure we've got a Downlink TBF assignment */
987 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200988
989 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
990 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700991 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200992
993 /* ACK the DL block */
994 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700995 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
996 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700997
998 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200999}
1000
1001/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1002 * answered, so TBFs for uplink and later for downlink are created.
1003 */
1004testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
1005 var CodingScheme exp_cs_mcs := CS_1;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001006 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001007}
1008
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001009/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1010 * answered, so TBFs for uplink and later for downlink are created.
1011 */
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001012private function f_TC_mo_ping_pong_2phase_access(template (value) MSRadioAccessCapabilityV ms_racap,
1013 template (present) CodingScheme exp_ul_cs_mcs := ?,
1014 template (present) CodingScheme exp_dl_cs_mcs := ?)
1015runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001016 var GsmRrMessage rr_imm_ass;
1017 var PacketUlAssign ul_tbf_ass;
1018 var PacketDlAssign dl_tbf_ass;
1019 var RlcmacDlBlock dl_block;
1020 var PCUIF_Message pcu_msg;
1021 var octetstring data := f_rnd_octstring(10);
1022 var boolean ok;
1023 var uint32_t sched_fn;
1024 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001025 var uint32_t unused_fn;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001026 var OCT4 tlli := '00000001'O;
1027 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001028 var CodingScheme cs_mcs;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001029 var uint14_t bsn := 0;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001030 /* 0111 0xxx: Single block packet access; one block period on a PDCH is needed for two phase packet access or other RR signalling purpose. */
1031 var uint16_t ra := oct2int('70'O);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001032 if (g_force_two_phase_access) {
1033 /* If 2phase access is enforced by the network, then let's
1034 request a One phase packet access, we'll receive a single block
1035 anyway */
1036 ra := bit2int(chan_req_def);
1037 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001038
1039 /* Initialize NS/BSSGP side */
1040 f_init_bssgp();
1041
1042 /* Initialize the PCU interface abstraction */
1043 f_init_raw(testcasename());
1044
1045 /* Establish BSSGP connection to the PCU */
1046 f_bssgp_establish();
1047 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1048
1049 /* Establish an Uplink TBF */
1050 ok := f_establish_tbf(rr_imm_ass, ra := ra);
1051 if (not ok) {
1052 setverdict(fail, "Failed to establish TBF");
1053 f_shutdown(__BFILE__, __LINE__);
1054 }
1055
1056 /* Make sure we've got an Uplink TBF assignment */
1057 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass, tr_PacketUlSglAssign);
1058
1059 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
1060 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
1061 */
1062 f_tx_rlcmac_ul_block(ts_RLC_UL_CTRL_ACK(valueof(ts_RlcMacUlCtrl_PKT_RES_REQ(tlli, ms_racap))), 0);
1063 f_rx_rlcmac_dl_block_exp_pkt_ul_ass(dl_block, sched_fn);
1064 if (dl_block.ctrl.payload.u.ul_assignment.identity.tlli.tlli != tlli) {
1065 setverdict(fail, "Wrong TLLI ", dl_block.ctrl.payload.u.ul_assignment.identity.tlli, " received vs exp ", tlli);
1066 f_shutdown(__BFILE__, __LINE__);
1067 }
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001068 cs_mcs := f_rlcmac_dl_block_get_assigned_ul_cs_mcs(dl_block);
1069 if (not match(cs_mcs, exp_ul_cs_mcs)) {
1070 setverdict(fail, "Wrong CS_MCS ", cs_mcs, " received vs exp ", exp_ul_cs_mcs);
1071 f_shutdown(__BFILE__, __LINE__);
1072 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001073
1074 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1075 and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001076 f_tx_rlcmac_ul_n_blocks(f_rlcmac_dl_block_get_tfi(dl_block), bsn, 1); /* TODO: send using cs_mcs */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001077
1078 //f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1079 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1080 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1081
1082 /* UL block should be received in SGSN */
1083 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1084
1085 /* Now SGSN sends some DL data, PCU will page on PACCH */
1086 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1087 f_rx_rlcmac_dl_block_exp_pkt_dl_ass(dl_block, sched_fn);
1088 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
1089 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1090
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001091 /* PCU acks the UL data after having received CV=0) */
1092 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1093
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001094 /* 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 +02001095 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 +02001096
1097 /* ACK the DL block */
1098 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
1099 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1100 0, f_dl_block_ack_fn(dl_block, dl_fn));
1101
1102 f_shutdown(__BFILE__, __LINE__, final := true);
1103}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001104
1105testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1106 var MultislotCap_GPRS mscap_gprs := {
1107 gprsmultislotclass := '00011'B,
1108 gprsextendeddynalloccap := '0'B
1109 };
1110 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001111 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1112 var CodingScheme exp_dl_cs_mcs := CS_2;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001113
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001114 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1115}
1116
1117testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
1118 /* Initialize the PCU interface abstraction with EGPRS-only */
1119 g_egprs_only := true;
1120
1121 var MultislotCap_GPRS mscap_gprs := {
1122 gprsmultislotclass := '00011'B,
1123 gprsextendeddynalloccap := '0'B
1124 };
1125 var MultislotCap_EGPRS mscap_egprs := {
1126 egprsmultislotclass := '00011'B,
1127 egprsextendeddynalloccap := '0'B
1128 };
1129 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1130 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1131 var CodingScheme exp_dl_cs_mcs := MCS_1;
1132
1133 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001134}
1135
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001136testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
1137 /* Configure PCU to force two phase access */
1138 g_force_two_phase_access := true;
1139
1140 var MultislotCap_GPRS mscap_gprs := {
1141 gprsmultislotclass := '00011'B,
1142 gprsextendeddynalloccap := '0'B
1143 };
1144 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1145 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1146 var CodingScheme exp_dl_cs_mcs := CS_2;
1147
1148 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1149}
1150
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001151/* Test scenario where SGSN wants to send some data against MS and it is
1152 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1153 */
1154private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit, template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
1155 var GsmRrMessage rr_imm_ass;
1156 var PacketUlAssign ul_tbf_ass;
1157 var PacketDlAssign dl_tbf_ass;
1158 var RlcmacDlBlock dl_block;
1159 var PCUIF_Message pcu_msg;
1160 var octetstring data := f_rnd_octstring(10);
1161 var boolean ok;
1162 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001163 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001164 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001165 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001166 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1167
1168 /* Initialize NS/BSSGP side */
1169 f_init_bssgp();
1170
1171 /* Initialize the PCU interface abstraction */
1172 f_init_raw(testcasename());
1173
1174 /* Establish BSSGP connection to the PCU */
1175 f_bssgp_establish();
1176 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1177
1178 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1179 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
1180 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1181
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001182 /* Make sure we've got a Downlink TBF assignment */
1183 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001184
1185 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1186 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001187 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001188
1189 /* ACK the DL block */
1190 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001191 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1192 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001193
1194 /* Now MS wants to answer the DL data, Establish an Uplink TBF */
1195 ok := f_establish_tbf(rr_imm_ass);
1196 if (not ok) {
1197 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001198 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001199 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001200
1201 /* Make sure we've got an Uplink TBF assignment */
1202 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001203
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001204 /* Send one UL block (with TLLI since we are in One-Phase Access
1205 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001206 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001207 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1208 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1209 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1210
1211 /* UL block should be received in SGSN */
1212 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001213
1214 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001215}
1216
1217testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
1218 var CodingScheme exp_cs_mcs := CS_1;
1219 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1220}
1221
1222/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1223/* information about the MS */
1224testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1225 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1226 gprsmultislotclass := '00011'B,
1227 gprsextendeddynalloccap := '0'B
1228 } ;
1229 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
1230 var CodingScheme exp_cs_mcs := CS_2;
1231 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1232}
1233
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001234/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
1235 * TBF, it will request retransmission through UL ACK/NACK (with missing block
1236 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
1237 * be transferred).
1238 */
1239testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
1240 var GsmRrMessage rr_imm_ass;
1241 var PacketUlAssign ul_tbf_ass;
1242 var RlcmacDlBlock dl_block;
1243 var template (value) RlcmacUlBlock ul_data;
1244 var boolean ok;
1245 var uint32_t sched_fn;
1246 var OCT4 tlli := '00000001'O;
1247 var uint14_t bsn := 5;
1248 var PDU_BSSGP bssgp_pdu;
1249 var octetstring total_payload;
1250 var octetstring payload;
1251 var octetstring lost_payload;
1252 var integer padding_len;
1253 var uint5_t tfi;
1254
1255 /* Initialize NS/BSSGP side */
1256 f_init_bssgp();
1257
1258 /* Initialize the PCU interface abstraction */
1259 f_init_raw(testcasename());
1260
1261 /* Establish BSSGP connection to the PCU */
1262 f_bssgp_establish();
1263 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1264
1265 /* Establish an Uplink TBF */
1266 ok := f_establish_tbf(rr_imm_ass);
1267 if (not ok) {
1268 setverdict(fail, "Failed to establish TBF");
1269 f_shutdown(__BFILE__, __LINE__);
1270 }
1271 /* Make sure we've got an Uplink TBF assignment */
1272 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1273 tfi := ul_tbf_ass.dynamic.tfi_assignment;
1274
1275 /* Send one UL block (with TLLI since we are in One-Phase Access
1276 contention resoultion) and make sure it is ACKED fine. */
1277 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1278 ul_data := t_RLCMAC_UL_DATA_TLLI(
1279 tfi := tfi,
1280 cv := 15, /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
1281 bsn := 0,
1282 blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) },
1283 tlli := tlli);
1284
1285 f_tx_rlcmac_ul_block(ul_data, 0);
1286 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1287 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1288 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1289 total_payload := payload;
1290
1291 /* Send 2 packets, skip 1 (inc bsn) and send another one */
1292 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1293 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 1, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1294 f_tx_rlcmac_ul_block(ul_data, 0);
1295 total_payload := total_payload & payload;
1296
1297 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1298 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 2, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1299 f_tx_rlcmac_ul_block(ul_data, 0);
1300 total_payload := total_payload & payload;
1301
1302 lost_payload := f_rnd_octstring(20); /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
1303 total_payload := total_payload & lost_payload;
1304
1305 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1306 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 4, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1307 f_tx_rlcmac_ul_block(ul_data, 0);
1308 total_payload := total_payload & payload;
1309
1310 /* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
1311 total_payload := total_payload & f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, g_bs_cv_max);
1312
1313 /* On CV=0, we'll receive a UL ACK asking about missing block */
1314 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1315 /* TODO: check ack ack bitmap (URBB) */
1316 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 3, blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
1317 f_tx_rlcmac_ul_block(ul_data, 0);
1318
1319 /* Now final ack is recieved */
1320 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1321 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1322 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1323
1324 /* receive one message on BSSGP with all aggregated data in payload: */
1325 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id, total_payload));
1326}
1327
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001328/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1329 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1330 * timeout occurs (specified by sent RRBP on DL block). */
1331testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
1332 var GsmRrMessage rr_imm_ass;
1333 var PacketDlAssign dl_tbf_ass;
1334 var RlcmacDlBlock dl_block;
1335 var octetstring data := f_rnd_octstring(10);
1336 var boolean ok;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001337 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001338 var OCT4 tlli := '00000001'O;
1339 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1340
1341 /* Initialize NS/BSSGP side */
1342 f_init_bssgp();
1343
1344 /* Initialize the PCU interface abstraction */
1345 f_init_raw(testcasename());
1346
1347 /* Establish BSSGP connection to the PCU */
1348 f_bssgp_establish();
1349 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1350
1351 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1352 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1353 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001354
1355 /* Make sure we've got a Downlink TBF assignment */
1356 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001357
1358 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1359 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001360 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001361
1362 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1363 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1364 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
1365 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001366
1367 /* Make sure we've got a Downlink TBF assignment */
1368 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1369
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 */
1375 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001376 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1377 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001378
1379 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001380}
1381
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001382/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1383testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1384 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1385 var octetstring data := f_rnd_octstring(16);
1386 var OCT4 tlli := f_rnd_octstring(4);
1387 var PacketDlAssign dl_tbf_ass;
1388 var GsmRrMessage rr_imm_ass;
1389 var RlcmacDlBlock dl_block;
1390 var uint32_t ack_fn;
1391 var uint32_t fn;
1392 timer T := 5.0;
1393
1394 /* Initialize NS/BSSGP side */
1395 f_init_bssgp();
1396
1397 /* Initialize the PCU interface abstraction */
1398 f_init_raw(testcasename());
1399
1400 /* Establish BSSGP connection to the PCU */
1401 f_bssgp_establish();
1402 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1403
1404 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1405 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1406 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1407
1408 /* Make sure we've got a Downlink TBF assignment with DL TFI */
1409 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1410 if (not ispresent(dl_tbf_ass.group1)) {
1411 setverdict(fail, "Immediate Assignment contains no DL TFI");
1412 f_shutdown(__BFILE__, __LINE__);
1413 }
1414
1415 /* Get DL TFI from received Downlink TBF assignment */
1416 var uint5_t tfi := dl_tbf_ass.group1.tfi_assignment;
1417
1418 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1419 f_sleep(X2002);
1420
1421 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
1422 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
1423 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1424
1425 /* TDMA frame number on which we are supposed to send the ACK */
1426 ack_fn := f_dl_block_ack_fn(dl_block, fn);
1427
1428 /* SGSN sends more blocks during the indicated RRBP */
1429 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
1430 data := f_rnd_octstring(16); /* Random LLC data */
1431 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1432
1433 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
1434
1435 /* Make sure this block has the same TFI as was assigned
1436 * FIXME: this is only valid for GPRS, not EGPRS. */
1437 if (dl_block.data.mac_hdr.hdr_ext.tfi != tfi) {
1438 setverdict(fail, "Rx DL data block with unexpected TFI: ",
1439 dl_block.data.mac_hdr.hdr_ext.tfi);
1440 f_shutdown(__BFILE__, __LINE__);
1441 }
1442
1443 /* Keep Ack/Nack description updated */
1444 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1445
1446 /* Break if this is the end of RRBP */
1447 if (fn == ack_fn) {
1448 ack_nack_desc.final_ack := '1'B;
1449 break;
1450 }
1451 }
1452
1453 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
1454 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(tfi, ack_nack_desc), fn := fn);
1455
1456 /* Make sure that the next block (after the Ack) is dummy */
1457 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
1458
1459 f_shutdown(__BFILE__, __LINE__, final := true);
1460}
1461
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001462private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
1463runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001464 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
1465 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
1466
1467 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
1468 setverdict(fail, "Mobile Identity length mismatch: ",
1469 "expected: 8, got: ", mi_lv.len);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001470 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001471 }
1472
1473 /* Make sure MI contains IMSI before referencing it */
1474 if (mi.typeOfIdentity != '001'B) {
1475 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
1476 "got: ", mi.typeOfIdentity);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001477 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001478 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
1479 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
1480 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001481 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001482 }
1483}
1484
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001485/* Test CS paging over the BTS<->PCU socket.
1486 * 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.
1487 * Paging should be send on the PACCH.
1488 *
1489 * 1. Send a Paging Request over PCU socket.
1490 * 2. Send a Ready-To-Send message over PCU socket
1491 * 3. Expect a Paging Frame
1492 */
1493testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
1494 var GsmRrMessage rr_imm_ass;
1495 var PacketUlAssign ul_tbf_ass;
1496 var RlcmacDlBlock dl_block;
1497 var boolean ok;
1498 var OCT4 tlli := '00000001'O;
1499 var MobileIdentityLV mi;
1500 var octetstring mi_enc_lv;
1501 var hexstring imsi := f_gen_imsi(42);
1502
1503 /* Initialize NS/BSSGP side */
1504 f_init_bssgp();
1505
1506 /* Initialize the PCU interface abstraction */
1507 f_init_raw(testcasename());
1508
1509 /* Establish BSSGP connection to the PCU */
1510 f_bssgp_establish();
1511 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1512
1513 /* Establish an Uplink TBF */
1514 ok := f_establish_tbf(rr_imm_ass);
1515 if (not ok) {
1516 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001517 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001518 }
1519
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001520 /* Make sure we've got an Uplink TBF assignment */
1521 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001522
1523 /* build mobile Identity */
1524 mi := valueof(ts_MI_IMSI_LV(imsi));
1525 mi_enc_lv := enc_MobileIdentityLV(mi);
1526 /* Send paging request */
1527 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
1528 sapi :=PCU_IF_SAPI_PDTCH));
1529
1530 /* Receive it on BTS side towards MS */
1531 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1532
1533 /* Make sure that Packet Paging Request contains the same IMSI */
1534 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1535
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001536 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001537}
1538
1539/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
1540 */
1541private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1542runs on RAW_PCU_Test_CT {
1543 var GsmRrMessage rr_imm_ass;
1544 var PacketUlAssign ul_tbf_ass;
1545 var RlcmacDlBlock dl_block;
1546 var boolean ok;
1547 var OCT4 tlli := '00000001'O;
1548 var hexstring imsi := f_gen_imsi(42);
1549 var GsmTmsi tmsi;
1550
1551 /* Initialize NS/BSSGP side */
1552 f_init_bssgp();
1553
1554 /* Initialize the PCU interface abstraction */
1555 f_init_raw(testcasename());
1556
1557 /* Establish BSSGP connection to the PCU */
1558 f_bssgp_establish();
1559 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1560
1561 /* Establish an Uplink TBF */
1562 ok := f_establish_tbf(rr_imm_ass);
1563 if (not ok) {
1564 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001565 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001566 }
1567
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001568 /* Make sure we've got an Uplink TBF assignment */
1569 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001570
1571 /* Send paging request with or without TMSI */
1572 if (use_ptmsi) {
1573 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
1574 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
1575 } else {
1576 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
1577 }
1578
1579 /* Receive it on BTS side towards MS */
1580 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1581
1582 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
1583 if (use_ptmsi) {
1584 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
1585 } else {
1586 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1587 }
1588
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001589 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001590}
1591
1592testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1593 f_tc_paging_cs_from_sgsn(0, true);
1594}
1595
1596testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1597 f_tc_paging_cs_from_sgsn(0);
1598}
1599
1600testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1601 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
1602}
1603
1604/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
1605 */
1606private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1607runs on RAW_PCU_Test_CT {
1608 var OCT4 tlli := '00000001'O;
1609 var integer imsi_suff_tx := 423;
1610 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
1611
1612 /* Initialize NS/BSSGP side */
1613 f_init_bssgp();
1614
1615 /* Initialize the PCU interface abstraction */
1616 f_init_raw(testcasename());
1617
1618 /* Establish BSSGP connection to the PCU */
1619 f_bssgp_establish();
1620 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1621
1622 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
1623 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
1624 if (use_ptmsi) {
1625 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
1626 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
1627 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
1628 } else {
1629 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
1630 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
1631 }
1632
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001633 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001634}
1635
1636testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1637 f_tc_paging_ps_from_sgsn(0, true);
1638}
1639
1640testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1641 f_tc_paging_ps_from_sgsn(0);
1642}
1643
1644testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1645 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
1646}
1647
1648private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
1649 template GsmRrMessage t_imm_ass := ?,
1650 PCUIF_BurstType bt := BURST_TYPE_1)
1651runs on RAW_PCU_Test_CT {
1652 var GsmRrMessage rr_msg;
1653 var uint16_t ra11;
1654 var boolean ok;
1655
1656 ra11 := enc_EGPRSPktChRequest2uint(req);
1657 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
1658
1659 ok := f_establish_tbf(rr_msg, ra := ra11, is_11bit := 1, burst_type := bt);
1660 if (not ok) {
1661 setverdict(fail, "Failed to establush an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001662 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001663 }
1664
1665 if (not match(rr_msg, t_imm_ass)) {
1666 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001667 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001668 }
1669
1670 setverdict(pass);
1671}
1672
1673testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
1674 var template GsmRrMessage imm_ass;
1675 var template IaRestOctets rest;
1676 var template EgprsUlAss ul_ass;
1677
1678 /* Initialize the PCU interface abstraction */
1679 f_init_raw(testcasename());
1680
1681 var EGPRSPktChRequest req := {
1682 /* NOTE: other fields are set in the loop */
1683 signalling := { tag := '110011'B }
1684 };
1685
1686 for (var integer i := 0; i < 6; i := i + 1) {
1687 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1688 req.signalling.random_bits := ext_ra;
1689
1690 /* For signalling, do we expect Multiblock UL TBF Assignment? */
1691 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
1692 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1693 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1694
1695 f_TC_egprs_pkt_chan_req(req, imm_ass);
1696 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001697
1698 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001699}
1700
1701testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
1702 var template GsmRrMessage imm_ass;
1703 var template IaRestOctets rest;
1704 var template EgprsUlAss ul_ass;
1705
1706 /* Initialize the PCU interface abstraction */
1707 f_init_raw(testcasename());
1708
1709 var EGPRSPktChRequest req := {
1710 /* NOTE: other fields are set in the loop */
1711 one_phase := { tag := '0'B }
1712 };
1713
1714 for (var integer i := 0; i < 6; i := i + 1) {
1715 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1716 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
1717 var BIT2 priority := substr(ext_ra, 0, 2);
1718 var BIT3 rand := substr(ext_ra, 2, 3);
1719
1720 req.one_phase.multislot_class := mslot_class;
1721 req.one_phase.priority := priority;
1722 req.one_phase.random_bits := rand;
1723
1724 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
1725 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
1726 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1727 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1728
1729 f_TC_egprs_pkt_chan_req(req, imm_ass);
1730 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001731
1732 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001733}
1734
1735testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
1736 var template GsmRrMessage imm_ass;
1737 var template IaRestOctets rest;
1738 var template EgprsUlAss ul_ass;
1739
1740 /* Initialize the PCU interface abstraction */
1741 f_init_raw(testcasename());
1742
1743 var EGPRSPktChRequest req := {
1744 /* NOTE: other fields are set in the loop */
1745 two_phase := { tag := '110000'B }
1746 };
1747
1748 for (var integer i := 0; i < 6; i := i + 1) {
1749 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1750 var BIT2 priority := substr(ext_ra, 0, 2);
1751 var BIT3 rand := substr(ext_ra, 2, 3);
1752
1753 req.two_phase.priority := priority;
1754 req.two_phase.random_bits := rand;
1755
1756 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
1757 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
1758 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1759 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1760
1761 f_TC_egprs_pkt_chan_req(req, imm_ass);
1762 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001763
1764 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001765}
1766
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07001767private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
1768 template IARRestOctets rest := ?,
1769 PCUIF_BurstType bt := BURST_TYPE_1)
1770runs on RAW_PCU_Test_CT {
1771 var template ReqRefWaitInd tr_ref;
1772 var GsmRrMessage rr_msg;
1773 var boolean ok;
1774
1775 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
1776 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
1777 ra := bit2int(ra11), is_11bit := 1,
1778 burst_type := bt, fn := fn,
1779 arfcn := 871));
1780
1781 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
1782 ok := f_pcuif_rx_imm_ass(rr_msg, t_imm_ass := tr_IMM_ASS_REJ);
1783 if (not ok) {
1784 setverdict(fail, "Failed to match Immediate Assignment Reject");
1785 f_shutdown(__BFILE__, __LINE__);
1786 }
1787
1788 /* Just to have a short-name reference to the actual message */
1789 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
1790
1791 /* Make sure that Request Reference list contains at least one entry
1792 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
1793 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn));
1794 if (not match(iar.payload, { *, tr_ref, * })) {
1795 setverdict(fail, "Request Reference list does not match");
1796 f_shutdown(__BFILE__, __LINE__);
1797 }
1798
1799 /* Match Feature Indicator (must indicate PS domain) */
1800 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
1801 setverdict(fail, "Feature Indicator does not match");
1802 f_shutdown(__BFILE__, __LINE__);
1803 }
1804
1805 /* Match IAR Rest Octets */
1806 if (not match(iar.rest_octets, rest)) {
1807 setverdict(fail, "IAR Rest Octets does not match: ",
1808 iar.rest_octets, " vs expected ", rest);
1809 f_shutdown(__BFILE__, __LINE__);
1810 }
1811
1812 setverdict(pass);
1813}
1814
1815/* Verify the contents of RR Immediate Assignment Reject message and its
1816 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
1817testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
1818 var template IARRestOctets rest;
1819 var BIT5 ext_ra;
1820
1821 /* Initialize the PCU interface abstraction */
1822 f_init_raw(testcasename());
1823
1824 for (var integer i := 0; i < 6; i := i + 1) {
1825 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
1826 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
1827
1828 /* Intentionally incorrect message (see table 11.2.5a.2) */
1829 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
1830 }
1831
1832 f_shutdown(__BFILE__, __LINE__, final := true);
1833}
1834
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001835control {
1836 execute( TC_pcuif_suspend() );
1837 execute( TC_ta_ptcch_idle() );
1838 execute( TC_ta_rach_imm_ass() );
1839 execute( TC_ta_idle_dl_tbf_ass() );
1840 execute( TC_ta_ptcch_ul_multi_tbf() );
1841 execute( TC_cs_lqual_ul_tbf() );
1842 execute( TC_cs_initial_ul() );
1843 execute( TC_cs_max_ul() );
1844 execute( TC_t3169() );
1845 execute( TC_t3193() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001846 execute( TC_countdown_procedure() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001847 execute( TC_mo_ping_pong() );
1848 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001849 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001850 execute( TC_mt_ping_pong() );
1851 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001852 execute (TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001853 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001854 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001855 execute( TC_paging_cs_from_bts() );
1856 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
1857 execute( TC_paging_cs_from_sgsn_sign() );
1858 execute( TC_paging_cs_from_sgsn_ptp() );
1859 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
1860 execute( TC_paging_ps_from_sgsn_sign() );
1861 execute( TC_paging_ps_from_sgsn_ptp() );
1862
1863 /* EGPRS specific test cases */
1864 execute( TC_egprs_pkt_chan_req_signalling() );
1865 execute( TC_egprs_pkt_chan_req_one_phase() );
1866 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07001867 execute( TC_egprs_pkt_chan_req_reject_content() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001868
1869 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001870}
1871
1872
1873
1874
1875
1876
Harald Weltea419df22019-03-21 17:23:04 +01001877}