blob: f5176d4095710fb4cfe8dc745e1784e3768a609d [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 */
Vadim Yanitskiyf77421f2020-07-19 16:08:24 +070062friend template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
Vadim Yanitskiyc1559302020-07-19 16:39:12 +070063 version := PCUIF_Types.mp_pcuif_version,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020064 flags := c_PCUIF_Flags_default,
Vadim Yanitskiy9e1206c2020-07-19 15:52:31 +070065 trx := f_PCUIF_ver_INFO_Trxs(),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020066 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 },
Vadim Yanitskiy0d590802020-08-21 00:14:22 +070093 local_port := { mp_nsconfig.remote_udp_port, 0 },
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020094 remote_port := { mp_nsconfig.local_udp_port, 0 },
Alexander Couzens1e5dc482020-07-28 15:38:46 +020095 remote_addr := f_PCUIF_ver_INFO_RemoteAddr(
96 mp_nsconfig.remote_proto, mp_nsconfig.local_ip)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020097}
98
99type record lqual_range {
100 /* component reference to the IPA_Client component used for RSL */
101 uint8_t low,
102 uint8_t high
103}
104
Pau Espin Pedrolaedc5112020-05-16 17:30:42 +0200105type component RAW_PCU_Test_CT extends bssgp_CT, MS_BTS_IFACE_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700106 /* PCU interface abstraction component */
107 var RAW_PCUIF_CT vc_PCUIF;
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700108
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200109 /* Connection to the PCUIF component */
110 port RAW_PCU_MSG_PT PCUIF;
111 /* VTY connection to the PCU */
112 port TELNETasp_PT PCUVTY;
113
114 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
115 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
116 {low := 5, high := 8},
117 {low := 7, high := 13},
118 {low := 12,high := 35}};
119 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
120 {low := 5, high := 8},
121 {low := 7, high := 13},
122 {low := 12,high := 15},
123 {low := 14, high := 17},
124 {low := 16, high := 18},
125 {low := 17,high := 20},
126 {low := 19, high := 24},
127 {low := 23,high := 35}};
128 var uint8_t g_cs_initial_dl := 1;
129 var uint8_t g_cs_initial_ul := 1;
130 var uint8_t g_mcs_initial_dl := 1;
131 var uint8_t g_mcs_initial_ul := 1;
132 var uint8_t g_cs_max_dl := 4;
133 var uint8_t g_cs_max_ul := 4;
134 var uint8_t g_mcs_max_dl := 9;
135 var uint8_t g_mcs_max_ul := 9;
136
137 var boolean g_egprs_only := false;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200138 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200139
140 /* Guard timeout */
141 timer g_T_guard := 60.0;
142};
143
144private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
145 [] g_T_guard.timeout {
146 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700147 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200148 }
149}
150
151private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
152 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
153 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
154
155 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
156 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
157}
158
159private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
160 var charstring cmd;
161
162 cmd := "cs link-quality-ranges" &
163 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
164 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
165 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
166 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
167 f_vty_config2(PCUVTY, {"pcu"}, cmd);
168
169 cmd := "mcs link-quality-ranges" &
170 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
171 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
172 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
173 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
174 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
175 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
176 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
177 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
178 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
179 f_vty_config2(PCUVTY, {"pcu"}, cmd);
180}
181
182private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
183 map(self:PCUVTY, system:PCUVTY);
184 f_vty_set_prompts(PCUVTY);
185 f_vty_transceive(PCUVTY, "enable");
186
187 if (g_egprs_only) {
188 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
189 } else {
190 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
191 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200192
193 if (g_force_two_phase_access) {
194 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
195 } else {
196 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
197 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200198}
199
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200200function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200201runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200202 /* Start the guard timer */
203 g_T_guard.start;
204 activate(as_Tguard_RAW());
205
206 /* Init PCU interface component */
207 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
208 connect(vc_PCUIF:MTC, self:PCUIF);
209 map(vc_PCUIF:PCU, system:PCU);
210
211 /* Create one BTS component (we may want more some day) */
212 vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
213 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
214 connect(vc_BTS:TC, self:BTS);
215
216 f_init_vty(id);
217
218 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
219 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
220
221 /* Wait until the BTS is ready (SI13 negotiated) */
222 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
223}
224
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200225testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
226 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
227 var GprsTlli tlli := 'FFFFFFFF'O;
228 timer T;
229
230 /* Initialize NS/BSSGP side */
231 f_init_bssgp();
232
233 /* Initialize the PCU interface abstraction */
234 f_init_raw(testcasename());
235
236 /* Establish BSSGP connection to the PCU */
237 f_bssgp_establish();
238
239 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
240
241 T.start(2.0);
242 alt {
243 [] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
244 setverdict(pass);
245 }
246 [] T.timeout {
247 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
248 }
249 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700250
251 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200252}
253
254/* Test of correct Timing Advance at the time of TBF establishment
255 * (derived from timing offset of the Access Burst). */
256testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200257 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200258
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200259 /* Initialize GPRS MS side */
260 f_init_gprs_ms();
261 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200262 /* Initialize the PCU interface abstraction */
263 f_init_raw(testcasename());
264
265 /* We cannot send too many TBF requests in a short time because
266 * at some point the PCU will fail to allocate a new TBF. */
267 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
268 /* Establish an Uplink TBF (send RACH.ind with current TA) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200269 ms.ta := ta;
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700270 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200271
272 /* Make sure Timing Advance IE matches out expectations */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200273 if (ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance != ta) {
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700274 setverdict(fail, "Timing Advance mismatch: ",
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200275 ms.ul_tbf.rr_imm_ass.payload.imm_ass.timing_advance,
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700276 " 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 {
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700289 var OCT4 tlli := f_rnd_octstring(4);
290 var GsmRrMessage rr_imm_ass;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200291
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();
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700300 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200301
302 /* SGSN sends some DL data, PCU will initiate Packet Downlink
303 * Assignment on CCCH (PCH). We don't care about the payload. */
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700304 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
305 rr_imm_ass := f_pcuif_rx_imm_ass(PCU_IF_SAPI_PCH, tr_IMM_TBF_ASS(dl := true));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200306
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. */
Vadim Yanitskiy84d1dd52020-05-28 21:09:22 +0700310 if (rr_imm_ass.payload.imm_ass.timing_advance != 0) {
311 setverdict(fail, "Timing Advance value doesn't match");
312 }
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;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200463 var GprsMS ms;
464
465 /* Initialize GPRS MS side */
466 f_init_gprs_ms();
467 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200468
469 /* Initialize the PCU interface abstraction */
470 f_init_raw(testcasename());
471
472 /* Enable forwarding of PTCCH/U TDMA events to us */
473 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
474
475 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
476 for (var integer i := 0; i < 7; i := i + 1) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200477 /* Establish an Uplink TBF */
478 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200479
480 /* We expect incremental TFI/USF assignment (dynamic allocation) */
481 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200482 if (not match(ms.ul_tbf.ass.ccch, t_ul_tbf_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200483 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700484 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200485 }
486
487 /* We also expect Timing Advance Index to be a part of the assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200488 if (ms.ul_tbf.ass.ccch.dynamic.ta_index != i) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200489 setverdict(fail, "Failed to match Timing Advance Index for #", i);
490 /* Keep going, the current OsmoPCU does not assign TA Index */
491 }
492 }
493
494 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
495 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
496 for (var integer i := 0; i < 7; i := i + 1) {
497 /* ToA in units of 1/4 of a symbol */
498 toa_map[i] := (i + 1) * 7 * 4;
499 }
500
501 /* Now we have all 7 TBFs established in one-phase access mode,
502 * however we will not be sending any data on them. Instead, we
503 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
504 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
505 *
506 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
507 * time-slots, so at the moment of scheduling a PTCCH/D block
508 * the PCU has odd number of PTCCH/U Access Bursts received. */
509 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
510 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
511 /* Other values are not known (yet) */
512 tai3_ta := ?));
513 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
514 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
515 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
516 /* Other values are out of our interest */
517 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700518
519 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200520}
521
522/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
523 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
524 *
525 * NOTE: the ranges are intentionally overlapping because OsmoPCU
526 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
527private template integer CS1_lqual_dB_range := (-infinity .. 6);
528private template integer CS2_lqual_dB_range := (5 .. 8);
529private template integer CS3_lqual_dB_range := (7 .. 13);
530private template integer CS4_lqual_dB_range := (12 .. infinity);
531
532testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200533 var RlcmacDlBlock dl_block;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200534 var GprsMS ms;
535 var uint32_t unused_fn, sched_fn;
536 var uint4_t cv;
537
538 /* Initialize GPRS MS side */
539 f_init_gprs_ms();
540 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200541
542 /* Initialize the PCU interface abstraction */
543 f_init_raw(testcasename());
544
545 f_pcuvty_set_allowed_cs_mcs();
546 f_pcuvty_set_link_quality_ranges();
547
548 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200549 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200550
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200551
552 /* The actual / old link quality values. We need to keep track of the old
553 * (basically previous) link quality value, because OsmoPCU actually
554 * changes the coding scheme if not only the actual, but also the old
555 * value leaves the current link quality range (window). */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200556 var integer lqual_old;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200557 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200558
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200559 /* Send one UL block (with TLLI since we are in One-Phase Access
560 contention resoultion) and make sure it is ACKED fine. */
561 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
562 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
563 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
564 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
565 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
566 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200567
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200568 /* 16 UL blocks (0 .. 15 dB, step = 1 cB) */
569 for (var integer i := 150; i >= 0; i := i - 1) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200570 /* Update the old / actual link quality */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200571 lqual_old := ms.lqual_cb;
572 ms.lqual_cb := 150 - i;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200573
574 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200575 log("Sending DATA.ind with link quality (dB): ", ms.lqual_cb);
576 if (i > g_bs_cv_max) {
577 cv := 15;
578 } else {
579 cv := i;
580 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200581
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200582 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := cv)
583
584 /* we will receive UL ACK/NACK from time to time. In that case, check CdCofing increases */
585 f_rx_rlcmac_dl_block(dl_block, unused_fn);
586 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
587 continue;
588 }
589 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
590 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
591 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
592 f_shutdown(__BFILE__, __LINE__);
593 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200594
595 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
596 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
597
598 /* Match the received Channel Coding Command. Since we are increasing
599 * the link quality value on each iteration and not decreasing, there
600 * is no need to check the both old and current link quality values. */
601 var template ChCodingCommand ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200602 select (lqual_old / 10) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200603 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
604 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
605 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
606 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
607 }
608
609 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
610 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200611 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200612 }
613 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700614
615 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200616}
617
618/* Test the max UL CS set by VTY works fine */
619testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200620 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200621 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200622 var uint32_t unused_fn, sched_fn;
623 var GprsMS ms;
624
625 /* Initialize GPRS MS side */
626 f_init_gprs_ms();
627 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200628
629 /* Initialize the PCU interface abstraction */
630 f_init_raw(testcasename());
631
632 /* Set initial UL CS to 3 */
633 g_cs_initial_ul := 3;
634 f_pcuvty_set_allowed_cs_mcs();
635 f_pcuvty_set_link_quality_ranges();
636
637 /* Take lqual (dB->cB) so that we stay in that CS */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200638 ms.lqual_cb := g_cs_lqual_ranges[2].low * 10;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200639
640 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200641 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200642
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200643 /* Send one UL block (with TLLI since we are in One-Phase Access
644 contention resoultion) and make sure it is ACKED fine. */
645 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
646 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
647 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
648 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
649 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
650 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200651
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200652 /* Send UL blocks, until we receive UL ACK/NACK and check we are in same initial CS: */
653 while (true) {
654 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 15);
655 f_rx_rlcmac_dl_block(dl_block, unused_fn);
656 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
657 continue;
658 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200659
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200660 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
661 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
662 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
663 f_shutdown(__BFILE__, __LINE__);
664 break;
665 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200666
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200667 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200668 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200669 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200670 if (last_ch_coding != CH_CODING_CS3) {
671 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200672 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200673 }
674
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200675 /* Remaining UL blocks are used to make sure regardless of initial
676 /* lqual, we can go lower at any time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200677 /* 0 dB, make sure we downgrade CS */
678 ms.lqual_cb := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200679 /* 5 UL blocks, check we are in same initial CS: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200680 f_ms_tx_ul_data_block_multi(ms, 5);
681 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
682 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
683 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200684
685 if (last_ch_coding != CH_CODING_CS1) {
686 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200687 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200688 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700689
690 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200691}
692
693/* Test the max UL CS set by VTY works fine */
694testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200695 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200696 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200697 var uint32_t unused_fn, sched_fn;
698 var GprsMS ms;
699
700 /* Initialize GPRS MS side */
701 f_init_gprs_ms();
702 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200703
704 /* Initialize the PCU interface abstraction */
705 f_init_raw(testcasename());
706
707 /* Set maximum allowed UL CS to 3 */
708 g_cs_max_ul := 3;
709 f_pcuvty_set_allowed_cs_mcs();
710 f_pcuvty_set_link_quality_ranges();
711
712 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200713 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200714
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200715 /* Send one UL block (with TLLI since we are in One-Phase Access
716 contention resoultion) and make sure it is ACKED fine. */
717 /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
718 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
719 f_ms_tx_ul_data_block(ms, f_rnd_octstring(16), cv := 15, with_tlli := true)
720 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
721 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
722 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200723
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200724 ms.lqual_cb := 40*10; /* 40 dB */
725 f_ms_tx_ul_data_block_multi(ms, 16);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200726
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200727 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
728 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200729
730 if (last_ch_coding != CH_CODING_CS3) {
731 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol1617e312020-05-22 14:41:14 +0200732 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200733 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700734
735 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200736}
737
738/* Verify PCU drops TBF after some time of inactivity. */
739testcase TC_t3169() runs on RAW_PCU_Test_CT {
740 var PCUIF_info_ind info_ind;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200741 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200742 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200743 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200744
745 /* Initialize NS/BSSGP side */
746 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200747 /* Initialize GPRS MS side */
748 f_init_gprs_ms();
749 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200750
751 info_ind := valueof(ts_PCUIF_INFO_default);
752 /* Set timer to 1 sec (default 5) to speedup test: */
753 info_ind.t3169 := 1;
754
755 /* Initialize the PCU interface abstraction */
756 f_init_raw(testcasename(), info_ind);
757
758 /* Establish BSSGP connection to the PCU */
759 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200760 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200761
762 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200763 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200764
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +0200765 /* Send one UL block (with TLLI since we are in One-Phase Access
766 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200767 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 1, with_tlli := true)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200768 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200769 /* UL block should NOT be received in SGSN, since we didn't get CV=0 */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200770
771 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
772 f_sleep(int2float(info_ind.t3169) + 1.0);
773
774 /* Send an UL block once again, the TBF should be gone by now so no ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200775 f_ms_tx_ul_data_block(ms, f_rnd_octstring(10), cv := 0)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200776 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700777
778 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200779}
780
781/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
782 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
783 * T3193) after DL TBF release */
784testcase TC_t3193() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200785 var RlcmacDlBlock dl_block;
786 var octetstring data := f_rnd_octstring(10);
787 var boolean ok;
788 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700789 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200790 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200791 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
792
793 /* Initialize NS/BSSGP side */
794 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200795 /* Initialize GPRS MS side */
796 f_init_gprs_ms();
797 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200798
799 /* Initialize the PCU interface abstraction */
800 f_init_raw(testcasename());
801
802 /* Establish BSSGP connection to the PCU */
803 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200804 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200805
806 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200807 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
808 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700809
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200810 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
811 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700812 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200813
814 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200815 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
816 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
817 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200818
819 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200820 (T3192 in MS) was started and until it fires the MS will be available
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200821 on PDCH in case new data arrives from SGSN. Let's verify it: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200822 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +0700823 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200824
825 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200826
827 /* 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 +0700828 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200829 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
830 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
831 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700832
833 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200834}
835
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200836/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
837testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200838 var RlcmacDlBlock dl_block;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200839 var uint32_t sched_fn;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200840 var octetstring total_payload;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200841 var GprsMS ms;
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200842
843 /* Initialize NS/BSSGP side */
844 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200845 /* Initialize GPRS MS side */
846 f_init_gprs_ms();
847 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200848
849 /* Initialize the PCU interface abstraction */
850 f_init_raw(testcasename());
851
852 /* Establish BSSGP connection to the PCU */
853 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200854 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200855
856 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200857 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200858
859 /* Send one UL block (with TLLI since we are in One-Phase Access
860 contention resoultion) and make sure it is ACKED fine. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200861 total_payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
862 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
863 f_ms_tx_ul_data_block(ms, total_payload, cv := 15, with_tlli := true)
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200864 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
865 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200866 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200867
868 /* Send enough blocks to test whole procedure: Until Nth block
869 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
870 */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200871 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, 20);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200872 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
873 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200874 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200875
876 /* receive one message on BSSGP with all aggregated data in payload: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +0200877 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, total_payload));
Pau Espin Pedrol487d6342020-05-14 19:22:33 +0200878}
879
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +0200880/* Verify PCU handles correctly CS1..4 with all possible LLC payload sizes fitting alone in one RLC block */
881testcase TC_ul_all_sizes() runs on RAW_PCU_Test_CT {
882 var RlcmacDlBlock dl_block;
883 var uint32_t dl_fn, sched_fn;
884 var octetstring payload;
885 var template (value) RlcmacUlBlock ul_data;
886 var GprsMS ms;
887
888 /* Initialize NS/BSSGP side */
889 f_init_bssgp();
890 /* Initialize GPRS MS side */
891 f_init_gprs_ms();
892 ms := g_ms[0]; /* We only use first MS in this test */
893
894 /* Initialize the PCU interface abstraction */
895 f_init_raw(testcasename());
896
897 /* Establish BSSGP connection to the PCU */
898 f_bssgp_establish();
899 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
900
901 /* Establish an Uplink TBF */
902 f_ms_establish_ul_tbf(ms);
903
904 /* Send one UL block (with TLLI since we are in One-Phase Access
905 contention resoultion) and make sure it is ACKED fine. */
906 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
907 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
908 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
909 cv := 15,
910 bsn := ms.ul_tbf.bsn,
911 blocks := { t_RLCMAC_LLCBLOCK(payload,
912 t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload), more := false, e := true))
913 },
914 tlli := ms.tlli);
915 f_ultbf_inc_bsn(ms.ul_tbf);
916 f_ms_tx_ul_block(ms, ul_data);
917
918 /* ACK and check it was received fine */
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_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
922 /* receive one message on BSSGP with all aggregated data in payload: */
923 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, payload));
924
925 /* Test sending LLC PDUS of incrementing size */
926 var integer max_size := 49;
927 for (var integer i := 1; i <= max_size; i := i + 1) {
928 var integer cv;
929 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
930 log("Sending DATA.ind with LLC payload size ", i);
931 if (i < max_size - g_bs_cv_max) {
932 cv := 15;
933 } else {
934 cv := max_size - i;
935 }
936
937 payload := f_rnd_octstring(i);
938 /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
939 ul_data := t_RLCMAC_UL_DATA(tfi := ms.ul_tbf.tfi,
940 cv := cv,
941 bsn := ms.ul_tbf.bsn,
942 blocks := { t_RLCMAC_LLCBLOCK(payload,
943 t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload), more := false, e := true))
944 });
945 f_ultbf_inc_bsn(ms.ul_tbf);
946 f_ms_tx_ul_block(ms, ul_data);
947
948 /* receive one message on BSSGP with all aggregated data in payload: */
949 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, payload));
950
951 /* we will receive UL ACK/NACK from time to time, handle it. */
952 f_rx_rlcmac_dl_block(dl_block, dl_fn);
953 if (match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
954 continue;
955 }
956 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK_GPRS(ul_tfi := ?)) and
957 not match(dl_block, tr_RLCMAC_UL_ACK_NACK_EGPRS(ul_tfi := ?))) {
958 setverdict(fail, "Failed to match Packet Uplink ACK / NACK:", dl_block);
959 f_shutdown(__BFILE__, __LINE__);
960 }
961
962 log("Rx Packet Uplink ACK / NACK");
963 sched_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
964 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
965 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
966 }
967 setverdict(pass);
968}
969
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +0200970function f_TC_ul_data_toolong_fills_padding_cs(inout GprsMS ms, CodingScheme cs, integer cv) runs on RAW_PCU_Test_CT {
971 var octetstring payload;
972 var template (value) RlcmacUlBlock ul_data;
973 var integer block_len, max_valid_data_len;
974 timer T;
975
976 block_len := f_rlcmac_cs_mcs2block_len(cs);
977 /* We need to send with TLLI since we are in One-Phase Access Contenion
978 * resoultion), so that's -4 bytes of data, -3 for headers, -1 for LI
979 * indicator, -1 for spare bits octet at the end */
980 max_valid_data_len := block_len - 4 - 3 - 1 - 1;
981 payload := f_rnd_octstring(max_valid_data_len + 1); /* +1 to write LLC data on last padding octet */
982 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
983 cv := cv,
984 bsn := ms.ul_tbf.bsn,
985 blocks := { t_RLCMAC_LLCBLOCK(payload,
986 t_RLCMAC_LLCBLOCK_HDR(length_ind := lengthof(payload), more := false, e := true))
987 },
988 tlli := ms.tlli);
989 f_ultbf_inc_bsn(ms.ul_tbf);
990 f_ms_tx_data_ind(ms, enc_RlcmacUlBlock(valueof(ul_data)));
991
992 T.start(0.5);
993 alt {
994 [] BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, ?)) {
995 setverdict(fail, "LLC PDU in Malformed RLC block was forwarded");
996 f_shutdown(__BFILE__, __LINE__);
997 }
998 [] T.timeout {
999 setverdict(pass);
1000 }
1001 }
1002}
1003/* Verify PCU finds out incorrectly formated RLC block and discards it. This
1004 blocks intentionally contain last byte of data placed in last byte of RLC
1005 containing padding/spare bits, which is incorrect. Spare bits exist and are
1006 described for CS2..4 in 3GPP TS 44.060 Table 10.2.1: "RLC data block size,
1007 discounting padding in octet" */
1008testcase TC_ul_data_toolong_fills_padding() runs on RAW_PCU_Test_CT {
1009 var GprsMS ms;
1010 var integer block_len, max_valid_data_len;
1011
1012 /* Initialize NS/BSSGP side */
1013 f_init_bssgp();
1014 /* Initialize GPRS MS side */
1015 f_init_gprs_ms();
1016 ms := g_ms[0]; /* We only use first MS in this test */
1017
1018 /* Initialize the PCU interface abstraction */
1019 f_init_raw(testcasename());
1020
1021 /* Establish BSSGP connection to the PCU */
1022 f_bssgp_establish();
1023 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
1024
1025 /* Establish an Uplink TBF */
1026 f_ms_establish_ul_tbf(ms);
1027
1028 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_2, 2);
1029 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_3, 1);
1030 f_TC_ul_data_toolong_fills_padding_cs(ms, CS_4, 0);
1031
1032 setverdict(pass);
1033}
1034
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001035/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1036 * answered, so TBFs for uplink and later for downlink are created.
1037 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001038private 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 +02001039 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001040 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001041 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001042 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001043 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001044
1045 /* Initialize NS/BSSGP side */
1046 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001047 /* Initialize GPRS MS side */
1048 f_init_gprs_ms();
1049 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001050
1051 /* Initialize the PCU interface abstraction */
1052 f_init_raw(testcasename());
1053
1054 /* Establish BSSGP connection to the PCU */
1055 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001056 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001057
1058 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001059 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001060
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001061 /* Send one UL block (with TLLI since we are in One-Phase Access
1062 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001063 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001064 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1065 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001066 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001067
1068 /* UL block should be received in SGSN */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001069 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001070
1071 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001072 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1073 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001074
1075 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1076 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001077 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001078
1079 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001080 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1081 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1082 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001083
1084 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001085}
1086
1087/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1088 * answered, so TBFs for uplink and later for downlink are created.
1089 */
1090testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
1091 var CodingScheme exp_cs_mcs := CS_1;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001092 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001093}
1094
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001095/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1096 * answered, so TBFs for uplink and later for downlink are created.
1097 */
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001098private function f_TC_mo_ping_pong_2phase_access(template (value) MSRadioAccessCapabilityV ms_racap,
1099 template (present) CodingScheme exp_ul_cs_mcs := ?,
1100 template (present) CodingScheme exp_dl_cs_mcs := ?)
1101runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001102 var RlcmacDlBlock dl_block;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001103 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001104 var uint32_t sched_fn;
1105 var uint32_t dl_fn;
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001106 var uint32_t unused_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001107 var GprsMS ms;
1108
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001109 /* 0111 0xxx: Single block packet access; one block period on a PDCH is needed for two phase packet access or other RR signalling purpose. */
1110 var uint16_t ra := oct2int('70'O);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001111 if (g_force_two_phase_access) {
1112 /* If 2phase access is enforced by the network, then let's
1113 request a One phase packet access, we'll receive a single block
1114 anyway */
1115 ra := bit2int(chan_req_def);
1116 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001117
1118 /* Initialize NS/BSSGP side */
1119 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001120 /* Initialize GPRS MS side */
1121 f_init_gprs_ms();
1122 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001123
1124 /* Initialize the PCU interface abstraction */
1125 f_init_raw(testcasename());
1126
1127 /* Establish BSSGP connection to the PCU */
1128 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001129 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001130
1131 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001132 f_ms_use_ra(ms, ra, ra_is_11bit := 0);
1133 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001134
1135 /* Make sure we've got an Uplink TBF assignment */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001136 if (not match(ms.ul_tbf.ass.ccch, tr_PacketUlSglAssign)) {
1137 setverdict(fail, "Wrong Packet Uplink Assignment received: ", ms.ul_tbf.ass.ccch, " vs exp: ", tr_PacketUlSglAssign);
1138 f_shutdown(__BFILE__, __LINE__);
1139 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001140
1141 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
1142 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
1143 */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07001144 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, ms_racap)), 0);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001145 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001146 if (not match(ms.ul_tbf.tx_cs_mcs, exp_ul_cs_mcs)) {
1147 setverdict(fail, "Wrong CS_MCS ", ms.ul_tbf.tx_cs_mcs, " received vs exp ", exp_ul_cs_mcs);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001148 f_shutdown(__BFILE__, __LINE__);
1149 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001150
1151 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1152 and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001153 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true); /* TODO: send using cs_mcs */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001154
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001155 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001156 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001157
1158 /* UL block should be received in SGSN */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001159 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001160
1161 /* Now SGSN sends some DL data, PCU will page on PACCH */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001162 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001163 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_DL_PACKET_ASS);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001164 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001165 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001166
Pau Espin Pedroladbbe1e2020-05-17 00:28:01 +02001167 /* PCU acks the UL data after having received CV=0) */
1168 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1169
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001170 /* 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 +02001171 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 +02001172
1173 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001174 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1175 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.ul_tbf.tfi, ms.dl_tbf.acknack_desc),
1176 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001177
1178 f_shutdown(__BFILE__, __LINE__, final := true);
1179}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001180
1181testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1182 var MultislotCap_GPRS mscap_gprs := {
1183 gprsmultislotclass := '00011'B,
1184 gprsextendeddynalloccap := '0'B
1185 };
1186 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001187 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1188 var CodingScheme exp_dl_cs_mcs := CS_2;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001189
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001190 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1191}
1192
1193testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
1194 /* Initialize the PCU interface abstraction with EGPRS-only */
1195 g_egprs_only := true;
1196
1197 var MultislotCap_GPRS mscap_gprs := {
1198 gprsmultislotclass := '00011'B,
1199 gprsextendeddynalloccap := '0'B
1200 };
1201 var MultislotCap_EGPRS mscap_egprs := {
1202 egprsmultislotclass := '00011'B,
1203 egprsextendeddynalloccap := '0'B
1204 };
1205 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1206 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1207 var CodingScheme exp_dl_cs_mcs := MCS_1;
1208
1209 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 +02001210}
1211
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001212testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
1213 /* Configure PCU to force two phase access */
1214 g_force_two_phase_access := true;
1215
1216 var MultislotCap_GPRS mscap_gprs := {
1217 gprsmultislotclass := '00011'B,
1218 gprsextendeddynalloccap := '0'B
1219 };
1220 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1221 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1222 var CodingScheme exp_dl_cs_mcs := CS_2;
1223
1224 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1225}
1226
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001227/* Test scenario where SGSN wants to send some data against MS and it is
1228 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1229 */
1230private 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 {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001231 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001232 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001233 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001234 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001235 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001236
1237 /* Initialize NS/BSSGP side */
1238 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001239 /* Initialize GPRS MS side */
1240 f_init_gprs_ms();
1241 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001242
1243 /* Initialize the PCU interface abstraction */
1244 f_init_raw(testcasename());
1245
1246 /* Establish BSSGP connection to the PCU */
1247 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001248 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001249
1250 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001251 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, ms_racap));
1252 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001253
1254 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1255 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001256 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001257
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02001258 /* ACK the DL block, and request UL TBF at the same time */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001259 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02001260 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK_CHREQ(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001261 f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001262
Pau Espin Pedrol6791eb62020-05-20 18:27:10 +02001263 /* Expect UL ass */
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001264 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001265
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001266 /* Send one UL block (with TLLI since we are in One-Phase Access
1267 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001268 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001269 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1270 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001271 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001272
1273 /* UL block should be received in SGSN */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001274 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001275
1276 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001277}
1278
1279testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
1280 var CodingScheme exp_cs_mcs := CS_1;
1281 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1282}
1283
1284/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1285/* information about the MS */
1286testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1287 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1288 gprsmultislotclass := '00011'B,
1289 gprsextendeddynalloccap := '0'B
1290 } ;
1291 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
1292 var CodingScheme exp_cs_mcs := CS_2;
1293 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1294}
1295
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001296/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
1297 * TBF, it will request retransmission through UL ACK/NACK (with missing block
1298 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
1299 * be transferred).
1300 */
1301testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001302 var RlcmacDlBlock dl_block;
1303 var template (value) RlcmacUlBlock ul_data;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001304 var uint32_t sched_fn;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001305 var octetstring total_payload;
1306 var octetstring payload;
1307 var octetstring lost_payload;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001308 var uint5_t tfi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001309 var GprsMS ms;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001310
1311 /* Initialize NS/BSSGP side */
1312 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001313 /* Initialize GPRS MS side */
1314 f_init_gprs_ms();
1315 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001316
1317 /* Initialize the PCU interface abstraction */
1318 f_init_raw(testcasename());
1319
1320 /* Establish BSSGP connection to the PCU */
1321 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001322 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001323
1324 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001325 f_ms_establish_ul_tbf(ms);
1326 tfi := ms.ul_tbf.tfi;
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001327
1328 /* Send one UL block (with TLLI since we are in One-Phase Access
1329 contention resoultion) and make sure it is ACKED fine. */
1330 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001331 f_ms_tx_ul_data_block(ms, payload, cv := 15, with_tlli := true);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001332
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001333 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1334 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001335 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001336 total_payload := payload;
1337
1338 /* Send 2 packets, skip 1 (inc bsn) and send another one */
1339 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001340 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001341 total_payload := total_payload & payload;
1342
1343 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001344 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001345 total_payload := total_payload & payload;
1346
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001347 lost_payload := f_rnd_octstring(20);
1348 ms.ul_tbf.bsn := ms.ul_tbf.bsn + 1; /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001349 total_payload := total_payload & lost_payload;
1350
1351 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001352 f_ms_tx_ul_data_block(ms, payload, cv := 15);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001353 total_payload := total_payload & payload;
1354
1355 /* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001356 total_payload := total_payload & f_ms_tx_ul_data_block_multi(ms, g_bs_cv_max);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001357
1358 /* On CV=0, we'll receive a UL ACK asking about missing block */
1359 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1360 /* TODO: check ack ack bitmap (URBB) */
1361 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 3, blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001362 f_ms_tx_ul_block(ms, ul_data);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001363
1364 /* Now final ack is recieved */
1365 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1366 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001367 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001368
1369 /* receive one message on BSSGP with all aggregated data in payload: */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001370 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, total_payload));
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001371}
1372
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001373/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1374 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1375 * timeout occurs (specified by sent RRBP on DL block). */
1376testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001377 var RlcmacDlBlock dl_block;
1378 var octetstring data := f_rnd_octstring(10);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001379 var uint32_t dl_fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001380 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001381
1382 /* Initialize NS/BSSGP side */
1383 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001384 /* Initialize GPRS MS side */
1385 f_init_gprs_ms();
1386 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001387
1388 /* Initialize the PCU interface abstraction */
1389 f_init_raw(testcasename());
1390
1391 /* Establish BSSGP connection to the PCU */
1392 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001393 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001394
1395 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001396 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1397 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001398
1399 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1400 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001401 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001402
1403 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1404 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1405 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001406 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001407
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001408 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1409 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001410 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001411
1412 /* ACK the DL block */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001413 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1414 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1415 f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001416
1417 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001418}
1419
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001420/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1421testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1422 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1423 var octetstring data := f_rnd_octstring(16);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001424 var PacketDlAssign dl_tbf_ass;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001425 var RlcmacDlBlock dl_block;
1426 var uint32_t ack_fn;
1427 var uint32_t fn;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001428 var GprsMS ms;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001429 timer T := 5.0;
1430
1431 /* Initialize NS/BSSGP side */
1432 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001433 /* Initialize GPRS MS side */
1434 f_init_gprs_ms();
1435 ms := g_ms[0]; /* We only use first MS in this test */
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001436
1437 /* Initialize the PCU interface abstraction */
1438 f_init_raw(testcasename());
1439
1440 /* Establish BSSGP connection to the PCU */
1441 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001442 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001443
1444 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001445 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
1446 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001447
1448 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1449 f_sleep(X2002);
1450
1451 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
1452 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001453 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001454
1455 /* TDMA frame number on which we are supposed to send the ACK */
1456 ack_fn := f_dl_block_ack_fn(dl_block, fn);
1457
1458 /* SGSN sends more blocks during the indicated RRBP */
1459 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
1460 data := f_rnd_octstring(16); /* Random LLC data */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001461 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001462
1463 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
1464
1465 /* Make sure this block has the same TFI as was assigned
1466 * FIXME: this is only valid for GPRS, not EGPRS. */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001467 if (dl_block.data.mac_hdr.hdr_ext.tfi != ms.dl_tbf.tfi) {
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001468 setverdict(fail, "Rx DL data block with unexpected TFI: ",
1469 dl_block.data.mac_hdr.hdr_ext.tfi);
1470 f_shutdown(__BFILE__, __LINE__);
1471 }
1472
1473 /* Keep Ack/Nack description updated */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001474 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001475
1476 /* Break if this is the end of RRBP */
1477 if (fn == ack_fn) {
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001478 ms.dl_tbf.acknack_desc.final_ack := '1'B;
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001479 break;
1480 }
1481 }
1482
1483 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001484 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc), fn := fn);
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001485
1486 /* Make sure that the next block (after the Ack) is dummy */
1487 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
1488
1489 f_shutdown(__BFILE__, __LINE__, final := true);
1490}
1491
Pau Espin Pedrol05b6c172020-06-26 17:28:23 +02001492/* Verify Decoding and segmentation of UL LLC PDUs into RLC data blocks, OS#4559.
1493 * Check "GPRS from A-Z" slide "Example of LI-Field and E-Bit" page 186.
1494 * Check "3GPP TS 44.060" Annex B. */
1495testcase TC_ul_flow_multiple_llc_blocks() runs on RAW_PCU_Test_CT {
1496 var RlcmacDlBlock dl_block;
1497 var octetstring dataA := f_rnd_octstring(20);
1498 var octetstring dataB := f_rnd_octstring(13);
1499 var octetstring dataC := f_rnd_octstring(3);
1500 var octetstring dataD := f_rnd_octstring(12);
1501 var uint32_t sched_fn;
1502 var GprsMS ms;
1503 var template (value) RlcmacUlBlock ul_data;
1504
1505 /* Initialize NS/BSSGP side */
1506 f_init_bssgp();
1507 /* Initialize GPRS MS side */
1508 f_init_gprs_ms();
1509 ms := g_ms[0]; /* We only use first MS in this test */
1510
1511 /* Initialize the PCU interface abstraction */
1512 f_init_raw(testcasename());
1513
1514 /* Establish BSSGP connection to the PCU */
1515 f_bssgp_establish();
1516 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
1517
1518 /* Establish an Uplink TBF */
1519 f_ms_establish_ul_tbf(ms);
1520
1521 /* Summary of what's transmitted:
1522 * 1- UL RlcDataBlock(dataA) [BSN=0, CV=3]
1523 * 2- UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2]
1524 * 3- UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1]
1525 * 4- UL RlcDataBlock(dataD finishes) [BSN=3, CV=0]
1526 * And on SGSN we receive 4 packets, one for each LlcBlock dataA..D.
1527 * We'll also receive some UL ACK/NACK we need to reply with CTRL ACK.
1528 */
1529
1530 /* UL RlcDataBlock(dataA) [BSN=0, CV=3] */
1531 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
1532 cv := 3,
1533 bsn := ms.ul_tbf.bsn,
1534 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 0, 16)) },
1535 tlli := ms.tlli);
1536 /* Indicate no llc header, meaning first LLC block doesn't finish in current
1537 * RLCMAC block being sent. */
1538 ul_data.data.mac_hdr.e := true;
1539 f_ultbf_inc_bsn(ms.ul_tbf);
1540 f_ms_tx_ul_block(ms, ul_data);
1541
1542 /* UL RlcDataBlock(dataA finished, dataB starts) [BSN=1, CV=2] */
1543 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
1544 cv := 2,
1545 bsn := ms.ul_tbf.bsn,
1546 blocks := { t_RLCMAC_LLCBLOCK(substr(dataA, 16, 4),
1547 t_RLCMAC_LLCBLOCK_HDR(length_ind := 4, more := true, e := true)),
1548 t_RLCMAC_LLCBLOCK(substr(dataB, 0, 11))
1549 },
1550 tlli := ms.tlli);
1551 f_ultbf_inc_bsn(ms.ul_tbf);
1552 f_ms_tx_ul_block(ms, ul_data);
1553
1554 /* UL block dataA should be received in SGSN */
1555 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataA));
1556
1557 /* UL RlcDataBlock(dataB finished, dataC starts and finishes, dataD starts) [BSN=2, CV=1] */
1558 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
1559 cv := 1,
1560 bsn := ms.ul_tbf.bsn,
1561 blocks := { t_RLCMAC_LLCBLOCK(substr(dataB, 11, 2),
1562 t_RLCMAC_LLCBLOCK_HDR(length_ind := 2, more := true, e := false)),
1563 t_RLCMAC_LLCBLOCK(substr(dataC, 0, 3),
1564 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := true, e := true)),
1565 t_RLCMAC_LLCBLOCK(substr(dataD, 0, 9))
1566 },
1567 tlli := ms.tlli);
1568 f_ultbf_inc_bsn(ms.ul_tbf);
1569 f_ms_tx_ul_block(ms, ul_data);
1570
1571 /* UL block dataB and dataC should be received in SGSN */
1572 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataB));
1573 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataC));
1574
1575 /* UL RlcDataBlock(dataD finishes) [BSN=3, CV=0] */
1576 ul_data := t_RLCMAC_UL_DATA_TLLI(tfi := ms.ul_tbf.tfi,
1577 cv := 0,
1578 bsn := ms.ul_tbf.bsn,
1579 blocks := { t_RLCMAC_LLCBLOCK(substr(dataD, 9, 3),
1580 t_RLCMAC_LLCBLOCK_HDR(length_ind := 3, more := false, e := true))
1581 },
1582 tlli := ms.tlli);
1583 f_ultbf_inc_bsn(ms.ul_tbf);
1584 f_ms_tx_ul_block(ms, ul_data);
1585
1586 /* UL block dataB and dataD should be received in SGSN */
1587 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id, dataD));
1588
1589 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1590 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1591 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1592
1593 f_shutdown(__BFILE__, __LINE__, final := true);
1594}
1595
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02001596/* Test scenario where MS wants to request a new TBF once the current one is
1597 * ending, by means of sending a Packet Resource Request on ul slot provided by
1598 * last Pkt Ul ACK's RRBP.
1599 * See 3GPP TS 44.060 sec 9.3.2.4.2 "Non-extended uplink TBF mode" */
1600testcase TC_ul_tbf_reestablish_with_pkt_resource_req() runs on RAW_PCU_Test_CT {
1601 var CodingScheme exp_cs_mcs := CS_1;
1602 var RlcmacDlBlock dl_block;
1603 var octetstring data := f_rnd_octstring(10);
1604 var uint32_t sched_fn;
1605 var uint32_t dl_fn;
1606 var template RlcmacDlBlock acknack_tmpl;
1607 var GprsMS ms;
1608
1609 /* Initialize NS/BSSGP side */
1610 f_init_bssgp();
1611 /* Initialize GPRS MS side */
1612 f_init_gprs_ms();
1613 ms := g_ms[0]; /* We only use first MS in this test */
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, ms.tlli);
1621
1622 /* Establish an Uplink TBF */
1623 f_ms_establish_ul_tbf(ms);
1624
1625 /* Send one UL block (with TLLI since we are in One-Phase Access
1626 contention resoultion) and make sure it is ACKED fine */
1627 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
1628
1629 /* UL block should be received in SGSN */
1630 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
1631
1632 acknack_tmpl := tr_RLCMAC_UL_ACK_NACK_GPRS(ms.ul_tbf.tfi,
1633 tr_UlAckNackGprs(ms.tlli,
1634 tr_AckNackDescription(final_ack := '1'B),
1635 tr_UlAckNackGprsAdditionsRel99(tbf_est := true)))
1636 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
1637
1638 /* TODO: verify TBF_EST and FinalACK are both '1' above */
1639
1640 /* Send PACKET RESOURCE REQUEST to request a new UL TBF */
Vadim Yanitskiyf3cb4dd2020-07-21 01:52:33 +07001641 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)), sched_fn);
Vadim Yanitskiy7431e9e2020-07-21 01:59:17 +07001642 f_ms_rx_pkt_ass_pacch(ms, sched_fn, tr_RLCMAC_UL_PACKET_ASS);
Pau Espin Pedrolcdbe9032020-07-07 20:20:42 +02001643 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1644 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1645
1646 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1647 and make sure it is ACKED fine */
1648 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := false); /* TODO: send using cs_mcs */
1649
1650 /* UL block should be received in SGSN */
1651 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
1652
1653 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn, acknack_tmpl);
1654 /* ACK the ACK */
1655 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1656
1657 f_shutdown(__BFILE__, __LINE__, final := true);
1658}
1659
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001660private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
1661runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001662 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
1663 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
1664
1665 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
1666 setverdict(fail, "Mobile Identity length mismatch: ",
1667 "expected: 8, got: ", mi_lv.len);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001668 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001669 }
1670
1671 /* Make sure MI contains IMSI before referencing it */
1672 if (mi.typeOfIdentity != '001'B) {
1673 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
1674 "got: ", mi.typeOfIdentity);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001675 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001676 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
1677 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
1678 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001679 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001680 }
1681}
1682
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001683/* Test CS paging over the BTS<->PCU socket.
1684 * 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.
1685 * Paging should be send on the PACCH.
1686 *
1687 * 1. Send a Paging Request over PCU socket.
1688 * 2. Send a Ready-To-Send message over PCU socket
1689 * 3. Expect a Paging Frame
1690 */
1691testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001692 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001693 var MobileIdentityLV mi;
1694 var octetstring mi_enc_lv;
1695 var hexstring imsi := f_gen_imsi(42);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001696 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001697
1698 /* Initialize NS/BSSGP side */
1699 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001700 /* Initialize GPRS MS side */
1701 f_init_gprs_ms();
1702 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001703
1704 /* Initialize the PCU interface abstraction */
1705 f_init_raw(testcasename());
1706
1707 /* Establish BSSGP connection to the PCU */
1708 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001709 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001710
1711 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001712 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001713
1714 /* build mobile Identity */
1715 mi := valueof(ts_MI_IMSI_LV(imsi));
1716 mi_enc_lv := enc_MobileIdentityLV(mi);
1717 /* Send paging request */
1718 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
1719 sapi :=PCU_IF_SAPI_PDTCH));
1720
1721 /* Receive it on BTS side towards MS */
1722 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1723
1724 /* Make sure that Packet Paging Request contains the same IMSI */
1725 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1726
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001727 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001728}
1729
1730/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
1731 */
1732private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1733runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001734 var RlcmacDlBlock dl_block;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001735 var hexstring imsi := f_gen_imsi(42);
1736 var GsmTmsi tmsi;
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001737 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001738
1739 /* Initialize NS/BSSGP side */
1740 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001741 /* Initialize GPRS MS side */
1742 f_init_gprs_ms();
1743 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001744
1745 /* Initialize the PCU interface abstraction */
1746 f_init_raw(testcasename());
1747
1748 /* Establish BSSGP connection to the PCU */
1749 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001750 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001751
1752 /* Establish an Uplink TBF */
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001753 f_ms_establish_ul_tbf(ms);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001754
1755 /* Send paging request with or without TMSI */
1756 if (use_ptmsi) {
1757 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
1758 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
1759 } else {
1760 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
1761 }
1762
1763 /* Receive it on BTS side towards MS */
1764 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1765
1766 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
1767 if (use_ptmsi) {
1768 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
1769 } else {
1770 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1771 }
1772
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001773 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001774}
1775
1776testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1777 f_tc_paging_cs_from_sgsn(0, true);
1778}
1779
1780testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1781 f_tc_paging_cs_from_sgsn(0);
1782}
1783
1784testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1785 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
1786}
1787
1788/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
1789 */
1790private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1791runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001792 var integer imsi_suff_tx := 423;
1793 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001794 var GprsMS ms;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001795
1796 /* Initialize NS/BSSGP side */
1797 f_init_bssgp();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001798 /* Initialize GPRS MS side */
1799 f_init_gprs_ms();
1800 ms := g_ms[0]; /* We only use first MS in this test */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001801
1802 /* Initialize the PCU interface abstraction */
1803 f_init_raw(testcasename());
1804
1805 /* Establish BSSGP connection to the PCU */
1806 f_bssgp_establish();
Pau Espin Pedrol4f7b8fd2020-05-18 18:28:17 +02001807 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001808
1809 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
1810 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
1811 if (use_ptmsi) {
1812 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
1813 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
1814 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
1815 } else {
1816 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
1817 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
1818 }
1819
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001820 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001821}
1822
1823testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1824 f_tc_paging_ps_from_sgsn(0, true);
1825}
1826
1827testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1828 f_tc_paging_ps_from_sgsn(0);
1829}
1830
1831testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1832 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
1833}
1834
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02001835/* Verify osmo-pcu handles DL UNIT_DATA from SGSN with IMSI IE correctly. See OS#4729 */
1836testcase TC_bssgp_dl_unitdata_with_valid_imsi() runs on RAW_PCU_Test_CT {
1837 var RlcmacDlBlock dl_block;
1838 var octetstring data := f_rnd_octstring(10);
1839 var uint32_t sched_fn;
1840 var uint32_t dl_fn;
1841 var GprsMS ms;
1842
1843 /* Initialize NS/BSSGP side */
1844 f_init_bssgp();
1845 /* Initialize GPRS MS side */
1846 f_init_gprs_ms();
1847 ms := g_ms[0]; /* We only use first MS in this test */
1848
1849 /* Initialize the PCU interface abstraction */
1850 f_init_raw(testcasename());
1851
1852 /* Establish BSSGP connection to the PCU */
1853 f_bssgp_establish();
1854 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
1855
1856 /* Establish an Uplink TBF */
1857 f_ms_establish_ul_tbf(ms);
1858
1859 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
1860 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
1861 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1862 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1863 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1864
1865 /* UL block should be received in SGSN */
1866 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
1867
1868 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
1869 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI(ms.imsi)));
1870 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
1871
1872 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1873 f_sleep(X2002);
1874 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
1875
1876 /* ACK the DL block */
1877 f_acknackdesc_ack_block(ms.dl_tbf.acknack_desc, dl_block, '1'B);
1878 f_ms_tx_ul_block(ms, ts_RLCMAC_DL_ACK_NACK(ms.dl_tbf.tfi, ms.dl_tbf.acknack_desc),
1879 f_dl_block_ack_fn(dl_block, dl_fn));
1880
1881 f_shutdown(__BFILE__, __LINE__, final := true);
1882}
1883
1884/* Verify osmo-pcu acts on incorrect IMSI IE content in DL UNIT_DATA from SGSN. See OS#4729 */
1885testcase TC_bssgp_dl_unitdata_with_invalid_imsi() runs on RAW_PCU_Test_CT {
1886 var RlcmacDlBlock dl_block;
1887 var octetstring data := f_rnd_octstring(10);
1888 var uint32_t sched_fn;
1889 var uint32_t dl_fn;
1890 var GprsMS ms;
1891
1892 /* Initialize NS/BSSGP side */
1893 f_init_bssgp();
1894 /* Initialize GPRS MS side */
1895 f_init_gprs_ms();
1896 ms := g_ms[0]; /* We only use first MS in this test */
1897
1898 /* Initialize the PCU interface abstraction */
1899 f_init_raw(testcasename());
1900
1901 /* Establish BSSGP connection to the PCU */
1902 f_bssgp_establish();
1903 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
1904
1905 /* Establish an Uplink TBF */
1906 f_ms_establish_ul_tbf(ms);
1907
1908 /* Fake GMM GPRS Attach or similar, PCU doesn't care about upper layers here */
1909 f_ms_tx_ul_data_block_multi(ms, 1, with_tlli := true);
1910 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1911 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1912 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), sched_fn);
1913
1914 /* UL block should be received in SGSN */
1915 BSSGP[0].receive(tr_BSSGP_UL_UD(ms.tlli, mp_gb_cfg.cell_id));
1916
1917 /* Now SGSN sends some DL data with an invalid IMSI */
1918 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data, imsi := ts_BSSGP_IMSI('1122'H)));
1919
1920 BSSGP_SIG[0].receive(tr_BSSGP_STATUS(omit, BSSGP_CAUSE_CONDITIONAL_IE_ERROR, ?));
1921
1922 /* TODO: make sure no data is sent over PCU -> MS */
1923
1924 f_shutdown(__BFILE__, __LINE__, final := true);
1925}
1926
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001927private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
Vadim Yanitskiy43893902020-05-29 15:21:50 +07001928 template GsmRrMessage t_imm_ass := ?,
1929 PCUIF_BurstType bt := BURST_TYPE_1)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001930runs on RAW_PCU_Test_CT {
Vadim Yanitskiy43893902020-05-29 15:21:50 +07001931 var GsmRrMessage rr_msg;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001932 var uint16_t ra11;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001933
1934 ra11 := enc_EGPRSPktChRequest2uint(req);
1935 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
1936
Vadim Yanitskiy28d18e12020-05-29 15:25:59 +07001937 rr_msg := f_pcuif_tx_rach_rx_imm_ass(ra := ra11, is_11bit := 1, burst_type := bt);
Vadim Yanitskiy43893902020-05-29 15:21:50 +07001938 if (not match(rr_msg, t_imm_ass)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001939 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001940 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001941 }
1942
1943 setverdict(pass);
1944}
1945
1946testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
1947 var template GsmRrMessage imm_ass;
1948 var template IaRestOctets rest;
1949 var template EgprsUlAss ul_ass;
1950
1951 /* Initialize the PCU interface abstraction */
1952 f_init_raw(testcasename());
1953
1954 var EGPRSPktChRequest req := {
1955 /* NOTE: other fields are set in the loop */
1956 signalling := { tag := '110011'B }
1957 };
1958
1959 for (var integer i := 0; i < 6; i := i + 1) {
1960 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1961 req.signalling.random_bits := ext_ra;
1962
1963 /* For signalling, do we expect Multiblock UL TBF Assignment? */
1964 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
1965 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
1966 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
1967
1968 f_TC_egprs_pkt_chan_req(req, imm_ass);
1969 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001970
1971 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001972}
1973
1974testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
1975 var template GsmRrMessage imm_ass;
1976 var template IaRestOctets rest;
1977 var template EgprsUlAss ul_ass;
1978
1979 /* Initialize the PCU interface abstraction */
1980 f_init_raw(testcasename());
1981
1982 var EGPRSPktChRequest req := {
1983 /* NOTE: other fields are set in the loop */
1984 one_phase := { tag := '0'B }
1985 };
1986
1987 for (var integer i := 0; i < 6; i := i + 1) {
1988 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
1989 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
1990 var BIT2 priority := substr(ext_ra, 0, 2);
1991 var BIT3 rand := substr(ext_ra, 2, 3);
1992
1993 req.one_phase.multislot_class := mslot_class;
1994 req.one_phase.priority := priority;
1995 req.one_phase.random_bits := rand;
1996
1997 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
1998 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
1999 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2000 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2001
2002 f_TC_egprs_pkt_chan_req(req, imm_ass);
2003 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002004
2005 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002006}
2007
2008testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
2009 var template GsmRrMessage imm_ass;
2010 var template IaRestOctets rest;
2011 var template EgprsUlAss ul_ass;
2012
2013 /* Initialize the PCU interface abstraction */
2014 f_init_raw(testcasename());
2015
2016 var EGPRSPktChRequest req := {
2017 /* NOTE: other fields are set in the loop */
2018 two_phase := { tag := '110000'B }
2019 };
2020
2021 for (var integer i := 0; i < 6; i := i + 1) {
2022 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2023 var BIT2 priority := substr(ext_ra, 0, 2);
2024 var BIT3 rand := substr(ext_ra, 2, 3);
2025
2026 req.two_phase.priority := priority;
2027 req.two_phase.random_bits := rand;
2028
2029 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
2030 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2031 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2032 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2033
2034 f_TC_egprs_pkt_chan_req(req, imm_ass);
2035 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002036
2037 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002038}
2039
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002040private function f_TC_egprs_pkt_chan_req_reject(bitstring ra11, uint32_t fn,
2041 template IARRestOctets rest := ?,
2042 PCUIF_BurstType bt := BURST_TYPE_1)
2043runs on RAW_PCU_Test_CT {
2044 var template ReqRefWaitInd tr_ref;
2045 var GsmRrMessage rr_msg;
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002046
2047 /* Send RACH.ind with malformed EGPRS Packet Channel Request */
2048 BTS.send(ts_PCUIF_RACH_IND(bts_nr := 0, trx_nr := 0, ts_nr := 0,
2049 ra := bit2int(ra11), is_11bit := 1,
2050 burst_type := bt, fn := fn,
2051 arfcn := 871));
2052
2053 /* Abuse f_pcuif_rx_imm_ass(): wait for Immediate Assignment Reject */
Vadim Yanitskiy7466c332020-05-28 20:41:19 +07002054 rr_msg := f_pcuif_rx_imm_ass(t_imm_ass := tr_IMM_ASS_REJ);
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002055
2056 /* Just to have a short-name reference to the actual message */
2057 var ImmediateAssignmentReject iar := rr_msg.payload.imm_ass_rej;
2058
2059 /* Make sure that Request Reference list contains at least one entry
2060 * with our TDMA frame number, and RA is set to 'reserved' value 127. */
2061 tr_ref := tr_ReqRefWaitInd(f_compute_ReqRef(127, fn));
2062 if (not match(iar.payload, { *, tr_ref, * })) {
2063 setverdict(fail, "Request Reference list does not match");
2064 f_shutdown(__BFILE__, __LINE__);
2065 }
2066
2067 /* Match Feature Indicator (must indicate PS domain) */
2068 if (not match(iar.feature_ind, FeatureIndicator:{?, false, true})) {
2069 setverdict(fail, "Feature Indicator does not match");
2070 f_shutdown(__BFILE__, __LINE__);
2071 }
2072
2073 /* Match IAR Rest Octets */
2074 if (not match(iar.rest_octets, rest)) {
2075 setverdict(fail, "IAR Rest Octets does not match: ",
2076 iar.rest_octets, " vs expected ", rest);
2077 f_shutdown(__BFILE__, __LINE__);
2078 }
2079
2080 setverdict(pass);
2081}
2082
2083/* Verify the contents of RR Immediate Assignment Reject message and its
2084 * Rest Octets sent in response to EGPRS Packet Channel Request (11 bit). */
2085testcase TC_egprs_pkt_chan_req_reject_content() runs on RAW_PCU_Test_CT {
2086 var template IARRestOctets rest;
2087 var BIT5 ext_ra;
2088
2089 /* Initialize the PCU interface abstraction */
2090 f_init_raw(testcasename());
2091
2092 for (var integer i := 0; i < 6; i := i + 1) {
2093 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
2094 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
2095
2096 /* Intentionally incorrect message (see table 11.2.5a.2) */
2097 f_TC_egprs_pkt_chan_req_reject('111111'B & ext_ra, 1337 + i, rest);
2098 }
2099
2100 f_shutdown(__BFILE__, __LINE__, final := true);
2101}
2102
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07002103/* At the moment, the IUT does not support any emergency services. Make sure
2104 * that EGPRS Packet Channel Request for an emergency call is properly rejected. */
2105testcase TC_egprs_pkt_chan_req_reject_emergency() runs on RAW_PCU_Test_CT {
2106 var template IARRestOctets rest;
2107 var BIT5 ext_ra;
2108 var BIT11 ra11;
2109
2110 /* Initialize the PCU interface abstraction */
2111 f_init_raw(testcasename());
2112
2113 var EGPRSPktChRequest req := {
2114 /* NOTE: other fields are set in the loop */
2115 emergency := { tag := '110111'B }
2116 };
2117
2118 for (var integer i := 0; i < 6; i := i + 1) {
2119 ext_ra := int2bit(f_rnd_int(32), 5); /* 5 LSB's of RA11 */
2120 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(ext_ra), * });
2121
2122 req.emergency.random_bits := ext_ra;
2123 ra11 := enc_EGPRSPktChRequest2bits(req);
2124
2125 /* Intentionally incorrect message (see table 11.2.5a.2) */
2126 f_TC_egprs_pkt_chan_req_reject(ra11, 1337 + i, rest);
2127 }
2128
2129 f_shutdown(__BFILE__, __LINE__, final := true);
2130}
2131
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002132/* Make sure that IUT responds with RR Immediate Assignment Reject due to exhaustion. */
2133testcase TC_egprs_pkt_chan_req_reject_exhaustion() runs on RAW_PCU_Test_CT {
2134 var template IARRestOctets rest;
2135 var BIT11 ra11;
2136
2137 /* Initialize the PCU interface abstraction */
2138 f_init_raw(testcasename());
2139
2140 var EGPRSPktChRequest req := {
2141 one_phase := {
2142 tag := '0'B,
2143 multislot_class := '10101'B,
2144 priority := '01'B,
2145 random_bits := '101'B
2146 }
2147 };
2148
2149 /* We send 7 requests, the IUT gives us all available USFs (0..6).
2150 * TODO: make it configurable: usf_max := mp_pdch_ts_num * 7. */
2151 for (var integer i := 0; i < 7; i := i + 1) {
2152 req.one_phase.random_bits := int2bit(f_rnd_int(8), 3);
2153 f_TC_egprs_pkt_chan_req(req, tr_IMM_TBF_ASS);
2154 }
2155
2156 ra11 := enc_EGPRSPktChRequest2bits(req);
2157 rest := tr_IARRestOctets({ *, tr_ExtRAOpt(substr(ra11, 6, 5)), * });
2158
2159 /* At this point, the IUT should run out of free USFs */
2160 f_TC_egprs_pkt_chan_req_reject(ra11, 1870, rest);
2161
2162 f_shutdown(__BFILE__, __LINE__, final := true);
2163}
2164
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002165/* Randomly generate a set of hopping parameters for one timeslot */
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07002166private function f_TC_pcuif_fh_params_gen(integer max_ma_len)
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002167return template (value) PCUIF_InfoTrxTs {
Vadim Yanitskiy7a04cdd2020-09-07 11:43:32 +07002168 /* Pick a random MA length in range 2 .. max_ma_len */
2169 var integer ma_len := 2 + f_rnd_int(max_ma_len - 2);
2170
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002171 return ts_PCUIF_InfoTrxTsH1(tsc := f_rnd_int(7),
2172 hsn := f_rnd_int(63),
2173 maio := f_rnd_int(63),
2174 ma := f_rnd_bitstring(ma_len));
2175}
2176
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002177private function f_TC_pcuif_fh_check_imm_ass(in PCUIF_info_ind info_ind,
2178 in GsmRrMessage rr_msg)
2179{
2180 var ImmediateAssignment ia := rr_msg.payload.imm_ass;
2181 var PCUIF_InfoTrxTs ts := info_ind.trx.v10[0].ts[ia.pkt_chan_desc.tn];
2182
2183 var template PacketChannelDescription tr_pkt_chan_desc := {
2184 channel_Type_spare := ?,
2185 tn := ?,
2186 tsc := ts.tsc,
2187 presence := '1'B,
2188 zero := omit,
2189 one := {
2190 maio := ts.maio,
2191 hsn := ts.hsn
2192 }
2193 };
2194
2195 if (not match(ia.pkt_chan_desc, tr_pkt_chan_desc)) {
2196 setverdict(fail, "Packet Channel Description does not match: ",
2197 ia.pkt_chan_desc, " vs ", tr_pkt_chan_desc);
2198 }
2199
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07002200 /* Mobile Allocation is expected to be octet-aligned */
2201 var uint8_t ma_oct_len := (ts.ma_bit_len + 8 - 1) / 8;
2202 var template MobileAllocationLV tr_ma := {
2203 len := ma_oct_len, /* in bytes */
2204 ma := substr(ts.ma, 0, ma_oct_len * 8)
2205 };
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002206
2207 if (not match(ia.mobile_allocation, tr_ma)) {
2208 setverdict(fail, "Mobile Allocation does not match: ",
2209 ia.mobile_allocation, " vs ", tr_ma);
2210 }
2211
2212 setverdict(pass);
2213}
2214
2215/* Make sure that Immediate (UL EGPRS TBF) Assignment contains hopping parameters */
2216testcase TC_pcuif_fh_imm_ass_ul_egprs() runs on RAW_PCU_Test_CT {
2217 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
2218 var GprsMS ms := valueof(t_GprsMS_def);
2219
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002220 /* Enable frequency hopping on TRX0/TS7 */
2221 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002222
2223 /* Initialize the PCU interface abstraction */
2224 f_init_raw(testcasename(), info_ind);
2225
2226 /* EGPRS Packet Channel Request (cause=Signalling) */
2227 f_ms_use_ra(ms, bit2int('11001101010'B), ra_is_11bit := 1);
2228
2229 /* Establish an Uplink EGPRS TBF */
2230 f_ms_establish_ul_tbf(ms);
2231
2232 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
2233 f_shutdown(__BFILE__, __LINE__, final := true);
2234}
2235
2236/* Make sure that Immediate (UL TBF) Assignment contains hopping parameters */
2237testcase TC_pcuif_fh_imm_ass_ul() runs on RAW_PCU_Test_CT {
2238 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
2239 var GprsMS ms := valueof(t_GprsMS_def);
2240
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002241 /* Enable frequency hopping on TRX0/TS7 */
2242 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(32);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002243
2244 /* Initialize the PCU interface abstraction */
2245 f_init_raw(testcasename(), info_ind);
2246
2247 /* Establish an Uplink TBF */
2248 f_ms_establish_ul_tbf(ms);
2249
2250 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.ul_tbf.rr_imm_ass);
2251 f_shutdown(__BFILE__, __LINE__, final := true);
2252}
2253
2254/* Make sure that Immediate (DL TBF) Assignment contains hopping parameters */
2255testcase TC_pcuif_fh_imm_ass_dl() runs on RAW_PCU_Test_CT {
2256 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
2257 var GprsMS ms := valueof(t_GprsMS_def);
2258
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002259 /* Enable frequency hopping on TRX0/TS7 */
2260 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(16);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002261
2262 /* Initialize NS/BSSGP side */
2263 f_init_bssgp();
2264
2265 /* Initialize the PCU interface abstraction */
2266 f_init_raw(testcasename(), info_ind);
2267
2268 /* Establish BSSGP connection to the PCU */
2269 f_bssgp_establish();
2270 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
2271
2272 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
2273 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, f_rnd_octstring(12)));
2274 f_ms_exp_dl_tbf_ass_ccch(ms, PCU_IF_SAPI_PCH);
2275
2276 f_TC_pcuif_fh_check_imm_ass(valueof(info_ind), ms.dl_tbf.rr_imm_ass);
2277 f_shutdown(__BFILE__, __LINE__, final := true);
2278}
2279
2280private function f_TC_pcuif_fh_check_pkt_ass(in PCUIF_info_ind info_ind,
2281 in FrequencyParameters fp)
2282{
2283 /* FIXME: TRX0/TS7 is a hard-coded expectation, make it configurable */
2284 var PCUIF_InfoTrxTs ts := info_ind.trx.v10[0].ts[7];
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002285
2286 /* Table 12.8.1: Frequency Parameters information elements */
2287 var template FrequencyParameters tr_fp := {
2288 tsc := ts.tsc,
2289 presence := '10'B, /* Direct encoding 1 */
2290 arfcn := omit,
2291 indirect := omit,
2292 direct1 := {
2293 maio := ts.maio,
2294 /* Table 12.10a.1: GPRS Mobile Allocation information elements */
2295 mobile_allocation := {
2296 hsn := ts.hsn,
2297 rfl_number_list_present := '0'B,
2298 rfl_number_list := omit,
2299 ma_present := '0'B, /* inverted logic */
Vadim Yanitskiy43ccaf52020-09-05 21:35:13 +07002300 ma_length := ts.ma_bit_len,
2301 ma_bitmap := substr(ts.ma, 0, ts.ma_bit_len)
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002302 }
2303 },
2304 direct2 := omit
2305 };
2306
2307 if (not match(fp, tr_fp)) {
2308 setverdict(fail, "Frequency Parameters IE does not match: ",
2309 fp, " vs ", tr_fp);
2310 }
2311
2312 setverdict(pass);
2313}
2314
2315/* Make sure that Packet Uplink Assignment contains hopping parameters */
2316testcase TC_pcuif_fh_pkt_ass_ul() runs on RAW_PCU_Test_CT {
2317 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
2318 var GprsMS ms := valueof(t_GprsMS_def);
2319 var uint32_t poll_fn;
2320
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002321 /* Enable frequency hopping on TRX0/TS7 */
2322 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002323
2324 /* Initialize the PCU interface abstraction */
2325 f_init_raw(testcasename(), info_ind);
2326
2327 /* Establish an Uplink TBF */
2328 f_ms_establish_ul_tbf(ms);
2329
2330 /* Send Packet Resource Request, so the network will allocate an Uplink resource */
2331 f_ms_tx_ul_block(ms, ts_RLC_UL_CTRL_ACK(ts_RlcMacUlCtrl_PKT_RES_REQ(ms.tlli, omit)));
2332
2333 /* Expect an RLC/MAC block with Packet Uplink Assignment on PACCH (see 11.2.29) */
2334 var RlcmacDlBlock blk := f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_UL_PACKET_ASS);
2335 var PacketUlAssignment ua := blk.ctrl.payload.u.ul_assignment;
2336
2337 /* 3GPP TS 44.060, section 12.8 "Frequency Parameters" */
2338 var template (omit) FrequencyParameters fp;
2339 if (ua.is_egprs == '1'B) {
2340 fp := ua.egprs.freq_par;
2341 } else {
2342 fp := ua.gprs.freq_par;
2343 }
2344
2345 /* This is an optional IE, so it's worth to check its presence */
2346 if (istemplatekind(fp, "omit")) {
2347 setverdict(fail, "Frequency Parameters IE is not present");
2348 f_shutdown(__BFILE__, __LINE__);
2349 }
2350
2351 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), valueof(fp));
2352 f_shutdown(__BFILE__, __LINE__, final := true);
2353}
2354
2355/* Make sure that Packet Downlink Assignment contains hopping parameters */
2356testcase TC_pcuif_fh_pkt_ass_dl() runs on RAW_PCU_Test_CT {
2357 var template PCUIF_info_ind info_ind := ts_PCUIF_INFO_default;
2358 var octetstring data := f_rnd_octstring(10);
2359 var GprsMS ms := valueof(t_GprsMS_def);
2360 var RlcmacDlBlock dl_block;
2361 var uint32_t poll_fn;
2362
Vadim Yanitskiyef0c1b52020-09-05 21:32:18 +07002363 /* Enable frequency hopping on TRX0/TS7 */
2364 info_ind.trx.v10[0].ts[7] := f_TC_pcuif_fh_params_gen(33);
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002365
2366 /* Initialize NS/BSSGP side */
2367 f_init_bssgp();
2368
2369 /* Initialize the PCU interface abstraction */
2370 f_init_raw(testcasename(), info_ind);
2371
2372 /* Establish BSSGP connection to the PCU */
2373 f_bssgp_establish();
2374 f_bssgp_client_llgmm_assign('FFFFFFFF'O, ms.tlli);
2375
2376 /* Establish an Uplink TBF */
2377 f_ms_establish_ul_tbf(ms);
2378
2379 /* Send an Uplink block, so this TBF becomes "active" */
2380 f_ms_tx_ul_data_block(ms, data, with_tlli := true);
2381
2382 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
2383 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, poll_fn);
2384 f_ms_tx_ul_block(ms, ts_RLCMAC_CTRL_ACK(ms.tlli), poll_fn);
2385
2386 /* SGSN sends some DL data, PCU will assign Downlink resource on PACCH */
2387 BSSGP[0].send(ts_BSSGP_DL_UD(ms.tlli, data));
2388
2389 /* Expect an RLC/MAC block with Packet Downlink Assignment on PACCH (see 11.2.29) */
2390 dl_block := f_ms_rx_pkt_ass_pacch(ms, poll_fn, tr_RLCMAC_DL_PACKET_ASS);
2391 var PacketDlAssignment da := dl_block.ctrl.payload.u.dl_assignment;
2392
2393 /* This is an optional IE, so it's worth to check its presence */
2394 if (not ispresent(da.freq_par)) {
2395 setverdict(fail, "Frequency Parameters IE is not present");
2396 f_shutdown(__BFILE__, __LINE__);
2397 }
2398
2399 f_TC_pcuif_fh_check_pkt_ass(valueof(info_ind), da.freq_par);
2400 f_shutdown(__BFILE__, __LINE__, final := true);
2401}
2402
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002403control {
2404 execute( TC_pcuif_suspend() );
2405 execute( TC_ta_ptcch_idle() );
2406 execute( TC_ta_rach_imm_ass() );
2407 execute( TC_ta_idle_dl_tbf_ass() );
2408 execute( TC_ta_ptcch_ul_multi_tbf() );
2409 execute( TC_cs_lqual_ul_tbf() );
2410 execute( TC_cs_initial_ul() );
2411 execute( TC_cs_max_ul() );
2412 execute( TC_t3169() );
2413 execute( TC_t3193() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002414 execute( TC_countdown_procedure() );
Pau Espin Pedrolfb2301e2020-06-30 20:46:54 +02002415 execute( TC_ul_all_sizes() );
Pau Espin Pedrol5e6844d2020-07-01 17:24:02 +02002416 execute( TC_ul_data_toolong_fills_padding() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002417 execute( TC_mo_ping_pong() );
2418 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002419 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002420 execute( TC_mt_ping_pong() );
2421 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02002422 execute( TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002423 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002424 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrole1195bb2020-07-07 13:27:18 +02002425 execute( TC_ul_flow_multiple_llc_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002426 execute( TC_paging_cs_from_bts() );
2427 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
2428 execute( TC_paging_cs_from_sgsn_sign() );
2429 execute( TC_paging_cs_from_sgsn_ptp() );
2430 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
2431 execute( TC_paging_ps_from_sgsn_sign() );
2432 execute( TC_paging_ps_from_sgsn_ptp() );
Pau Espin Pedrolc03eb122020-08-27 18:54:24 +02002433 execute( TC_bssgp_dl_unitdata_with_valid_imsi() );
2434 execute( TC_bssgp_dl_unitdata_with_invalid_imsi() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002435
2436 /* EGPRS specific test cases */
2437 execute( TC_egprs_pkt_chan_req_signalling() );
2438 execute( TC_egprs_pkt_chan_req_one_phase() );
2439 execute( TC_egprs_pkt_chan_req_two_phase() );
Vadim Yanitskiy4f56d322020-05-22 20:15:48 +07002440 execute( TC_egprs_pkt_chan_req_reject_content() );
Vadim Yanitskiy7e06c252020-05-22 20:48:53 +07002441 execute( TC_egprs_pkt_chan_req_reject_emergency() );
Vadim Yanitskiyc4324ff2020-05-22 21:53:58 +07002442 execute( TC_egprs_pkt_chan_req_reject_exhaustion() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002443
2444 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Vadim Yanitskiy94fe83e2020-07-20 04:03:13 +07002445
2446 /* Frequency hopping specific test cases */
2447 if (PCUIF_Types.mp_pcuif_version >= 10) {
2448 /* Immediate Assignment on AGCH/PCH */
2449 execute( TC_pcuif_fh_imm_ass_ul_egprs() );
2450 execute( TC_pcuif_fh_imm_ass_ul() );
2451 execute( TC_pcuif_fh_imm_ass_dl() );
2452 /* Packet Uplink/Downlink Assignment on PACCH */
2453 execute( TC_pcuif_fh_pkt_ass_ul() );
2454 execute( TC_pcuif_fh_pkt_ass_dl() );
2455 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002456}
2457
2458
2459
2460
2461
2462
Harald Weltea419df22019-03-21 17:23:04 +01002463}