blob: 43ed7c5d2f0793936fea06a32bf4bad73d7fb3bd [file] [log] [blame]
Harald Weltea0895f92018-03-08 11:51:23 +01001module PCU_Tests {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002
3/* "RAW" PCU tests: Talk directly to the PCU socket of OsmoPCU on the one hand side (emulating
4 the BTS/BSC side PCU socket server) and the Gb interface on the other hand side. No NS/BSSGP
5 Emulation is used; rather, we simply use the NS_CodecPort to implement both standard and non-
6 standard procedures on the NS and BSSGP level. The goal of these tests is to test exactly
7 those NS and BSSGP implementations on the BSS (PCU) side. */
8
9/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
10 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
11 * All rights reserved.
12 *
13 * Released under the terms of GNU General Public License, Version 2 or
14 * (at your option) any later version.
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18
19friend module PCU_Tests_NS;
20
21import from General_Types all;
22import from Osmocom_Types all;
23import from GSM_Types all;
24import from GSM_RR_Types all;
25
26import from Osmocom_VTY_Functions all;
27import from TELNETasp_PortType all;
28
29import from MobileL3_GMM_SM_Types all;
30import from RLCMAC_CSN1_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020031import from RLCMAC_CSN1_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020032import from RLCMAC_Types all;
Pau Espin Pedrole8d7d162020-04-29 19:07:36 +020033import from RLCMAC_Templates all;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +020034
35import from MobileL3_CommonIE_Types all;
36import from L3_Templates all;
37
38import from NS_Types all;
39import from BSSGP_Types all;
40import from Osmocom_Gb_Types all;
41
42import from BSSGP_Emulation all; /* BssgpConfig */
43import from NS_Emulation all; /* NSConfiguration */
44
45import from UD_Types all;
46import from PCUIF_Types all;
47import from PCUIF_CodecPort all;
48import from PCUIF_Components all;
49import from IPL4asp_Types all;
50import from Native_Functions all;
51import from SGSN_Components all;
52
53modulepar {
54 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
55
56 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
57}
58
59
60/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
61private template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
62 version := PCU_IF_VERSION,
63 flags := c_PCUIF_Flags_default,
64 trx := valueof(ts_PCUIF_InfoTrxs_def),
65 bsic := 7,
66 mcc := 262,
67 mnc := 42,
68 mnc_3_digits := 0,
69 lac := 13135,
70 rac := 0,
71 nsei := mp_nsconfig.nsei,
72 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
73 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
74 cell_id := 20960,
75 repeat_time := 5 * 50,
76 repeat_count := 3,
77 bvci := mp_gb_cfg.bvci,
78 t3142 := 20,
79 t3169 := 5,
80 t3191 := 5,
81 t3193_10ms := 160,
82 t3195 := 5,
83 t3101 := 10,
84 t3103 := 4,
85 t3105 := 8,
86 cv_countdown := 15,
87 dl_tbf_ext := 250 * 10, /* ms */
88 ul_tbf_ext := 250 * 10, /* ms */
89 initial_cs := 2,
90 initial_mcs := 6,
91 nsvci := { mp_nsconfig.nsvci, 0 },
92 local_pprt := { mp_nsconfig.remote_udp_port, 0 },
93 remote_port := { mp_nsconfig.local_udp_port, 0 },
94 remote_ip := { f_inet_haddr(mp_nsconfig.local_ip) , '00000000'O }
95}
96
97type record lqual_range {
98 /* component reference to the IPA_Client component used for RSL */
99 uint8_t low,
100 uint8_t high
101}
102
103type component RAW_PCU_Test_CT extends bssgp_CT {
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700104 /* PCU interface abstraction component */
105 var RAW_PCUIF_CT vc_PCUIF;
106 /* Virtual BTS component */
107 var RAW_PCU_BTS_CT vc_BTS;
108
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200109 /* Connection to the BTS component (one for now) */
110 port RAW_PCU_MSG_PT BTS;
111 /* Connection to the PCUIF component */
112 port RAW_PCU_MSG_PT PCUIF;
113 /* VTY connection to the PCU */
114 port TELNETasp_PT PCUVTY;
115
116 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
117 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
118 {low := 5, high := 8},
119 {low := 7, high := 13},
120 {low := 12,high := 35}};
121 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
122 {low := 5, high := 8},
123 {low := 7, high := 13},
124 {low := 12,high := 15},
125 {low := 14, high := 17},
126 {low := 16, high := 18},
127 {low := 17,high := 20},
128 {low := 19, high := 24},
129 {low := 23,high := 35}};
130 var uint8_t g_cs_initial_dl := 1;
131 var uint8_t g_cs_initial_ul := 1;
132 var uint8_t g_mcs_initial_dl := 1;
133 var uint8_t g_mcs_initial_ul := 1;
134 var uint8_t g_cs_max_dl := 4;
135 var uint8_t g_cs_max_ul := 4;
136 var uint8_t g_mcs_max_dl := 9;
137 var uint8_t g_mcs_max_ul := 9;
138
Pau Espin Pedrol5feace62020-05-14 16:44:18 +0200139 /* Value at which Countdown Procedure starts. Announced by network (GPRS Cell Options as per TS 04.60 Chapter 12.24) */
140 var uint4_t g_bs_cv_max := 4;
141
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200142 var boolean g_egprs_only := false;
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200143 var boolean g_force_two_phase_access := false;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200144
145 /* Guard timeout */
146 timer g_T_guard := 60.0;
147};
148
149private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
150 [] g_T_guard.timeout {
151 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700152 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200153 }
154}
155
156private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
157 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
158 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
159
160 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
161 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
162}
163
164private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
165 var charstring cmd;
166
167 cmd := "cs link-quality-ranges" &
168 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
169 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
170 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
171 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
172 f_vty_config2(PCUVTY, {"pcu"}, cmd);
173
174 cmd := "mcs link-quality-ranges" &
175 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
176 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
177 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
178 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
179 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
180 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
181 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
182 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
183 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
184 f_vty_config2(PCUVTY, {"pcu"}, cmd);
185}
186
187private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
188 map(self:PCUVTY, system:PCUVTY);
189 f_vty_set_prompts(PCUVTY);
190 f_vty_transceive(PCUVTY, "enable");
191
192 if (g_egprs_only) {
193 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
194 } else {
195 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
196 }
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +0200197
198 if (g_force_two_phase_access) {
199 f_vty_config2(PCUVTY, {"pcu"}, "two-phase-access");
200 } else {
201 f_vty_config2(PCUVTY, {"pcu"}, "no two-phase-access");
202 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200203}
204
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200205function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200206runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200207 /* Start the guard timer */
208 g_T_guard.start;
209 activate(as_Tguard_RAW());
210
211 /* Init PCU interface component */
212 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
213 connect(vc_PCUIF:MTC, self:PCUIF);
214 map(vc_PCUIF:PCU, system:PCU);
215
216 /* Create one BTS component (we may want more some day) */
217 vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
218 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
219 connect(vc_BTS:TC, self:BTS);
220
221 f_init_vty(id);
222
223 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
224 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
225
226 /* Wait until the BTS is ready (SI13 negotiated) */
227 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
228}
229
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700230private function f_shutdown(charstring file, integer line,
231 boolean final := false)
232runs on RAW_PCU_Test_CT {
233 /* Determine if the test case was aborted in the middle */
234 if (not final) {
235 log("Test case ", testcasename(), " aborted at ", file, ":", line);
236 } else {
237 /* Guard verdict to avoid 'none' */
238 setverdict(pass);
239 }
240
241 /* Properly shutdown virtual BTS and its clock generator */
242 BTS.send(ts_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN));
243 vc_BTS.done; /* wait untill it's done */
244
245 /* Shutdown the others and MTC */
246 all component.stop;
247 mtc.stop;
248}
249
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200250template AckNackDescription t_AckNackDescription_init := {
251 final_ack := '0'B,
252 starting_seq_nr := 0,
253 receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'B
254}
255
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200256private function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block)
257runs on RAW_PCU_Test_CT return uint5_t {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200258 if (ischosen(dl_block.data)) {
259 return dl_block.data.mac_hdr.hdr_ext.tfi;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200260 } else if (ischosen(dl_block.data_egprs)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200261 return dl_block.data_egprs.mac_hdr.tfi;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200262 } else { /* Ctrl block */
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200263 if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(tr_DynamicAllocation(?))))) {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200264 return dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;
265 }
Pau Espin Pedrol45b664b2020-05-14 15:16:40 +0200266 if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(tr_DynamicAllocation(?))))) {
267 return dl_block.ctrl.payload.u.ul_assignment.egprs.dyn_block_alloc.ul_tfi_assignment;
268 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200269 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200270 setverdict(fail, "DlBlock doesn't contain a TFI:", dl_block);
271 f_shutdown(__BFILE__, __LINE__);
272 return 0; /* make compiler happy */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200273}
274
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +0200275/* Get the Chan coding command from a dl block containing PACCH UL Assignment */
276private function f_rlcmac_dl_block_get_assigned_ul_cs_mcs(RlcmacDlBlock dl_block)
277runs on RAW_PCU_Test_CT return CodingScheme {
278 if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(?)))) {
279 return f_rlcmac_block_ChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.gprs.ch_coding_cmd);
280 }
281 if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_EGPRS(?, tr_PktUlAssEgprsDynamic(?)))) {
282 return f_rlcmac_block_EgprsChCodingCommand2cs_mcs(dl_block.ctrl.payload.u.ul_assignment.egprs.chan_coding_cmd);
283 }
284 setverdict(fail, "DlBlock doesn't contain CS_MCS information:", dl_block);
285 f_shutdown(__BFILE__, __LINE__);
286 return CS_1; /* make compiler happy */
287}
288
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200289/* TS 44.060 sec 12.3 Ack/Nack Description */
290private function f_acknackdesc_ack_block(inout AckNackDescription desc, RlcmacDlBlock dl_block, BIT1 final_ack := '0'B)
291{
292 var uint7_t bsn;
293 var integer i;
294 var integer inc;
295
296 if (ischosen(dl_block.data)) {
297 bsn := dl_block.data.mac_hdr.hdr_ext.bsn;
298 } else {
299 bsn := dl_block.data_egprs.mac_hdr.bsn1;
300 }
301
302 inc := bsn - desc.starting_seq_nr + 1;
303 /* Filling hole? */
304 if (bsn < desc.starting_seq_nr) {
305 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);
306 return;
307 }
308
309 /* SSN is increased, and so RBB values need to be moved */
310 for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {
311 desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];
312 }
313 for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {
314 desc.receive_block_bitmap[i] := int2bit(0, 1);
315 }
316 /* Now we can set current bit and update SSN */
317 desc.starting_seq_nr := bsn + 1;
318 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);
319
320 /* Finally update the final_ack bit as requested: */
321 desc.final_ack := final_ack;
322}
323
324/* This function can be used to send DATA.cnf in response to the IUT originated DATA.req.
325 * NOTE: it's the responsibility of caller to make sure that pcu_msg contains u.data_req. */
326private function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)
327runs on RAW_PCU_Test_CT {
328 var PCUIF_Message pcu_msg_cnf := {
329 msg_type := PCU_IF_MSG_DATA_CNF,
330 bts_nr := pcu_msg.bts_nr,
331 spare := pcu_msg.spare,
332 u := { data_cnf := pcu_msg.u.data_req }
333 };
334
335 /* PCU wants DATA.cnf containing basically everything that was in DATA.req,
336 * but PCU_IF_SAPI_PCH is a special case - paging group shall be excluded. */
337 if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
338 pcu_msg_cnf.u.data_cnf.data := substr(pcu_msg.u.data_req.data, 3,
339 pcu_msg.u.data_req.len - 3);
340 }
341
342 BTS.send(pcu_msg_cnf);
343}
344
345private function f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,
346 template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
347 template GsmRrMessage t_imm_ass := ?,
348 uint8_t bts_nr := 0)
349runs on RAW_PCU_Test_CT return boolean {
350 var PCUIF_Message pcu_msg;
351 var octetstring data;
352 timer T;
353
354 T.start(2.0);
355 alt {
356 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
357 sapi := sapi, data := ?)) -> value pcu_msg {
358 /* On PCH the payload is prefixed with paging group (3 octets): skip it.
359 * TODO: add an additional template parameter, so we can match it. */
360 if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
361 data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
362 } else {
363 data := pcu_msg.u.data_req.data;
364 }
365
366 rr_imm_ass := dec_GsmRrMessage(data);
367 if (not match(rr_imm_ass, t_imm_ass)) {
368 /* Not for us? Wait for more. */
369 repeat;
370 }
371
372 log("Rx Immediate Assignment: ", rr_imm_ass);
373 setverdict(pass);
374 return true;
375 }
376 [] BTS.receive { repeat; }
377 [] T.timeout {
378 setverdict(fail, "Timeout waiting for Immediate Assignment");
379 }
380 }
381
382 return false;
383}
384
Vadim Yanitskiyf74ae992020-05-06 16:05:51 +0700385/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */
386private const BIT8 chan_req_def := '01111000'B;
387
Vadim Yanitskiy85cb9912020-05-06 16:29:43 +0700388/* Establish an Uplink TBF by sending RACH.ind towards the PCU */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200389private function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,
Vadim Yanitskiyf74ae992020-05-06 16:05:51 +0700390 uint16_t ra := bit2int(chan_req_def),
391 uint8_t is_11bit := 0,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200392 PCUIF_BurstType burst_type := BURST_TYPE_0,
393 TimingAdvance ta := 0)
394runs on RAW_PCU_Test_CT return boolean {
395 var uint32_t fn;
396
397 /* FIXME: ask the BTS component to give us the current TDMA fn */
398 fn := 1337 + ta;
399
400 /* Send RACH.ind */
401 log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);
402 BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
403 ra := ra, is_11bit := is_11bit,
404 burst_type := burst_type,
405 fn := fn, arfcn := 871,
406 qta := ta * 4));
407
408 /* 3GPP TS 44.018, table 9.1.8.1, note 2b: Request Reference shall be set to 127
409 * when Immediate Assignment is triggered by EGPRS Packet Channel Request. Here
410 * we assume that 11 bit RA always contains EGPRS Packet Channel Request. */
411 if (is_11bit != 0) { ra := 127; }
412
413 /* Expect Immediate (TBF) Assignment on TS0/AGCH */
414 return f_pcuif_rx_imm_ass(rr_imm_ass, PCU_IF_SAPI_AGCH,
Vadim Yanitskiy85cb9912020-05-06 16:29:43 +0700415 tr_IMM_TBF_ASS(false, ra, fn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200416 bts_nr := bts_nr);
417}
418
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200419private function f_imm_ass_verify_ul_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketUlAssign ul_tbf_ass, template PacketUlAssign ul_ass := tr_PacketUlDynAssign)
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700420runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200421
422 /* Make sure we received an UL TBF Assignment */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200423 if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(ul_ass)))) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200424 ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
425 log("Rx Uplink TBF assignment: ", ul_tbf_ass);
426 setverdict(pass);
427 } else {
428 setverdict(fail, "Failed to match UL TBF Assignment");
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700429 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200430 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200431}
432
Vadim Yanitskiy5b649cc2020-05-06 16:35:38 +0700433private function f_imm_ass_verify_dl_tbf_ass(in GsmRrMessage rr_imm_ass, out PacketDlAssign dl_tbf_ass)
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700434runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200435
436 /* Make sure we received a DL TBF Assignment */
437 if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {
438 dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;
439 log("Rx Downlink TBF assignment: ", dl_tbf_ass);
440 setverdict(pass);
441 } else {
442 setverdict(fail, "Failed to match DL TBF Assignment");
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700443 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200444 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200445}
446
447/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200448function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200449runs on RAW_PCU_Test_CT {
450 var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
451 BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
452 sapi := PCU_IF_SAPI_PDTCH, data := data,
453 fn := fn, arfcn := 871, lqual_cb := lqual_cb));
454 if (fn != 0) {
455 ev_param := {tdma_fn := fn };
456 }
457 BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));
458}
459
460/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
461private function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
462runs on RAW_PCU_Test_CT {
463 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
464 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
465 arfcn := 871, block_nr := 0));
466 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
467 sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
468}
469
470/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi. */
471private function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)
472runs on RAW_PCU_Test_CT {
473 var PCUIF_Message pcu_msg;
474 var octetstring macblock;
475 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
476 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
477 /* First 3 bytes contain paging group: */
478 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
479 rr_imm_ass := dec_GsmRrMessage(macblock);
480 if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {
481 setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700482 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200483 }
484 f_pcuif_tx_data_cnf(pcu_msg);
485}
486
487/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi. */
488private function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
489 template integer pag_group := ?)
490runs on RAW_PCU_Test_CT return GsmRrMessage {
491 var GsmRrMessage rr_pag_req1;
492 var PCUIF_Message pcu_msg;
493 var octetstring imsi_suff_octstr;
494 var integer pag_group_rx;
495 var octetstring macblock;
496
497 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
498 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
499
500 /* First 3 bytes contain IMSI suffix to calculate paging group: */
501 imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);
502 pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +
503 str2int(oct2char(imsi_suff_octstr[1])) * 10 +
504 str2int(oct2char(imsi_suff_octstr[2]));
505
506 /* Make sure we've got RR Paging Request Type 1 for a given MI */
507 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
508 rr_pag_req1 := dec_GsmRrMessage(macblock);
509 if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {
510 setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700511 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200512 }
513
514 /* Make sure that received paging froup matches the expected one */
515 if (not match(pag_group_rx, pag_group)) {
516 setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700517 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200518 }
519
520 f_pcuif_tx_data_cnf(pcu_msg);
521 return rr_pag_req1;
522}
523
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200524/* Send one rlcmac UL block adding necessary extra padding at the end.
525 * returns length of extra padding added at the end, in octets.
526 * FIXME: Only supports CS-1 so far.
527 */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200528private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200529runs on RAW_PCU_Test_CT return integer {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200530 var octetstring data;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200531 var integer padding_len;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200532 /* Encode the payload of DATA.ind */
533 data := enc_RlcmacUlBlock(valueof(ul_data));
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200534 padding_len := 23 - lengthof(data);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200535 data := f_pad_oct(data, 23, '00'O); /* CS-1 */
536
537 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
538 f_pcuif_tx_data_ind(data, lqual_cb, fn);
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200539 return padding_len;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200540}
541
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200542private function f_tx_rlcmac_ul_n_blocks(uint5_t tfi, inout uint14_t bsn, integer num_blocks := 1, template (omit) GprsTlli tlli := omit)
543runs on RAW_PCU_Test_CT return octetstring {
544 var octetstring total_payload := ''O;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200545 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200546 tfi := tfi,
Pau Espin Pedrol5feace62020-05-14 16:44:18 +0200547 cv := 15, /* num UL blocks to be sent (to be overridden in loop) */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200548 bsn := 0, /* To be generated in loop */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200549 blocks := { /* To be generated in loop */ });
550
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +0200551 if (not istemplatekind(tlli, "omit")) {
552 ul_data.data.mac_hdr.tlli_ind := true;
553 ul_data.data.tlli := tlli;
554 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200555
556 for (var integer i := 0; i < num_blocks; i := i + 1) {
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200557 var integer padding_len;
558 var octetstring payload := f_rnd_octstring(10);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200559 /* Prepare a new UL block (CV, random payload) */
Pau Espin Pedrol5feace62020-05-14 16:44:18 +0200560 var integer cv := num_blocks - i - 1;
561 if (cv > g_bs_cv_max) {
562 cv := 15;
563 }
564 ul_data.data.mac_hdr.countdown := cv;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200565 ul_data.data.mac_hdr.bsn := bsn + i;
566 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) };
567 padding_len := f_tx_rlcmac_ul_block(ul_data);
568 total_payload := total_payload & payload & f_pad_oct(''O, padding_len, '00'O);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200569 }
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +0200570 bsn := valueof(ul_data.data.mac_hdr.bsn) + 1; /* update bsn to point to next one */
571 return total_payload;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200572}
573
574private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
575runs on RAW_PCU_Test_CT {
576 var PCUIF_Message pcu_msg;
577 f_pcuif_rx_data_req(pcu_msg);
578 dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
579 dl_fn := pcu_msg.u.data_req.fn;
580
581 var integer len := lengthof(pcu_msg.u.data_req.data);
582 var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)
583 if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {
584 setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700585 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200586 }
587}
588
589private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
590runs on RAW_PCU_Test_CT {
591 var uint32_t dl_fn;
592
593 f_rx_rlcmac_dl_block(dl_block, dl_fn);
594 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
595 setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700596 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200597 }
598
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700599 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200600}
601
602private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
603runs on RAW_PCU_Test_CT {
604 var uint32_t dl_fn;
605
606 f_rx_rlcmac_dl_block(dl_block, dl_fn);
607 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
608 setverdict(fail, "Failed to match Packet DUMMY DL");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700609 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200610 }
611}
612
613private function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
614runs on RAW_PCU_Test_CT {
615 var uint32_t dl_fn;
616
617 f_rx_rlcmac_dl_block(dl_block, dl_fn);
618 if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
619 setverdict(fail, "Failed to match Packet Downlink Assignment");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700620 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200621 }
622
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700623 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200624}
625
626private function f_rx_rlcmac_dl_block_exp_pkt_ul_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
627runs on RAW_PCU_Test_CT {
628 var uint32_t dl_fn;
629
630 f_rx_rlcmac_dl_block(dl_block, dl_fn);
631 if (not match(dl_block, tr_RLCMAC_UL_PACKET_ASS())) {
632 setverdict(fail, "Failed to match Packet Uplink Assignment");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700633 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200634 }
635
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700636 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200637}
638
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200639private function f_rx_rlcmac_dl_block_exp_pkt_dl_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
640runs on RAW_PCU_Test_CT {
641 var uint32_t dl_fn;
642
643 f_rx_rlcmac_dl_block(dl_block, dl_fn);
644 if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
645 setverdict(fail, "Failed to match Packet Downlink Assignment");
646 f_shutdown(__BFILE__, __LINE__);
647 }
648
649 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
650}
651
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200652
653private function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
654runs on RAW_PCU_Test_CT {
655 var uint32_t dl_fn;
656
657 f_rx_rlcmac_dl_block(dl_block, dl_fn);
658 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
659 setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700660 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200661 }
662}
663
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700664/* This function does what could probably be done with templates */
665private function f_rlcmac_dl_block_verify_data_gprs(in RlcmacDlDataBlock data_block,
666 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700667 template (present) uint7_t exp_bsn := ?,
668 template (present) CodingScheme exp_cs := ?)
669runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700670 if (not match(data_block.mac_hdr.hdr_ext.bsn, exp_bsn)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200671 setverdict(fail, "DL block BSN doesn't match: ",
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700672 data_block.mac_hdr.hdr_ext.bsn, " vs exp ", exp_bsn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200673 }
674
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700675 if (lengthof(data_block.blocks) < 1) {
676 setverdict(fail, "DL block has no LLC payload: ", data_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700677 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200678 }
679
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700680 if (not match(data_block.blocks[0].payload, data)) {
681 setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
682 data_block.blocks[0].payload, " vs ", data);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700683 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200684 }
685
686 /* Check next data blocks contain dummy frames */
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700687 if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
688 setverdict(fail, "Second data payload is not a dummy frame: ",
689 data_block.blocks[1].payload);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700690 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200691 }
692
693 /* TODO: check exp_cs */
694}
695
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700696/* This function does what could probably be done with templates */
697private function f_rlcmac_dl_block_verify_data_egprs(in RlcmacDlEgprsDataBlock data_block,
698 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700699 template (present) uint14_t exp_bsn := ?,
700 template (present) CodingScheme exp_cs := ?)
701runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700702 if (not match(data_block.mac_hdr.bsn1, exp_bsn)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200703 setverdict(fail, "DL block BSN doesn't match: ",
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700704 data_block.mac_hdr.bsn1, " vs exp ", exp_bsn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200705 }
706
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700707 if (lengthof(data_block.blocks) < 1) {
708 setverdict(fail, "DL block has no LLC payload: ", data_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700709 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200710 }
711
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700712 if (not match(data_block.blocks[0].payload, data)) {
713 setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
714 data_block.blocks[0].payload, " vs ", data);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700715 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200716 }
717
718 /* Check next data blocks contain dummy frames */
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700719 if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
720 setverdict(fail, "Second data payload is not a dummy frame: ",
721 data_block.blocks[1].payload);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700722 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200723 }
724
725 /* TODO: Check exp_cs. In the case of EGPRS, first check mac_hdr.header_type and then decode CPS = exp_cs based on mac_hdr.header_type.
726 See wireshark's egprs_Header_type1_coding_puncturing_scheme_to_mcs. */
727}
728
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700729/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */
730private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
731 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700732 template (present) uint7_t exp_bsn := ?,
733 template (present) CodingScheme exp_cs := ?)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200734runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700735 /* FIXME: ideally we should use an alt statement with timeout here, rather than
736 * having +100500 layers of abstraction. This would facilitate developing the
737 * multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received
738 * block is exactly what you need. */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200739 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700740
741 /* Make sure it's either GPRS or EGPRS data block */
742 if (not match(dl_block, tr_RLCMAC_DATA)) {
743 setverdict(fail, "Failed to match DL DATA: ", dl_block, " vs ", tr_RLCMAC_DATA);
744 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200745 }
746
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700747 if (ischosen(dl_block.data_egprs)) {
748 f_rlcmac_dl_block_verify_data_egprs(dl_block.data_egprs, data, exp_bsn, exp_cs);
749 } else if (ischosen(dl_block.data)) {
750 f_rlcmac_dl_block_verify_data_gprs(dl_block.data, data, exp_bsn, exp_cs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200751 } else {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700752 /* Should not happen, but the caller may theoretically give us a template for CTRL */
753 setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);
754 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200755 }
756}
757
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700758private function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)
759runs on RAW_PCU_Test_CT return uint32_t {
760 var boolean rrbp_valid;
761 var MacRrbp rrbp;
762
763 /* The argument must be either a GPRS or EGPRS data block */
764 if (ischosen(dl_block.data_egprs)) {
765 rrbp_valid := true; /* always valid */
766 rrbp := dl_block.data_egprs.mac_hdr.rrbp;
767 } else if (ischosen(dl_block.data)) {
768 rrbp_valid := dl_block.data.mac_hdr.mac_hdr.rrbp_valid;
769 rrbp := dl_block.data.mac_hdr.mac_hdr.rrbp;
770 } else {
Pau Espin Pedrol1832cd82020-05-13 16:42:24 +0200771 rrbp_valid := dl_block.ctrl.mac_hdr.rrbp_valid;
772 rrbp := dl_block.ctrl.mac_hdr.rrbp;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700773 }
774
775 /* Make sure that the given block really needs to be ACKnowledged */
776 if (not rrbp_valid) {
777 setverdict(fail, "DL block shall not be ACKnowledged, field RRBP is not valid");
778 f_shutdown(__BFILE__, __LINE__);
779 }
780
781 return f_rrbp_ack_fn(dl_fn, rrbp);
782}
783
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200784testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
785 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
786 var GprsTlli tlli := 'FFFFFFFF'O;
787 timer T;
788
789 /* Initialize NS/BSSGP side */
790 f_init_bssgp();
791
792 /* Initialize the PCU interface abstraction */
793 f_init_raw(testcasename());
794
795 /* Establish BSSGP connection to the PCU */
796 f_bssgp_establish();
797
798 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
799
800 T.start(2.0);
801 alt {
802 [] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
803 setverdict(pass);
804 }
805 [] T.timeout {
806 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
807 }
808 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700809
810 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200811}
812
813/* Test of correct Timing Advance at the time of TBF establishment
814 * (derived from timing offset of the Access Burst). */
815testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
816 var GsmRrMessage rr_msg;
817 var boolean ok;
818
819 /* Initialize the PCU interface abstraction */
820 f_init_raw(testcasename());
821
822 /* We cannot send too many TBF requests in a short time because
823 * at some point the PCU will fail to allocate a new TBF. */
824 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
825 /* Establish an Uplink TBF (send RACH.ind with current TA) */
826 ok := f_establish_tbf(rr_msg, bts_nr := 0, ta := ta);
827 if (not ok) {
828 setverdict(fail, "Failed to establish an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700829 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830 }
831
832 /* Make sure Timing Advance IE matches out expectations */
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700833 if (rr_msg.payload.imm_ass.timing_advance != ta) {
834 setverdict(fail, "Timing Advance mismatch: ",
835 rr_msg.payload.imm_ass.timing_advance,
836 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700837 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200838 }
839 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700840
841 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200842}
843
844/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
845 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
846 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
847 * no active TBF exists at the moment of establishment (idle mode). */
848testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
849 var OCT4 tlli := f_rnd_octstring(4);
850 var GsmRrMessage rr_imm_ass;
851
852 /* Initialize NS/BSSGP side */
853 f_init_bssgp();
854
855 /* Initialize the PCU interface abstraction */
856 f_init_raw(testcasename());
857
858 /* Establish BSSGP connection to the PCU */
859 f_bssgp_establish();
860 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
861
862 /* SGSN sends some DL data, PCU will initiate Packet Downlink
863 * Assignment on CCCH (PCH). We don't care about the payload. */
864 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
865 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass); // TODO: match by TLLI!
866
867 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
868 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
869 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
870 if (not match(rr_imm_ass, tr_IMM_TBF_ASS(ta := 0))) {
871 setverdict(fail, "Timing Advance value doesn't match");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200872 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700873
874 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200875}
876
877/* Verify that the PCU generates valid PTCCH/D messages
878 * while neither Uplink nor Downlink TBF is established. */
879testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
880 var PTCCHDownlinkMsg ptcch_msg;
881 var PCUIF_Message pcu_msg;
882 timer T;
883
884 /* Initialize the PCU interface abstraction */
885 f_init_raw(testcasename());
886
887 /* Sent an RTS.req for PTCCH/D */
888 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
889 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
890 arfcn := 871, block_nr := 0));
891 T.start(5.0);
892 alt {
893 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
894 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
895 log("Rx DATA.req message: ", pcu_msg);
896 setverdict(pass);
897 }
898 [] BTS.receive(PCUIF_Message:?) { repeat; }
899 [] T.timeout {
900 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700901 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200902 }
903 }
904
905 ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
906 log("Decoded PTCCH/D message: ", ptcch_msg);
907
908 /* Make sure the message is encoded correctly
909 * TODO: do we expect all TA values to be equal '1111111'B? */
910 if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
911 setverdict(fail, "Malformed PTCCH/D message");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200912 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700913
914 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200915}
916
917/* Test of correct Timing Advance during an active Uplink TBF.
918 *
919 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
920 * are not continuous and there can be long time gaps between them. This happens
921 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
922 * significantly change between such rare Uplink transmissions, so GPRS introduces
923 * additional mechanisms to control Timing Advance, and thus reduce interference
924 * between neighboring TDMA time-slots.
925 *
926 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
927 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
928 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
929 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
930 * among with the initial Timing Advance value. And here PTCCH comes to play.
931 *
932 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
933 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
934 * continuously. To ensure continuous measurements of the signal propagation
935 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
936 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
937 *
938 * The purpose of this test case is to verify the assignment of Timing Advance
939 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
940 * first establishes several Uplink TBFs, but does not transmit any Uplink
941 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
942 * indications to the PCU, checking the correctness of two received PTCCH/D
943 * messages (period of PTCCH/D is two multi-frames).
944 */
945
946/* List of ToA values for Access Bursts to be sent on PTCCH/U,
947 * each ToA (Timing of Arrival) value is in units of 1/4 of
948 * a symbol (i.e. 1 symbol is 4 QTA units). */
949type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
950const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
951 0, 0, 0, 0,
952 0, 0, 0, 0,
953 0, 0, 0, 0,
954 0, 0, 0, 0
955};
956
957private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
958 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
959runs on RAW_PCU_Test_CT {
960 var RAW_PCU_Event event;
961 var integer ss;
962
963 /* Send Access Bursts on PTCCH/U for every TA Index */
964 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
965 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700966 if (ss < 0) { /* Shall not happen */
967 f_shutdown(__BFILE__, __LINE__);
968 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200969
970 log("Sending an Access Burst on PTCCH/U",
971 ", sub-slot=", ss, " (TAI)",
972 ", fn=", event.data.tdma_fn,
973 ", ToA=", toa_map[ss], " (QTA)");
974 /* TODO: do we care about RA and burst format? */
975 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
976 ra := oct2int('3A'O),
977 is_11bit := 0,
978 burst_type := BURST_TYPE_0,
979 fn := event.data.tdma_fn,
980 arfcn := 871,
981 qta := toa_map[ss],
982 sapi := PCU_IF_SAPI_PTCCH));
983 repeat;
984 }
985}
986
987private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
988 template PTCCHDownlinkMsg t_ta_msg)
989runs on RAW_PCU_Test_CT {
990 var PTCCHDownlinkMsg ta_msg;
991 var PCUIF_Message pcu_msg;
992 timer T;
993
994 /* First, send an RTS.req for the upcoming PTCCH/D block */
995 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
996 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
997 arfcn := 871, block_nr := 0));
998 T.start(2.0);
999 alt {
1000 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
1001 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
1002 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
1003 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
1004 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
1005 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
1006 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
1007 log("Rx PTCCH/D message: ", ta_msg);
1008
1009 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001010 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001011 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
1012 }
1013 }
1014 [] BTS.receive { repeat; }
1015 [] T.timeout {
1016 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001017 }
1018 }
1019}
1020
1021testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
1022 var template PacketUlAssign t_ul_tbf_ass;
1023 var PacketUlAssign ul_tbf_ass[7];
1024 var GsmRrMessage rr_msg[7];
1025 var boolean ok;
1026
1027 /* Initialize the PCU interface abstraction */
1028 f_init_raw(testcasename());
1029
1030 /* Enable forwarding of PTCCH/U TDMA events to us */
1031 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
1032
1033 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
1034 for (var integer i := 0; i < 7; i := i + 1) {
1035 ok := f_establish_tbf(rr_msg[i], ta := 0);
1036 if (not ok) {
1037 setverdict(fail, "Failed to establish an Uplink TBF #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001038 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001039 }
1040
1041 /* Make sure we received an UL TBF Assignment */
1042 if (match(rr_msg[i], tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
1043 ul_tbf_ass[i] := rr_msg[i].payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
1044 log("Rx Uplink TBF assignment for #", i, ": ", ul_tbf_ass[i]);
1045 } else {
1046 setverdict(fail, "Failed to match UL TBF Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001047 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001048 }
1049
1050 /* We expect incremental TFI/USF assignment (dynamic allocation) */
1051 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
1052 if (not match(ul_tbf_ass[i], t_ul_tbf_ass)) {
1053 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001054 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001055 }
1056
1057 /* We also expect Timing Advance Index to be a part of the assignment */
1058 if (ul_tbf_ass[i].dynamic.ta_index != i) {
1059 setverdict(fail, "Failed to match Timing Advance Index for #", i);
1060 /* Keep going, the current OsmoPCU does not assign TA Index */
1061 }
1062 }
1063
1064 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
1065 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
1066 for (var integer i := 0; i < 7; i := i + 1) {
1067 /* ToA in units of 1/4 of a symbol */
1068 toa_map[i] := (i + 1) * 7 * 4;
1069 }
1070
1071 /* Now we have all 7 TBFs established in one-phase access mode,
1072 * however we will not be sending any data on them. Instead, we
1073 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
1074 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
1075 *
1076 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
1077 * time-slots, so at the moment of scheduling a PTCCH/D block
1078 * the PCU has odd number of PTCCH/U Access Bursts received. */
1079 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
1080 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
1081 /* Other values are not known (yet) */
1082 tai3_ta := ?));
1083 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
1084 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
1085 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
1086 /* Other values are out of our interest */
1087 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001088
1089 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001090}
1091
1092/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
1093 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
1094 *
1095 * NOTE: the ranges are intentionally overlapping because OsmoPCU
1096 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
1097private template integer CS1_lqual_dB_range := (-infinity .. 6);
1098private template integer CS2_lqual_dB_range := (5 .. 8);
1099private template integer CS3_lqual_dB_range := (7 .. 13);
1100private template integer CS4_lqual_dB_range := (12 .. infinity);
1101
1102testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
1103 var GsmRrMessage rr_imm_ass;
1104 var PacketUlAssign ul_tbf_ass;
1105 var RlcmacDlBlock dl_block;
1106 var PCUIF_Message pcu_msg;
1107 var octetstring data;
1108 var boolean ok;
1109 var uint32_t unused_fn;
1110
1111 /* Initialize the PCU interface abstraction */
1112 f_init_raw(testcasename());
1113
1114 f_pcuvty_set_allowed_cs_mcs();
1115 f_pcuvty_set_link_quality_ranges();
1116
1117 /* Establish an Uplink TBF */
1118 ok := f_establish_tbf(rr_imm_ass);
1119 if (not ok) {
1120 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001121 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001122 }
1123
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001124 /* Make sure we've got an Uplink TBF assignment */
1125 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001126
1127 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1128 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1129 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
1130 bsn := 0, /* TODO: what should be here? */
1131 blocks := { /* To be generated in loop */ });
1132
1133 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1134 ul_data.data.tlli := '00000001'O;
1135
1136 /* The actual / old link quality values. We need to keep track of the old
1137 * (basically previous) link quality value, because OsmoPCU actually
1138 * changes the coding scheme if not only the actual, but also the old
1139 * value leaves the current link quality range (window). */
1140 var integer lqual := 0;
1141 var integer lqual_old;
1142
1143 /* 16 UL blocks (0 .. 15 dB, step = 1 dB) */
1144 for (var integer i := 0; i < 16; i := i + 1) {
1145 /* Prepare a new UL block (CV, random payload) */
1146 ul_data.data.mac_hdr.countdown := (15 - i);
1147 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1148
1149 /* Update the old / actual link quality */
1150 lqual_old := lqual;
1151 lqual := i;
1152
1153 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1154 log("Sending DATA.ind with link quality (dB): ", lqual);
1155 f_tx_rlcmac_ul_block(ul_data, lqual * 10);
1156
1157 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1158 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1159
1160 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
1161 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
1162
1163 /* Match the received Channel Coding Command. Since we are increasing
1164 * the link quality value on each iteration and not decreasing, there
1165 * is no need to check the both old and current link quality values. */
1166 var template ChCodingCommand ch_coding;
1167 select (lqual_old) {
1168 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
1169 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
1170 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
1171 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
1172 }
1173
1174 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
1175 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001176 }
1177 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001178
1179 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001180}
1181
1182/* Test the max UL CS set by VTY works fine */
1183testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
1184 var GsmRrMessage rr_imm_ass;
1185 var PacketUlAssign ul_tbf_ass;
1186 var RlcmacDlBlock dl_block;
1187 var boolean ok;
1188 var integer lqual_cb;
1189 var ChCodingCommand last_ch_coding;
1190 var uint32_t unused_fn;
1191
1192 /* Initialize the PCU interface abstraction */
1193 f_init_raw(testcasename());
1194
1195 /* Set initial UL CS to 3 */
1196 g_cs_initial_ul := 3;
1197 f_pcuvty_set_allowed_cs_mcs();
1198 f_pcuvty_set_link_quality_ranges();
1199
1200 /* Take lqual (dB->cB) so that we stay in that CS */
1201 lqual_cb := g_cs_lqual_ranges[2].low * 10;
1202
1203 /* Establish an Uplink TBF */
1204 ok := f_establish_tbf(rr_imm_ass);
1205 if (not ok) {
1206 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001207 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001208 }
1209
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001210 /* Make sure we've got an Uplink TBF assignment */
1211 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001212
1213 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1214 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1215 cv := 3, /* 8 UL blocks to be sent (to be overridden in loop) */
1216 bsn := 0, /* TODO: what should be here? */
1217 blocks := { /* To be generated in loop */ });
1218
1219 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1220 ul_data.data.tlli := '00000001'O;
1221
1222 /* 3 UL blocks, check we are in same initial CS: */
1223 for (var integer i := 0; i < 3; i := i + 1) {
1224 /* Prepare a new UL block (CV, random payload) */
1225 ul_data.data.mac_hdr.countdown := (7 - i);
1226 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1227
1228 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1229 f_tx_rlcmac_ul_block(ul_data, lqual_cb);
1230
1231 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1232 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1233 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1234 }
1235
1236 if (last_ch_coding != CH_CODING_CS3) {
1237 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001238 }
1239
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001240 /* Remaining UL blocks are used to make sure regardless of initial
1241 /* lqual, we can go lower at any time */
1242
1243 /* 5 UL blocks, check we are in same initial CS: */
1244 for (var integer i := 3; i < 8; i := i + 1) {
1245 /* Prepare a new UL block (CV, random payload) */
1246 ul_data.data.mac_hdr.countdown := (7 - i);
1247 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1248
1249 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1250 f_tx_rlcmac_ul_block(ul_data, 0); /* 0 dB, make sure we downgrade CS */
1251
1252 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1253 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1254
1255 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1256 }
1257
1258 if (last_ch_coding != CH_CODING_CS1) {
1259 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001260 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001261
1262 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001263}
1264
1265/* Test the max UL CS set by VTY works fine */
1266testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
1267 var GsmRrMessage rr_imm_ass;
1268 var PacketUlAssign ul_tbf_ass;
1269 var RlcmacDlBlock dl_block;
1270 var boolean ok;
1271 var ChCodingCommand last_ch_coding;
1272 var uint32_t unused_fn;
1273
1274 /* Initialize the PCU interface abstraction */
1275 f_init_raw(testcasename());
1276
1277 /* Set maximum allowed UL CS to 3 */
1278 g_cs_max_ul := 3;
1279 f_pcuvty_set_allowed_cs_mcs();
1280 f_pcuvty_set_link_quality_ranges();
1281
1282 /* Establish an Uplink TBF */
1283 ok := f_establish_tbf(rr_imm_ass);
1284 if (not ok) {
1285 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001286 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001287 }
1288
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001289 /* Make sure we've got an Uplink TBF assignment */
1290 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001291
1292 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1293 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1294 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
1295 bsn := 0, /* TODO: what should be here? */
1296 blocks := { /* To be generated in loop */ });
1297
1298 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1299 ul_data.data.tlli := '00000001'O;
1300
1301 /* 16 UL blocks */
1302 for (var integer i := 0; i < 16; i := i + 1) {
1303 /* Prepare a new UL block (CV, random payload) */
1304 ul_data.data.mac_hdr.countdown := (15 - i);
1305 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1306
1307 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1308 f_tx_rlcmac_ul_block(ul_data, 40*10); /* 40 dB */
1309
1310 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1311 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1312
1313 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1314 }
1315
1316 if (last_ch_coding != CH_CODING_CS3) {
1317 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001318 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001319
1320 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001321}
1322
1323/* Verify PCU drops TBF after some time of inactivity. */
1324testcase TC_t3169() runs on RAW_PCU_Test_CT {
1325 var PCUIF_info_ind info_ind;
1326 var GsmRrMessage rr_imm_ass;
1327 var PacketUlAssign ul_tbf_ass;
1328 var RlcmacDlBlock dl_block;
1329 var PCUIF_Message pcu_msg;
1330 var octetstring data;
1331 var boolean ok;
1332 var uint32_t unused_fn;
1333 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001334 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001335
1336 /* Initialize NS/BSSGP side */
1337 f_init_bssgp();
1338
1339 info_ind := valueof(ts_PCUIF_INFO_default);
1340 /* Set timer to 1 sec (default 5) to speedup test: */
1341 info_ind.t3169 := 1;
1342
1343 /* Initialize the PCU interface abstraction */
1344 f_init_raw(testcasename(), info_ind);
1345
1346 /* Establish BSSGP connection to the PCU */
1347 f_bssgp_establish();
1348 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1349
1350 /* Establish an Uplink TBF */
1351 ok := f_establish_tbf(rr_imm_ass);
1352 if (not ok) {
1353 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001354 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001355 }
1356
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001357 /* Make sure we've got an Uplink TBF assignment */
1358 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001359
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001360 /* Send one UL block (with TLLI since we are in One-Phase Access
1361 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001362 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001363 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1364 /* UL block should be received in SGSN */
1365 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1366
1367 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
1368 f_sleep(int2float(info_ind.t3169) + 1.0);
1369
1370 /* Send an UL block once again, the TBF should be gone by now so no ACK */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001371 bsn := 0;
1372 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001373 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001374
1375 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001376}
1377
1378/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1379 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1380 * T3193) after DL TBF release */
1381testcase TC_t3193() runs on RAW_PCU_Test_CT {
1382 var GsmRrMessage rr_imm_ass;
1383 var PacketDlAssign dl_tbf_ass;
1384 var RlcmacDlBlock dl_block;
1385 var octetstring data := f_rnd_octstring(10);
1386 var boolean ok;
1387 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001388 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001389 var OCT4 tlli := '00000001'O;
1390 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1391
1392 /* Initialize NS/BSSGP side */
1393 f_init_bssgp();
1394
1395 /* Initialize the PCU interface abstraction */
1396 f_init_raw(testcasename());
1397
1398 /* Establish BSSGP connection to the PCU */
1399 f_bssgp_establish();
1400 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1401
1402 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1403 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1404 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001405
1406 /* Make sure we've got a Downlink TBF assignment */
1407 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1408
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001409 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1410 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001411 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001412
1413 /* ACK the DL block */
1414 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001415 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1416 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001417 /* we are done with the DL-TBF here so far, let's clean up our local state: */
1418 ack_nack_desc := valueof(t_AckNackDescription_init)
1419
1420 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
1421 (T3192 in MS) was started and until it fires the MS will be abailable
1422 on PDCH in case new data arrives from SGSN. Let's verify it: */
1423 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1424 f_rx_rlcmac_dl_block_exp_pkt_ass(dl_block, sched_fn);
1425 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1426
1427 /* 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 +07001428 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001429 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001430 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1431 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001432
1433 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001434}
1435
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02001436/* Verify PCU handles correctly Countdown Procedure based on BS_CV_MAX */
1437testcase TC_countdown_procedure() runs on RAW_PCU_Test_CT {
1438 var GsmRrMessage rr_imm_ass;
1439 var PacketUlAssign ul_tbf_ass;
1440 var RlcmacDlBlock dl_block;
1441 var boolean ok;
1442 var uint32_t sched_fn;
1443 var OCT4 tlli := '00000001'O;
1444 var uint14_t bsn := 1;
1445 var PDU_BSSGP bssgp_pdu;
1446 var octetstring total_payload;
1447 var integer padding_len;
1448
1449 /* Initialize NS/BSSGP side */
1450 f_init_bssgp();
1451
1452 /* Initialize the PCU interface abstraction */
1453 f_init_raw(testcasename());
1454
1455 /* Establish BSSGP connection to the PCU */
1456 f_bssgp_establish();
1457 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1458
1459 /* Establish an Uplink TBF */
1460 ok := f_establish_tbf(rr_imm_ass);
1461 if (not ok) {
1462 setverdict(fail, "Failed to establish TBF");
1463 f_shutdown(__BFILE__, __LINE__);
1464 }
1465 /* Make sure we've got an Uplink TBF assignment */
1466 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1467
1468 /* Send one UL block (with TLLI since we are in One-Phase Access
1469 contention resoultion) and make sure it is ACKED fine. */
1470 total_payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1471 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA_TLLI(
1472 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1473 cv := 15, /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
1474 bsn := 0,
1475 blocks := { valueof(t_RLCMAC_LLCBLOCK(total_payload)) },
1476 tlli := tlli);
1477
1478 f_tx_rlcmac_ul_block(ul_data, 0);
1479 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1480 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1481 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1482
1483 /* Send enough blocks to test whole procedure: Until Nth block
1484 (N=BS_CV_MAX), CV=15 is sent, and then the decreasing countdown value is sent.
1485 */
1486 total_payload := total_payload & f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 20);
1487 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1488 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1489 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1490
1491 /* receive one message on BSSGP with all aggregated data in payload: */
1492 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id, total_payload));
1493}
1494
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001495/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1496 * answered, so TBFs for uplink and later for downlink are created.
1497 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001498private 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 +02001499 var GsmRrMessage rr_imm_ass;
1500 var PacketUlAssign ul_tbf_ass;
1501 var PacketDlAssign dl_tbf_ass;
1502 var RlcmacDlBlock dl_block;
1503 var PCUIF_Message pcu_msg;
1504 var octetstring data := f_rnd_octstring(10);
1505 var boolean ok;
1506 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001507 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001508 var OCT4 tlli := '00000001'O;
1509 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001510 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001511
1512 /* Initialize NS/BSSGP side */
1513 f_init_bssgp();
1514
1515 /* Initialize the PCU interface abstraction */
1516 f_init_raw(testcasename());
1517
1518 /* Establish BSSGP connection to the PCU */
1519 f_bssgp_establish();
1520 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1521
1522 /* Establish an Uplink TBF */
1523 ok := f_establish_tbf(rr_imm_ass);
1524 if (not ok) {
1525 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001526 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001527 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001528
1529 /* Make sure we've got an Uplink TBF assignment */
1530 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001531
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001532 /* Send one UL block (with TLLI since we are in One-Phase Access
1533 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001534 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001535 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1536 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1537 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1538
1539 /* UL block should be received in SGSN */
1540 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1541
1542 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
1543 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1544 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1545
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001546 /* Make sure we've got a Downlink TBF assignment */
1547 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001548
1549 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1550 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001551 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001552
1553 /* ACK the DL block */
1554 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001555 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1556 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001557
1558 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001559}
1560
1561/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1562 * answered, so TBFs for uplink and later for downlink are created.
1563 */
1564testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
1565 var CodingScheme exp_cs_mcs := CS_1;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001566 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001567}
1568
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001569/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1570 * answered, so TBFs for uplink and later for downlink are created.
1571 */
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001572private function f_TC_mo_ping_pong_2phase_access(template (value) MSRadioAccessCapabilityV ms_racap,
1573 template (present) CodingScheme exp_ul_cs_mcs := ?,
1574 template (present) CodingScheme exp_dl_cs_mcs := ?)
1575runs on RAW_PCU_Test_CT {
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001576 var GsmRrMessage rr_imm_ass;
1577 var PacketUlAssign ul_tbf_ass;
1578 var PacketDlAssign dl_tbf_ass;
1579 var RlcmacDlBlock dl_block;
1580 var PCUIF_Message pcu_msg;
1581 var octetstring data := f_rnd_octstring(10);
1582 var boolean ok;
1583 var uint32_t sched_fn;
1584 var uint32_t dl_fn;
1585 var OCT4 tlli := '00000001'O;
1586 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001587 var CodingScheme cs_mcs;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001588 var uint14_t bsn := 0;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001589 /* 0111 0xxx: Single block packet access; one block period on a PDCH is needed for two phase packet access or other RR signalling purpose. */
1590 var uint16_t ra := oct2int('70'O);
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001591 if (g_force_two_phase_access) {
1592 /* If 2phase access is enforced by the network, then let's
1593 request a One phase packet access, we'll receive a single block
1594 anyway */
1595 ra := bit2int(chan_req_def);
1596 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001597
1598 /* Initialize NS/BSSGP side */
1599 f_init_bssgp();
1600
1601 /* Initialize the PCU interface abstraction */
1602 f_init_raw(testcasename());
1603
1604 /* Establish BSSGP connection to the PCU */
1605 f_bssgp_establish();
1606 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1607
1608 /* Establish an Uplink TBF */
1609 ok := f_establish_tbf(rr_imm_ass, ra := ra);
1610 if (not ok) {
1611 setverdict(fail, "Failed to establish TBF");
1612 f_shutdown(__BFILE__, __LINE__);
1613 }
1614
1615 /* Make sure we've got an Uplink TBF assignment */
1616 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass, tr_PacketUlSglAssign);
1617
1618 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
1619 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
1620 */
1621 f_tx_rlcmac_ul_block(ts_RLC_UL_CTRL_ACK(valueof(ts_RlcMacUlCtrl_PKT_RES_REQ(tlli, ms_racap))), 0);
1622 f_rx_rlcmac_dl_block_exp_pkt_ul_ass(dl_block, sched_fn);
1623 if (dl_block.ctrl.payload.u.ul_assignment.identity.tlli.tlli != tlli) {
1624 setverdict(fail, "Wrong TLLI ", dl_block.ctrl.payload.u.ul_assignment.identity.tlli, " received vs exp ", tlli);
1625 f_shutdown(__BFILE__, __LINE__);
1626 }
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001627 cs_mcs := f_rlcmac_dl_block_get_assigned_ul_cs_mcs(dl_block);
1628 if (not match(cs_mcs, exp_ul_cs_mcs)) {
1629 setverdict(fail, "Wrong CS_MCS ", cs_mcs, " received vs exp ", exp_ul_cs_mcs);
1630 f_shutdown(__BFILE__, __LINE__);
1631 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001632
1633 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1634 and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001635 f_tx_rlcmac_ul_n_blocks(f_rlcmac_dl_block_get_tfi(dl_block), bsn, 1); /* TODO: send using cs_mcs */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001636
1637 //f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1638 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1639 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1640
1641 /* UL block should be received in SGSN */
1642 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1643
1644 /* Now SGSN sends some DL data, PCU will page on PACCH */
1645 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1646 f_rx_rlcmac_dl_block_exp_pkt_dl_ass(dl_block, sched_fn);
1647 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
1648 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1649
1650 /* 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 +02001651 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 +02001652
1653 /* ACK the DL block */
1654 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
1655 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1656 0, f_dl_block_ack_fn(dl_block, dl_fn));
1657
1658 f_shutdown(__BFILE__, __LINE__, final := true);
1659}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001660
1661testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1662 var MultislotCap_GPRS mscap_gprs := {
1663 gprsmultislotclass := '00011'B,
1664 gprsextendeddynalloccap := '0'B
1665 };
1666 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001667 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1668 var CodingScheme exp_dl_cs_mcs := CS_2;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001669
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02001670 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1671}
1672
1673testcase TC_mo_ping_pong_with_ul_racap_egprs_only() runs on RAW_PCU_Test_CT {
1674 /* Initialize the PCU interface abstraction with EGPRS-only */
1675 g_egprs_only := true;
1676
1677 var MultislotCap_GPRS mscap_gprs := {
1678 gprsmultislotclass := '00011'B,
1679 gprsextendeddynalloccap := '0'B
1680 };
1681 var MultislotCap_EGPRS mscap_egprs := {
1682 egprsmultislotclass := '00011'B,
1683 egprsextendeddynalloccap := '0'B
1684 };
1685 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, mscap_egprs)) };
1686 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, true);
1687 var CodingScheme exp_dl_cs_mcs := MCS_1;
1688
1689 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 +02001690}
1691
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02001692testcase TC_force_two_phase_access() runs on RAW_PCU_Test_CT {
1693 /* Configure PCU to force two phase access */
1694 g_force_two_phase_access := true;
1695
1696 var MultislotCap_GPRS mscap_gprs := {
1697 gprsmultislotclass := '00011'B,
1698 gprsextendeddynalloccap := '0'B
1699 };
1700 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1701 var CodingScheme exp_ul_cs_mcs := f_rlcmac_block_int2cs_mcs(g_mcs_initial_ul, false);
1702 var CodingScheme exp_dl_cs_mcs := CS_2;
1703
1704 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_ul_cs_mcs, exp_dl_cs_mcs);
1705}
1706
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001707/* Test scenario where SGSN wants to send some data against MS and it is
1708 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1709 */
1710private 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 {
1711 var GsmRrMessage rr_imm_ass;
1712 var PacketUlAssign ul_tbf_ass;
1713 var PacketDlAssign dl_tbf_ass;
1714 var RlcmacDlBlock dl_block;
1715 var PCUIF_Message pcu_msg;
1716 var octetstring data := f_rnd_octstring(10);
1717 var boolean ok;
1718 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001719 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001720 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001721 var uint14_t bsn := 0;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001722 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1723
1724 /* Initialize NS/BSSGP side */
1725 f_init_bssgp();
1726
1727 /* Initialize the PCU interface abstraction */
1728 f_init_raw(testcasename());
1729
1730 /* Establish BSSGP connection to the PCU */
1731 f_bssgp_establish();
1732 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1733
1734 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1735 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
1736 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1737
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001738 /* Make sure we've got a Downlink TBF assignment */
1739 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001740
1741 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1742 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001743 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001744
1745 /* ACK the DL block */
1746 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001747 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1748 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001749
1750 /* Now MS wants to answer the DL data, Establish an Uplink TBF */
1751 ok := f_establish_tbf(rr_imm_ass);
1752 if (not ok) {
1753 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001754 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001755 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001756
1757 /* Make sure we've got an Uplink TBF assignment */
1758 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001759
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001760 /* Send one UL block (with TLLI since we are in One-Phase Access
1761 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol4cbb9602020-05-14 19:21:49 +02001762 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001763 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1764 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1765 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1766
1767 /* UL block should be received in SGSN */
1768 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001769
1770 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001771}
1772
1773testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
1774 var CodingScheme exp_cs_mcs := CS_1;
1775 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1776}
1777
1778/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1779/* information about the MS */
1780testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1781 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1782 gprsmultislotclass := '00011'B,
1783 gprsextendeddynalloccap := '0'B
1784 } ;
1785 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
1786 var CodingScheme exp_cs_mcs := CS_2;
1787 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1788}
1789
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02001790/* Verify that if PCU doesn't get one of the intermediate UL data blocks in a UL
1791 * TBF, it will request retransmission through UL ACK/NACK (with missing block
1792 * in its bitmap) when CV=0 is received (and hence it knows no more data is to
1793 * be transferred).
1794 */
1795testcase TC_ul_intermediate_retrans() runs on RAW_PCU_Test_CT {
1796 var GsmRrMessage rr_imm_ass;
1797 var PacketUlAssign ul_tbf_ass;
1798 var RlcmacDlBlock dl_block;
1799 var template (value) RlcmacUlBlock ul_data;
1800 var boolean ok;
1801 var uint32_t sched_fn;
1802 var OCT4 tlli := '00000001'O;
1803 var uint14_t bsn := 5;
1804 var PDU_BSSGP bssgp_pdu;
1805 var octetstring total_payload;
1806 var octetstring payload;
1807 var octetstring lost_payload;
1808 var integer padding_len;
1809 var uint5_t tfi;
1810
1811 /* Initialize NS/BSSGP side */
1812 f_init_bssgp();
1813
1814 /* Initialize the PCU interface abstraction */
1815 f_init_raw(testcasename());
1816
1817 /* Establish BSSGP connection to the PCU */
1818 f_bssgp_establish();
1819 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1820
1821 /* Establish an Uplink TBF */
1822 ok := f_establish_tbf(rr_imm_ass);
1823 if (not ok) {
1824 setverdict(fail, "Failed to establish TBF");
1825 f_shutdown(__BFILE__, __LINE__);
1826 }
1827 /* Make sure we've got an Uplink TBF assignment */
1828 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1829 tfi := ul_tbf_ass.dynamic.tfi_assignment;
1830
1831 /* Send one UL block (with TLLI since we are in One-Phase Access
1832 contention resoultion) and make sure it is ACKED fine. */
1833 payload := f_rnd_octstring(16); /* 16 bytes fills the llc block (because TLLI takes 4 bytes) */
1834 ul_data := t_RLCMAC_UL_DATA_TLLI(
1835 tfi := tfi,
1836 cv := 15, /* Set CV = 15 to signal there's still more than BS_CV_MAX blocks to be sent */
1837 bsn := 0,
1838 blocks := { valueof(t_RLCMAC_LLCBLOCK(payload)) },
1839 tlli := tlli);
1840
1841 f_tx_rlcmac_ul_block(ul_data, 0);
1842 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1843 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1844 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1845 total_payload := payload;
1846
1847 /* Send 2 packets, skip 1 (inc bsn) and send another one */
1848 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1849 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 1, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1850 f_tx_rlcmac_ul_block(ul_data, 0);
1851 total_payload := total_payload & payload;
1852
1853 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1854 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 2, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1855 f_tx_rlcmac_ul_block(ul_data, 0);
1856 total_payload := total_payload & payload;
1857
1858 lost_payload := f_rnd_octstring(20); /* LOST PAYLOAD bsn=3, will be retransmitted, next bsn is increased +2 */
1859 total_payload := total_payload & lost_payload;
1860
1861 payload := f_rnd_octstring(20); /* 20 bytes fills the CS-1 llc block */
1862 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 4, blocks := {t_RLCMAC_LLCBLOCK(payload)});
1863 f_tx_rlcmac_ul_block(ul_data, 0);
1864 total_payload := total_payload & payload;
1865
1866 /* Send enough blocks to finish the transmission (since we were sending BSN=15, send BS_CV_MAX packets) */
1867 total_payload := total_payload & f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, bsn, g_bs_cv_max);
1868
1869 /* On CV=0, we'll receive a UL ACK asking about missing block */
1870 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1871 /* TODO: check ack ack bitmap (URBB) */
1872 ul_data := t_RLCMAC_UL_DATA(tfi := tfi, cv := 15, bsn := 3, blocks := {t_RLCMAC_LLCBLOCK(lost_payload)});
1873 f_tx_rlcmac_ul_block(ul_data, 0);
1874
1875 /* Now final ack is recieved */
1876 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1877 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1878 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1879
1880 /* receive one message on BSSGP with all aggregated data in payload: */
1881 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id, total_payload));
1882}
1883
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001884/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1885 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1886 * timeout occurs (specified by sent RRBP on DL block). */
1887testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
1888 var GsmRrMessage rr_imm_ass;
1889 var PacketDlAssign dl_tbf_ass;
1890 var RlcmacDlBlock dl_block;
1891 var octetstring data := f_rnd_octstring(10);
1892 var boolean ok;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001893 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001894 var OCT4 tlli := '00000001'O;
1895 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1896
1897 /* Initialize NS/BSSGP side */
1898 f_init_bssgp();
1899
1900 /* Initialize the PCU interface abstraction */
1901 f_init_raw(testcasename());
1902
1903 /* Establish BSSGP connection to the PCU */
1904 f_bssgp_establish();
1905 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1906
1907 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1908 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1909 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001910
1911 /* Make sure we've got a Downlink TBF assignment */
1912 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001913
1914 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1915 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001916 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001917
1918 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1919 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1920 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
1921 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001922
1923 /* Make sure we've got a Downlink TBF assignment */
1924 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1925
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001926 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1927 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001928 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001929
1930 /* ACK the DL block */
1931 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001932 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1933 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001934
1935 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001936}
1937
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001938/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1939testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1940 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1941 var octetstring data := f_rnd_octstring(16);
1942 var OCT4 tlli := f_rnd_octstring(4);
1943 var PacketDlAssign dl_tbf_ass;
1944 var GsmRrMessage rr_imm_ass;
1945 var RlcmacDlBlock dl_block;
1946 var uint32_t ack_fn;
1947 var uint32_t fn;
1948 timer T := 5.0;
1949
1950 /* Initialize NS/BSSGP side */
1951 f_init_bssgp();
1952
1953 /* Initialize the PCU interface abstraction */
1954 f_init_raw(testcasename());
1955
1956 /* Establish BSSGP connection to the PCU */
1957 f_bssgp_establish();
1958 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1959
1960 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1961 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1962 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1963
1964 /* Make sure we've got a Downlink TBF assignment with DL TFI */
1965 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1966 if (not ispresent(dl_tbf_ass.group1)) {
1967 setverdict(fail, "Immediate Assignment contains no DL TFI");
1968 f_shutdown(__BFILE__, __LINE__);
1969 }
1970
1971 /* Get DL TFI from received Downlink TBF assignment */
1972 var uint5_t tfi := dl_tbf_ass.group1.tfi_assignment;
1973
1974 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1975 f_sleep(X2002);
1976
1977 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
1978 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
1979 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1980
1981 /* TDMA frame number on which we are supposed to send the ACK */
1982 ack_fn := f_dl_block_ack_fn(dl_block, fn);
1983
1984 /* SGSN sends more blocks during the indicated RRBP */
1985 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
1986 data := f_rnd_octstring(16); /* Random LLC data */
1987 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1988
1989 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
1990
1991 /* Make sure this block has the same TFI as was assigned
1992 * FIXME: this is only valid for GPRS, not EGPRS. */
1993 if (dl_block.data.mac_hdr.hdr_ext.tfi != tfi) {
1994 setverdict(fail, "Rx DL data block with unexpected TFI: ",
1995 dl_block.data.mac_hdr.hdr_ext.tfi);
1996 f_shutdown(__BFILE__, __LINE__);
1997 }
1998
1999 /* Keep Ack/Nack description updated */
2000 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
2001
2002 /* Break if this is the end of RRBP */
2003 if (fn == ack_fn) {
2004 ack_nack_desc.final_ack := '1'B;
2005 break;
2006 }
2007 }
2008
2009 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
2010 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(tfi, ack_nack_desc), fn := fn);
2011
2012 /* Make sure that the next block (after the Ack) is dummy */
2013 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
2014
2015 f_shutdown(__BFILE__, __LINE__, final := true);
2016}
2017
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002018private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
2019runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002020 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
2021 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
2022
2023 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
2024 setverdict(fail, "Mobile Identity length mismatch: ",
2025 "expected: 8, got: ", mi_lv.len);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002026 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002027 }
2028
2029 /* Make sure MI contains IMSI before referencing it */
2030 if (mi.typeOfIdentity != '001'B) {
2031 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
2032 "got: ", mi.typeOfIdentity);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002033 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002034 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
2035 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
2036 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002037 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002038 }
2039}
2040
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002041private function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)
2042runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002043 if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {
2044 setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",
2045 "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002046 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002047 }
2048}
2049
2050/* Test CS paging over the BTS<->PCU socket.
2051 * 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.
2052 * Paging should be send on the PACCH.
2053 *
2054 * 1. Send a Paging Request over PCU socket.
2055 * 2. Send a Ready-To-Send message over PCU socket
2056 * 3. Expect a Paging Frame
2057 */
2058testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
2059 var GsmRrMessage rr_imm_ass;
2060 var PacketUlAssign ul_tbf_ass;
2061 var RlcmacDlBlock dl_block;
2062 var boolean ok;
2063 var OCT4 tlli := '00000001'O;
2064 var MobileIdentityLV mi;
2065 var octetstring mi_enc_lv;
2066 var hexstring imsi := f_gen_imsi(42);
2067
2068 /* Initialize NS/BSSGP side */
2069 f_init_bssgp();
2070
2071 /* Initialize the PCU interface abstraction */
2072 f_init_raw(testcasename());
2073
2074 /* Establish BSSGP connection to the PCU */
2075 f_bssgp_establish();
2076 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
2077
2078 /* Establish an Uplink TBF */
2079 ok := f_establish_tbf(rr_imm_ass);
2080 if (not ok) {
2081 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002082 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002083 }
2084
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002085 /* Make sure we've got an Uplink TBF assignment */
2086 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002087
2088 /* build mobile Identity */
2089 mi := valueof(ts_MI_IMSI_LV(imsi));
2090 mi_enc_lv := enc_MobileIdentityLV(mi);
2091 /* Send paging request */
2092 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
2093 sapi :=PCU_IF_SAPI_PDTCH));
2094
2095 /* Receive it on BTS side towards MS */
2096 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
2097
2098 /* Make sure that Packet Paging Request contains the same IMSI */
2099 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
2100
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002101 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002102}
2103
2104/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
2105 */
2106private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
2107runs on RAW_PCU_Test_CT {
2108 var GsmRrMessage rr_imm_ass;
2109 var PacketUlAssign ul_tbf_ass;
2110 var RlcmacDlBlock dl_block;
2111 var boolean ok;
2112 var OCT4 tlli := '00000001'O;
2113 var hexstring imsi := f_gen_imsi(42);
2114 var GsmTmsi tmsi;
2115
2116 /* Initialize NS/BSSGP side */
2117 f_init_bssgp();
2118
2119 /* Initialize the PCU interface abstraction */
2120 f_init_raw(testcasename());
2121
2122 /* Establish BSSGP connection to the PCU */
2123 f_bssgp_establish();
2124 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
2125
2126 /* Establish an Uplink TBF */
2127 ok := f_establish_tbf(rr_imm_ass);
2128 if (not ok) {
2129 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002130 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002131 }
2132
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07002133 /* Make sure we've got an Uplink TBF assignment */
2134 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002135
2136 /* Send paging request with or without TMSI */
2137 if (use_ptmsi) {
2138 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
2139 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
2140 } else {
2141 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
2142 }
2143
2144 /* Receive it on BTS side towards MS */
2145 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
2146
2147 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
2148 if (use_ptmsi) {
2149 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
2150 } else {
2151 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
2152 }
2153
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002154 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002155}
2156
2157testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
2158 f_tc_paging_cs_from_sgsn(0, true);
2159}
2160
2161testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
2162 f_tc_paging_cs_from_sgsn(0);
2163}
2164
2165testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
2166 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
2167}
2168
2169/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
2170 */
2171private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
2172runs on RAW_PCU_Test_CT {
2173 var OCT4 tlli := '00000001'O;
2174 var integer imsi_suff_tx := 423;
2175 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
2176
2177 /* Initialize NS/BSSGP side */
2178 f_init_bssgp();
2179
2180 /* Initialize the PCU interface abstraction */
2181 f_init_raw(testcasename());
2182
2183 /* Establish BSSGP connection to the PCU */
2184 f_bssgp_establish();
2185 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
2186
2187 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
2188 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
2189 if (use_ptmsi) {
2190 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
2191 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
2192 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
2193 } else {
2194 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
2195 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
2196 }
2197
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002198 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002199}
2200
2201testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
2202 f_tc_paging_ps_from_sgsn(0, true);
2203}
2204
2205testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
2206 f_tc_paging_ps_from_sgsn(0);
2207}
2208
2209testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
2210 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
2211}
2212
2213private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
2214 template GsmRrMessage t_imm_ass := ?,
2215 PCUIF_BurstType bt := BURST_TYPE_1)
2216runs on RAW_PCU_Test_CT {
2217 var GsmRrMessage rr_msg;
2218 var uint16_t ra11;
2219 var boolean ok;
2220
2221 ra11 := enc_EGPRSPktChRequest2uint(req);
2222 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
2223
2224 ok := f_establish_tbf(rr_msg, ra := ra11, is_11bit := 1, burst_type := bt);
2225 if (not ok) {
2226 setverdict(fail, "Failed to establush an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002227 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002228 }
2229
2230 if (not match(rr_msg, t_imm_ass)) {
2231 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002232 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002233 }
2234
2235 setverdict(pass);
2236}
2237
2238testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
2239 var template GsmRrMessage imm_ass;
2240 var template IaRestOctets rest;
2241 var template EgprsUlAss ul_ass;
2242
2243 /* Initialize the PCU interface abstraction */
2244 f_init_raw(testcasename());
2245
2246 var EGPRSPktChRequest req := {
2247 /* NOTE: other fields are set in the loop */
2248 signalling := { tag := '110011'B }
2249 };
2250
2251 for (var integer i := 0; i < 6; i := i + 1) {
2252 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2253 req.signalling.random_bits := ext_ra;
2254
2255 /* For signalling, do we expect Multiblock UL TBF Assignment? */
2256 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2257 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2258 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2259
2260 f_TC_egprs_pkt_chan_req(req, imm_ass);
2261 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002262
2263 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002264}
2265
2266testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
2267 var template GsmRrMessage imm_ass;
2268 var template IaRestOctets rest;
2269 var template EgprsUlAss ul_ass;
2270
2271 /* Initialize the PCU interface abstraction */
2272 f_init_raw(testcasename());
2273
2274 var EGPRSPktChRequest req := {
2275 /* NOTE: other fields are set in the loop */
2276 one_phase := { tag := '0'B }
2277 };
2278
2279 for (var integer i := 0; i < 6; i := i + 1) {
2280 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2281 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
2282 var BIT2 priority := substr(ext_ra, 0, 2);
2283 var BIT3 rand := substr(ext_ra, 2, 3);
2284
2285 req.one_phase.multislot_class := mslot_class;
2286 req.one_phase.priority := priority;
2287 req.one_phase.random_bits := rand;
2288
2289 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
2290 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
2291 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2292 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2293
2294 f_TC_egprs_pkt_chan_req(req, imm_ass);
2295 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002296
2297 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002298}
2299
2300testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
2301 var template GsmRrMessage imm_ass;
2302 var template IaRestOctets rest;
2303 var template EgprsUlAss ul_ass;
2304
2305 /* Initialize the PCU interface abstraction */
2306 f_init_raw(testcasename());
2307
2308 var EGPRSPktChRequest req := {
2309 /* NOTE: other fields are set in the loop */
2310 two_phase := { tag := '110000'B }
2311 };
2312
2313 for (var integer i := 0; i < 6; i := i + 1) {
2314 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2315 var BIT2 priority := substr(ext_ra, 0, 2);
2316 var BIT3 rand := substr(ext_ra, 2, 3);
2317
2318 req.two_phase.priority := priority;
2319 req.two_phase.random_bits := rand;
2320
2321 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
2322 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2323 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2324 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2325
2326 f_TC_egprs_pkt_chan_req(req, imm_ass);
2327 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002328
2329 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002330}
2331
2332control {
2333 execute( TC_pcuif_suspend() );
2334 execute( TC_ta_ptcch_idle() );
2335 execute( TC_ta_rach_imm_ass() );
2336 execute( TC_ta_idle_dl_tbf_ass() );
2337 execute( TC_ta_ptcch_ul_multi_tbf() );
2338 execute( TC_cs_lqual_ul_tbf() );
2339 execute( TC_cs_initial_ul() );
2340 execute( TC_cs_max_ul() );
2341 execute( TC_t3169() );
2342 execute( TC_t3193() );
Pau Espin Pedrol487d6342020-05-14 19:22:33 +02002343 execute( TC_countdown_procedure() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002344 execute( TC_mo_ping_pong() );
2345 execute( TC_mo_ping_pong_with_ul_racap() );
Pau Espin Pedrol0c0bf872020-05-14 15:50:49 +02002346 execute( TC_force_two_phase_access() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002347 execute( TC_mt_ping_pong() );
2348 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrola416cb82020-05-15 14:09:02 +02002349 execute (TC_ul_intermediate_retrans() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002350 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002351 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002352 execute( TC_paging_cs_from_bts() );
2353 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
2354 execute( TC_paging_cs_from_sgsn_sign() );
2355 execute( TC_paging_cs_from_sgsn_ptp() );
2356 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
2357 execute( TC_paging_ps_from_sgsn_sign() );
2358 execute( TC_paging_ps_from_sgsn_ptp() );
2359
2360 /* EGPRS specific test cases */
2361 execute( TC_egprs_pkt_chan_req_signalling() );
2362 execute( TC_egprs_pkt_chan_req_one_phase() );
2363 execute( TC_egprs_pkt_chan_req_two_phase() );
Pau Espin Pedrol42acafc2020-05-14 15:18:38 +02002364
2365 execute( TC_mo_ping_pong_with_ul_racap_egprs_only() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002366}
2367
2368
2369
2370
2371
2372
Harald Weltea419df22019-03-21 17:23:04 +01002373}