blob: 51933694b63661c72f07f2bbc751c719ba5d5c4c [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>
10 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
11 * 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;
1025 var OCT4 tlli := '00000001'O;
1026 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001027 var CodingScheme cs_mcs;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001028 var uint14_t bsn := 0;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001029 /* 0111 0xxx: Single block packet access; one block period on a PDCH is needed for two phase packet access or other RR signalling purpose. */
1030 var uint16_t ra := oct2int('70'O);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001031 if (g_force_two_phase_access) {
1032 /* If 2phase access is enforced by the network, then let's
1033 request a One phase packet access, we'll receive a single block
1034 anyway */
1035 ra := bit2int(chan_req_def);
1036 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001037
1038 /* Initialize NS/BSSGP side */
1039 f_init_bssgp();
1040
1041 /* Initialize the PCU interface abstraction */
1042 f_init_raw(testcasename());
1043
1044 /* Establish BSSGP connection to the PCU */
1045 f_bssgp_establish();
1046 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1047
1048 /* Establish an Uplink TBF */
1049 ok := f_establish_tbf(rr_imm_ass, ra := ra);
1050 if (not ok) {
1051 setverdict(fail, "Failed to establish TBF");
1052 f_shutdown(__BFILE__, __LINE__);
1053 }
1054
1055 /* Make sure we've got an Uplink TBF assignment */
1056 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass, tr_PacketUlSglAssign);
1057
1058 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
1059 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
1060 */
1061 f_tx_rlcmac_ul_block(ts_RLC_UL_CTRL_ACK(valueof(ts_RlcMacUlCtrl_PKT_RES_REQ(tlli, ms_racap))), 0);
1062 f_rx_rlcmac_dl_block_exp_pkt_ul_ass(dl_block, sched_fn);
1063 if (dl_block.ctrl.payload.u.ul_assignment.identity.tlli.tlli != tlli) {
1064 setverdict(fail, "Wrong TLLI ", dl_block.ctrl.payload.u.ul_assignment.identity.tlli, " received vs exp ", tlli);
1065 f_shutdown(__BFILE__, __LINE__);
1066 }
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001067 cs_mcs := f_rlcmac_dl_block_get_assigned_ul_cs_mcs(dl_block);
1068 if (not match(cs_mcs, exp_ul_cs_mcs)) {
1069 setverdict(fail, "Wrong CS_MCS ", cs_mcs, " received vs exp ", exp_ul_cs_mcs);
1070 f_shutdown(__BFILE__, __LINE__);
1071 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001072
1073 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1074 and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001075 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 +02001076
1077 //f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1078 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1079 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1080
1081 /* UL block should be received in SGSN */
1082 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1083
1084 /* Now SGSN sends some DL data, PCU will page on PACCH */
1085 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1086 f_rx_rlcmac_dl_block_exp_pkt_dl_ass(dl_block, sched_fn);
1087 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
1088 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1089
1090 /* 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 +02001091 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 +02001092
1093 /* ACK the DL block */
1094 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
1095 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1096 0, f_dl_block_ack_fn(dl_block, dl_fn));
1097
1098 f_shutdown(__BFILE__, __LINE__, final := true);
1099}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001100
1101testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1102 var MultislotCap_GPRS mscap_gprs := {
1103 gprsmultislotclass := '00011'B,
1104 gprsextendeddynalloccap := '0'B
1105 };
1106 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001107 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1108 var CodingScheme exp_dl_cs_mcs := CS_2;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001109
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001110 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1111}
1112
1113testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
1114 /* Initialize the PCU interface abstraction with EGPRS-only */
1115 g_egprs_only := true;
1116
1117 var MultislotCap_GPRS mscap_gprs := {
1118 gprsmultislotclass := '00011'B,
1119 gprsextendeddynalloccap := '0'B
1120 };
1121 var MultislotCap_EGPRS mscap_egprs := {
1122 egprsmultislotclass := '00011'B,
1123 egprsextendeddynalloccap := '0'B
1124 };
1125 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1126 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1127 var CodingScheme exp_dl_cs_mcs := MCS_1;
1128
1129 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 +02001130}
1131
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001132testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
1133 /* Configure PCU to force two phase access */
1134 g_force_two_phase_access := true;
1135
1136 var MultislotCap_GPRS mscap_gprs := {
1137 gprsmultislotclass := '00011'B,
1138 gprsextendeddynalloccap := '0'B
1139 };
1140 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1141 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1142 var CodingScheme exp_dl_cs_mcs := CS_2;
1143
1144 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1145}
1146
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001147/* Test scenario where SGSN wants to send some data against MS and it is
1148 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1149 */
1150private 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 {
1151 var GsmRrMessage rr_imm_ass;
1152 var PacketUlAssign ul_tbf_ass;
1153 var PacketDlAssign dl_tbf_ass;
1154 var RlcmacDlBlock dl_block;
1155 var PCUIF_Message pcu_msg;
1156 var octetstring data := f_rnd_octstring(10);
1157 var boolean ok;
1158 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001159 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001160 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001161 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001162 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1163
1164 /* Initialize NS/BSSGP side */
1165 f_init_bssgp();
1166
1167 /* Initialize the PCU interface abstraction */
1168 f_init_raw(testcasename());
1169
1170 /* Establish BSSGP connection to the PCU */
1171 f_bssgp_establish();
1172 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1173
1174 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1175 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
1176 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1177
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001178 /* Make sure we've got a Downlink TBF assignment */
1179 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001180
1181 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1182 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001183 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001184
1185 /* ACK the DL block */
1186 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001187 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1188 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001189
1190 /* Now MS wants to answer the DL data, Establish an Uplink TBF */
1191 ok := f_establish_tbf(rr_imm_ass);
1192 if (not ok) {
1193 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001194 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001195 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001196
1197 /* Make sure we've got an Uplink TBF assignment */
1198 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001199
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001200 /* Send one UL block (with TLLI since we are in One-Phase Access
1201 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001202 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001203 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1204 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1205 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1206
1207 /* UL block should be received in SGSN */
1208 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001209
1210 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001211}
1212
1213testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
1214 var CodingScheme exp_cs_mcs := CS_1;
1215 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1216}
1217
1218/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1219/* information about the MS */
1220testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1221 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1222 gprsmultislotclass := '00011'B,
1223 gprsextendeddynalloccap := '0'B
1224 } ;
1225 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
1226 var CodingScheme exp_cs_mcs := CS_2;
1227 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1228}
1229
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001230/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
1231 * TBF, it will request retransmission through UL ACK/NACK (with missing block
1232 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
1233 * be transferred).
1234 */
1235testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
1236 var GsmRrMessage rr_imm_ass;
1237 var PacketUlAssign ul_tbf_ass;
1238 var RlcmacDlBlock dl_block;
1239 var template (value) RlcmacUlBlock ul_data;
1240 var boolean ok;
1241 var uint32_t sched_fn;
1242 var OCT4 tlli := '00000001'O;
1243 var uint14_t bsn := 5;
1244 var PDU_BSSGP bssgp_pdu;
1245 var octetstring total_payload;
1246 var octetstring payload;
1247 var octetstring lost_payload;
1248 var integer padding_len;
1249 var uint5_t tfi;
1250
1251 /* Initialize NS/BSSGP side */
1252 f_init_bssgp();
1253
1254 /* Initialize the PCU interface abstraction */
1255 f_init_raw(testcasename());
1256
1257 /* Establish BSSGP connection to the PCU */
1258 f_bssgp_establish();
1259 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1260
1261 /* Establish an Uplink TBF */
1262 ok := f_establish_tbf(rr_imm_ass);
1263 if (not ok) {
1264 setverdict(fail, "Failed to establish TBF");
1265 f_shutdown(__BFILE__, __LINE__);
1266 }
1267 /* Make sure we've got an Uplink TBF assignment */
1268 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1269 tfi := ul_tbf_ass.dynamic.tfi_assignment;
1270
1271 /* Send one UL block (with TLLI since we are in One-Phase Access
1272 contention resoultion) and make sure it is ACKED fine. */
1273 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1274 ul_data := t_RLCMAC_UL_DATA_TLLI(
1275 tfi := tfi,
1276 cv := 15, /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
1277 bsn := 0,
1278 blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) },
1279 tlli := tlli);
1280
1281 f_tx_rlcmac_ul_block(ul_data, 0);
1282 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1283 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1284 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1285 total_payload := payload;
1286
1287 /* Send 2 packets, skip 1 (inc bsn) and send another one */
1288 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1289 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 1, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1290 f_tx_rlcmac_ul_block(ul_data, 0);
1291 total_payload := total_payload & payload;
1292
1293 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1294 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 2, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1295 f_tx_rlcmac_ul_block(ul_data, 0);
1296 total_payload := total_payload & payload;
1297
1298 lost_payload := f_rnd_octstring(20); /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
1299 total_payload := total_payload & lost_payload;
1300
1301 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1302 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 4, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1303 f_tx_rlcmac_ul_block(ul_data, 0);
1304 total_payload := total_payload & payload;
1305
1306 /* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
1307 total_payload := total_payload & f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, g_bs_cv_max);
1308
1309 /* On CV=0, we'll receive a UL ACK asking about missing block */
1310 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1311 /* TODO: check ack ack bitmap (URBB) */
1312 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 3, blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
1313 f_tx_rlcmac_ul_block(ul_data, 0);
1314
1315 /* Now final ack is recieved */
1316 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1317 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1318 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1319
1320 /* receive one message on BSSGP with all aggregated data in payload: */
1321 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id, total_payload));
1322}
1323
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001324/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1325 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1326 * timeout occurs (specified by sent RRBP on DL block). */
1327testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
1328 var GsmRrMessage rr_imm_ass;
1329 var PacketDlAssign dl_tbf_ass;
1330 var RlcmacDlBlock dl_block;
1331 var octetstring data := f_rnd_octstring(10);
1332 var boolean ok;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001333 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001334 var OCT4 tlli := '00000001'O;
1335 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1336
1337 /* Initialize NS/BSSGP side */
1338 f_init_bssgp();
1339
1340 /* Initialize the PCU interface abstraction */
1341 f_init_raw(testcasename());
1342
1343 /* Establish BSSGP connection to the PCU */
1344 f_bssgp_establish();
1345 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1346
1347 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1348 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1349 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001350
1351 /* Make sure we've got a Downlink TBF assignment */
1352 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001353
1354 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1355 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001356 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001357
1358 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1359 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1360 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
1361 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001362
1363 /* Make sure we've got a Downlink TBF assignment */
1364 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1365
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001366 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1367 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001368 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001369
1370 /* ACK the DL block */
1371 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001372 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1373 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001374
1375 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001376}
1377
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001378/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1379testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1380 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1381 var octetstring data := f_rnd_octstring(16);
1382 var OCT4 tlli := f_rnd_octstring(4);
1383 var PacketDlAssign dl_tbf_ass;
1384 var GsmRrMessage rr_imm_ass;
1385 var RlcmacDlBlock dl_block;
1386 var uint32_t ack_fn;
1387 var uint32_t fn;
1388 timer T := 5.0;
1389
1390 /* Initialize NS/BSSGP side */
1391 f_init_bssgp();
1392
1393 /* Initialize the PCU interface abstraction */
1394 f_init_raw(testcasename());
1395
1396 /* Establish BSSGP connection to the PCU */
1397 f_bssgp_establish();
1398 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1399
1400 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1401 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1402 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1403
1404 /* Make sure we've got a Downlink TBF assignment with DL TFI */
1405 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1406 if (not ispresent(dl_tbf_ass.group1)) {
1407 setverdict(fail, "Immediate Assignment contains no DL TFI");
1408 f_shutdown(__BFILE__, __LINE__);
1409 }
1410
1411 /* Get DL TFI from received Downlink TBF assignment */
1412 var uint5_t tfi := dl_tbf_ass.group1.tfi_assignment;
1413
1414 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1415 f_sleep(X2002);
1416
1417 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
1418 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
1419 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1420
1421 /* TDMA frame number on which we are supposed to send the ACK */
1422 ack_fn := f_dl_block_ack_fn(dl_block, fn);
1423
1424 /* SGSN sends more blocks during the indicated RRBP */
1425 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
1426 data := f_rnd_octstring(16); /* Random LLC data */
1427 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1428
1429 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
1430
1431 /* Make sure this block has the same TFI as was assigned
1432 * FIXME: this is only valid for GPRS, not EGPRS. */
1433 if (dl_block.data.mac_hdr.hdr_ext.tfi != tfi) {
1434 setverdict(fail, "Rx DL data block with unexpected TFI: ",
1435 dl_block.data.mac_hdr.hdr_ext.tfi);
1436 f_shutdown(__BFILE__, __LINE__);
1437 }
1438
1439 /* Keep Ack/Nack description updated */
1440 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1441
1442 /* Break if this is the end of RRBP */
1443 if (fn == ack_fn) {
1444 ack_nack_desc.final_ack := '1'B;
1445 break;
1446 }
1447 }
1448
1449 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
1450 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(tfi, ack_nack_desc), fn := fn);
1451
1452 /* Make sure that the next block (after the Ack) is dummy */
1453 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
1454
1455 f_shutdown(__BFILE__, __LINE__, final := true);
1456}
1457
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001458private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
1459runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001460 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
1461 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
1462
1463 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
1464 setverdict(fail, "Mobile Identity length mismatch: ",
1465 "expected: 8, got: ", mi_lv.len);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001466 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001467 }
1468
1469 /* Make sure MI contains IMSI before referencing it */
1470 if (mi.typeOfIdentity != '001'B) {
1471 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
1472 "got: ", mi.typeOfIdentity);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001473 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001474 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
1475 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
1476 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001477 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001478 }
1479}
1480
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001481/* Test CS paging over the BTS<->PCU socket.
1482 * 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.
1483 * Paging should be send on the PACCH.
1484 *
1485 * 1. Send a Paging Request over PCU socket.
1486 * 2. Send a Ready-To-Send message over PCU socket
1487 * 3. Expect a Paging Frame
1488 */
1489testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
1490 var GsmRrMessage rr_imm_ass;
1491 var PacketUlAssign ul_tbf_ass;
1492 var RlcmacDlBlock dl_block;
1493 var boolean ok;
1494 var OCT4 tlli := '00000001'O;
1495 var MobileIdentityLV mi;
1496 var octetstring mi_enc_lv;
1497 var hexstring imsi := f_gen_imsi(42);
1498
1499 /* Initialize NS/BSSGP side */
1500 f_init_bssgp();
1501
1502 /* Initialize the PCU interface abstraction */
1503 f_init_raw(testcasename());
1504
1505 /* Establish BSSGP connection to the PCU */
1506 f_bssgp_establish();
1507 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1508
1509 /* Establish an Uplink TBF */
1510 ok := f_establish_tbf(rr_imm_ass);
1511 if (not ok) {
1512 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001513 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001514 }
1515
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001516 /* Make sure we've got an Uplink TBF assignment */
1517 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001518
1519 /* build mobile Identity */
1520 mi := valueof(ts_MI_IMSI_LV(imsi));
1521 mi_enc_lv := enc_MobileIdentityLV(mi);
1522 /* Send paging request */
1523 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
1524 sapi :=PCU_IF_SAPI_PDTCH));
1525
1526 /* Receive it on BTS side towards MS */
1527 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1528
1529 /* Make sure that Packet Paging Request contains the same IMSI */
1530 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1531
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001532 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001533}
1534
1535/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
1536 */
1537private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1538runs on RAW_PCU_Test_CT {
1539 var GsmRrMessage rr_imm_ass;
1540 var PacketUlAssign ul_tbf_ass;
1541 var RlcmacDlBlock dl_block;
1542 var boolean ok;
1543 var OCT4 tlli := '00000001'O;
1544 var hexstring imsi := f_gen_imsi(42);
1545 var GsmTmsi tmsi;
1546
1547 /* Initialize NS/BSSGP side */
1548 f_init_bssgp();
1549
1550 /* Initialize the PCU interface abstraction */
1551 f_init_raw(testcasename());
1552
1553 /* Establish BSSGP connection to the PCU */
1554 f_bssgp_establish();
1555 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1556
1557 /* Establish an Uplink TBF */
1558 ok := f_establish_tbf(rr_imm_ass);
1559 if (not ok) {
1560 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001561 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001562 }
1563
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001564 /* Make sure we've got an Uplink TBF assignment */
1565 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001566
1567 /* Send paging request with or without TMSI */
1568 if (use_ptmsi) {
1569 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
1570 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
1571 } else {
1572 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
1573 }
1574
1575 /* Receive it on BTS side towards MS */
1576 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1577
1578 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
1579 if (use_ptmsi) {
1580 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
1581 } else {
1582 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1583 }
1584
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001585 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001586}
1587
1588testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1589 f_tc_paging_cs_from_sgsn(0, true);
1590}
1591
1592testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1593 f_tc_paging_cs_from_sgsn(0);
1594}
1595
1596testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1597 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
1598}
1599
1600/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
1601 */
1602private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1603runs on RAW_PCU_Test_CT {
1604 var OCT4 tlli := '00000001'O;
1605 var integer imsi_suff_tx := 423;
1606 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
1607
1608 /* Initialize NS/BSSGP side */
1609 f_init_bssgp();
1610
1611 /* Initialize the PCU interface abstraction */
1612 f_init_raw(testcasename());
1613
1614 /* Establish BSSGP connection to the PCU */
1615 f_bssgp_establish();
1616 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1617
1618 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
1619 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
1620 if (use_ptmsi) {
1621 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
1622 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
1623 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
1624 } else {
1625 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
1626 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
1627 }
1628
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001629 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001630}
1631
1632testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1633 f_tc_paging_ps_from_sgsn(0, true);
1634}
1635
1636testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1637 f_tc_paging_ps_from_sgsn(0);
1638}
1639
1640testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1641 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
1642}
1643
1644private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
1645 template GsmRrMessage t_imm_ass := ?,
1646 PCUIF_BurstType bt := BURST_TYPE_1)
1647runs on RAW_PCU_Test_CT {
1648 var GsmRrMessage rr_msg;
1649 var uint16_t ra11;
1650 var boolean ok;
1651
1652 ra11 := enc_EGPRSPktChRequest2uint(req);
1653 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
1654
1655 ok := f_establish_tbf(rr_msg, ra := ra11, is_11bit := 1, burst_type := bt);
1656 if (not ok) {
1657 setverdict(fail, "Failed to establush an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001658 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001659 }
1660
1661 if (not match(rr_msg, t_imm_ass)) {
1662 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001663 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001664 }
1665
1666 setverdict(pass);
1667}
1668
1669testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
1670 var template GsmRrMessage imm_ass;
1671 var template IaRestOctets rest;
1672 var template EgprsUlAss ul_ass;
1673
1674 /* Initialize the PCU interface abstraction */
1675 f_init_raw(testcasename());
1676
1677 var EGPRSPktChRequest req := {
1678 /* NOTE: other fields are set in the loop */
1679 signalling := { tag := '110011'B }
1680 };
1681
1682 for (var integer i := 0; i < 6; i := i + 1) {
1683 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1684 req.signalling.random_bits := ext_ra;
1685
1686 /* For signalling, do we expect Multiblock UL TBF Assignment? */
1687 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
1688 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1689 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1690
1691 f_TC_egprs_pkt_chan_req(req, imm_ass);
1692 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001693
1694 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001695}
1696
1697testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
1698 var template GsmRrMessage imm_ass;
1699 var template IaRestOctets rest;
1700 var template EgprsUlAss ul_ass;
1701
1702 /* Initialize the PCU interface abstraction */
1703 f_init_raw(testcasename());
1704
1705 var EGPRSPktChRequest req := {
1706 /* NOTE: other fields are set in the loop */
1707 one_phase := { tag := '0'B }
1708 };
1709
1710 for (var integer i := 0; i < 6; i := i + 1) {
1711 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1712 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
1713 var BIT2 priority := substr(ext_ra, 0, 2);
1714 var BIT3 rand := substr(ext_ra, 2, 3);
1715
1716 req.one_phase.multislot_class := mslot_class;
1717 req.one_phase.priority := priority;
1718 req.one_phase.random_bits := rand;
1719
1720 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
1721 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
1722 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1723 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1724
1725 f_TC_egprs_pkt_chan_req(req, imm_ass);
1726 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001727
1728 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001729}
1730
1731testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
1732 var template GsmRrMessage imm_ass;
1733 var template IaRestOctets rest;
1734 var template EgprsUlAss ul_ass;
1735
1736 /* Initialize the PCU interface abstraction */
1737 f_init_raw(testcasename());
1738
1739 var EGPRSPktChRequest req := {
1740 /* NOTE: other fields are set in the loop */
1741 two_phase := { tag := '110000'B }
1742 };
1743
1744 for (var integer i := 0; i < 6; i := i + 1) {
1745 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1746 var BIT2 priority := substr(ext_ra, 0, 2);
1747 var BIT3 rand := substr(ext_ra, 2, 3);
1748
1749 req.two_phase.priority := priority;
1750 req.two_phase.random_bits := rand;
1751
1752 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
1753 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
1754 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1755 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1756
1757 f_TC_egprs_pkt_chan_req(req, imm_ass);
1758 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001759
1760 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001761}
1762
1763control {
1764 execute( TC_pcuif_suspend() );
1765 execute( TC_ta_ptcch_idle() );
1766 execute( TC_ta_rach_imm_ass() );
1767 execute( TC_ta_idle_dl_tbf_ass() );
1768 execute( TC_ta_ptcch_ul_multi_tbf() );
1769 execute( TC_cs_lqual_ul_tbf() );
1770 execute( TC_cs_initial_ul() );
1771 execute( TC_cs_max_ul() );
1772 execute( TC_t3169() );
1773 execute( TC_t3193() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001774 execute( TC_countdown_procedure() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001775 execute( TC_mo_ping_pong() );
1776 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001777 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001778 execute( TC_mt_ping_pong() );
1779 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001780 execute (TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001781 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001782 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001783 execute( TC_paging_cs_from_bts() );
1784 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
1785 execute( TC_paging_cs_from_sgsn_sign() );
1786 execute( TC_paging_cs_from_sgsn_ptp() );
1787 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
1788 execute( TC_paging_ps_from_sgsn_sign() );
1789 execute( TC_paging_ps_from_sgsn_ptp() );
1790
1791 /* EGPRS specific test cases */
1792 execute( TC_egprs_pkt_chan_req_signalling() );
1793 execute( TC_egprs_pkt_chan_req_one_phase() );
1794 execute( TC_egprs_pkt_chan_req_two_phase() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001795
1796 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001797}
1798
1799
1800
1801
1802
1803
Harald Weltea419df22019-03-21 17:23:04 +01001804}