blob: 5b822bb6364edca96c19029ff4d684594aea9f14 [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
139 var boolean g_egprs_only := false;
140
141 /* Guard timeout */
142 timer g_T_guard := 60.0;
143};
144
145private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
146 [] g_T_guard.timeout {
147 setverdict(fail, "Timeout of T_guard");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700148 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200149 }
150}
151
152private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
153 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
154 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
155
156 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
157 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
158}
159
160private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
161 var charstring cmd;
162
163 cmd := "cs link-quality-ranges" &
164 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
165 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
166 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
167 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
168 f_vty_config2(PCUVTY, {"pcu"}, cmd);
169
170 cmd := "mcs link-quality-ranges" &
171 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
172 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
173 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
174 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
175 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
176 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
177 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
178 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
179 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
180 f_vty_config2(PCUVTY, {"pcu"}, cmd);
181}
182
183private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
184 map(self:PCUVTY, system:PCUVTY);
185 f_vty_set_prompts(PCUVTY);
186 f_vty_transceive(PCUVTY, "enable");
187
188 if (g_egprs_only) {
189 f_vty_config2(PCUVTY, {"pcu"}, "egprs only");
190 } else {
191 f_vty_config2(PCUVTY, {"pcu"}, "no egprs");
192 }
193}
194
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200195function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200196runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200197 /* Start the guard timer */
198 g_T_guard.start;
199 activate(as_Tguard_RAW());
200
201 /* Init PCU interface component */
202 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
203 connect(vc_PCUIF:MTC, self:PCUIF);
204 map(vc_PCUIF:PCU, system:PCU);
205
206 /* Create one BTS component (we may want more some day) */
207 vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
208 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
209 connect(vc_BTS:TC, self:BTS);
210
211 f_init_vty(id);
212
213 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
214 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
215
216 /* Wait until the BTS is ready (SI13 negotiated) */
217 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
218}
219
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700220private function f_shutdown(charstring file, integer line,
221 boolean final := false)
222runs on RAW_PCU_Test_CT {
223 /* Determine if the test case was aborted in the middle */
224 if (not final) {
225 log("Test case ", testcasename(), " aborted at ", file, ":", line);
226 } else {
227 /* Guard verdict to avoid 'none' */
228 setverdict(pass);
229 }
230
231 /* Properly shutdown virtual BTS and its clock generator */
232 BTS.send(ts_RAW_PCU_CMD(GENERAL_CMD_SHUTDOWN));
233 vc_BTS.done; /* wait untill it's done */
234
235 /* Shutdown the others and MTC */
236 all component.stop;
237 mtc.stop;
238}
239
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200240template AckNackDescription t_AckNackDescription_init := {
241 final_ack := '0'B,
242 starting_seq_nr := 0,
243 receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'B
244}
245
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200246private function f_rlcmac_dl_block_get_tfi(RlcmacDlBlock dl_block)
247runs on RAW_PCU_Test_CT return uint5_t {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200248 if (ischosen(dl_block.data)) {
249 return dl_block.data.mac_hdr.hdr_ext.tfi;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200250 } else if (ischosen(dl_block.data_egprs)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200251 return dl_block.data_egprs.mac_hdr.tfi;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200252 } else { /* Ctrl block */
253 if (match(dl_block, tr_RLCMAC_UL_PACKET_ASS_GPRS(?, tr_PktUlAssGprsDynamic(?)))) {
254 return dl_block.ctrl.payload.u.ul_assignment.gprs.dyn_block_alloc.ul_tfi_assignment;
255 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200256 }
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200257 setverdict(fail, "DlBlock doesn't contain a TFI:", dl_block);
258 f_shutdown(__BFILE__, __LINE__);
259 return 0; /* make compiler happy */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200260}
261
262/* TS 44.060 sec 12.3 Ack/Nack Description */
263private function f_acknackdesc_ack_block(inout AckNackDescription desc, RlcmacDlBlock dl_block, BIT1 final_ack := '0'B)
264{
265 var uint7_t bsn;
266 var integer i;
267 var integer inc;
268
269 if (ischosen(dl_block.data)) {
270 bsn := dl_block.data.mac_hdr.hdr_ext.bsn;
271 } else {
272 bsn := dl_block.data_egprs.mac_hdr.bsn1;
273 }
274
275 inc := bsn - desc.starting_seq_nr + 1;
276 /* Filling hole? */
277 if (bsn < desc.starting_seq_nr) {
278 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);
279 return;
280 }
281
282 /* SSN is increased, and so RBB values need to be moved */
283 for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {
284 desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];
285 }
286 for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {
287 desc.receive_block_bitmap[i] := int2bit(0, 1);
288 }
289 /* Now we can set current bit and update SSN */
290 desc.starting_seq_nr := bsn + 1;
291 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);
292
293 /* Finally update the final_ack bit as requested: */
294 desc.final_ack := final_ack;
295}
296
297/* This function can be used to send DATA.cnf in response to the IUT originated DATA.req.
298 * NOTE: it's the responsibility of caller to make sure that pcu_msg contains u.data_req. */
299private function f_pcuif_tx_data_cnf(in PCUIF_Message pcu_msg)
300runs on RAW_PCU_Test_CT {
301 var PCUIF_Message pcu_msg_cnf := {
302 msg_type := PCU_IF_MSG_DATA_CNF,
303 bts_nr := pcu_msg.bts_nr,
304 spare := pcu_msg.spare,
305 u := { data_cnf := pcu_msg.u.data_req }
306 };
307
308 /* PCU wants DATA.cnf containing basically everything that was in DATA.req,
309 * but PCU_IF_SAPI_PCH is a special case - paging group shall be excluded. */
310 if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
311 pcu_msg_cnf.u.data_cnf.data := substr(pcu_msg.u.data_req.data, 3,
312 pcu_msg.u.data_req.len - 3);
313 }
314
315 BTS.send(pcu_msg_cnf);
316}
317
318private function f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,
319 template PCUIF_Sapi sapi := PCU_IF_SAPI_AGCH,
320 template GsmRrMessage t_imm_ass := ?,
321 uint8_t bts_nr := 0)
322runs on RAW_PCU_Test_CT return boolean {
323 var PCUIF_Message pcu_msg;
324 var octetstring data;
325 timer T;
326
327 T.start(2.0);
328 alt {
329 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
330 sapi := sapi, data := ?)) -> value pcu_msg {
331 /* On PCH the payload is prefixed with paging group (3 octets): skip it.
332 * TODO: add an additional template parameter, so we can match it. */
333 if (pcu_msg.u.data_req.sapi == PCU_IF_SAPI_PCH) {
334 data := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
335 } else {
336 data := pcu_msg.u.data_req.data;
337 }
338
339 rr_imm_ass := dec_GsmRrMessage(data);
340 if (not match(rr_imm_ass, t_imm_ass)) {
341 /* Not for us? Wait for more. */
342 repeat;
343 }
344
345 log("Rx Immediate Assignment: ", rr_imm_ass);
346 setverdict(pass);
347 return true;
348 }
349 [] BTS.receive { repeat; }
350 [] T.timeout {
351 setverdict(fail, "Timeout waiting for Immediate Assignment");
352 }
353 }
354
355 return false;
356}
357
Vadim Yanitskiyf74ae992020-05-06 16:05:51 +0700358/* One phase packet access (see 3GPP TS 44.018, table 9.1.8.1) */
359private const BIT8 chan_req_def := '01111000'B;
360
Vadim Yanitskiy85cb9912020-05-06 16:29:43 +0700361/* Establish an Uplink TBF by sending RACH.ind towards the PCU */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200362private function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,
Vadim Yanitskiyf74ae992020-05-06 16:05:51 +0700363 uint16_t ra := bit2int(chan_req_def),
364 uint8_t is_11bit := 0,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200365 PCUIF_BurstType burst_type := BURST_TYPE_0,
366 TimingAdvance ta := 0)
367runs on RAW_PCU_Test_CT return boolean {
368 var uint32_t fn;
369
370 /* FIXME: ask the BTS component to give us the current TDMA fn */
371 fn := 1337 + ta;
372
373 /* Send RACH.ind */
374 log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);
375 BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
376 ra := ra, is_11bit := is_11bit,
377 burst_type := burst_type,
378 fn := fn, arfcn := 871,
379 qta := ta * 4));
380
381 /* 3GPP TS 44.018, table 9.1.8.1, note 2b: Request Reference shall be set to 127
382 * when Immediate Assignment is triggered by EGPRS Packet Channel Request. Here
383 * we assume that 11 bit RA always contains EGPRS Packet Channel Request. */
384 if (is_11bit != 0) { ra := 127; }
385
386 /* Expect Immediate (TBF) Assignment on TS0/AGCH */
387 return f_pcuif_rx_imm_ass(rr_imm_ass, PCU_IF_SAPI_AGCH,
Vadim Yanitskiy85cb9912020-05-06 16:29:43 +0700388 tr_IMM_TBF_ASS(false, ra, fn),
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200389 bts_nr := bts_nr);
390}
391
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200392private 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 +0700393runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200394
395 /* Make sure we received an UL TBF Assignment */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200396 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 +0200397 ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
398 log("Rx Uplink TBF assignment: ", ul_tbf_ass);
399 setverdict(pass);
400 } else {
401 setverdict(fail, "Failed to match UL TBF Assignment");
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700402 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200403 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200404}
405
Vadim Yanitskiy5b649cc2020-05-06 16:35:38 +0700406private 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 +0700407runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200408
409 /* Make sure we received a DL TBF Assignment */
410 if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {
411 dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;
412 log("Rx Downlink TBF assignment: ", dl_tbf_ass);
413 setverdict(pass);
414 } else {
415 setverdict(fail, "Failed to match DL TBF Assignment");
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +0700416 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200417 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200418}
419
420/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol2456dad2020-04-30 20:22:38 +0200421function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200422runs on RAW_PCU_Test_CT {
423 var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
424 BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
425 sapi := PCU_IF_SAPI_PDTCH, data := data,
426 fn := fn, arfcn := 871, lqual_cb := lqual_cb));
427 if (fn != 0) {
428 ev_param := {tdma_fn := fn };
429 }
430 BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));
431}
432
433/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
434private function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
435runs on RAW_PCU_Test_CT {
436 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
437 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
438 arfcn := 871, block_nr := 0));
439 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
440 sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
441}
442
443/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi. */
444private function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)
445runs on RAW_PCU_Test_CT {
446 var PCUIF_Message pcu_msg;
447 var octetstring macblock;
448 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
449 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
450 /* First 3 bytes contain paging group: */
451 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
452 rr_imm_ass := dec_GsmRrMessage(macblock);
453 if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {
454 setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700455 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200456 }
457 f_pcuif_tx_data_cnf(pcu_msg);
458}
459
460/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi. */
461private function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
462 template integer pag_group := ?)
463runs on RAW_PCU_Test_CT return GsmRrMessage {
464 var GsmRrMessage rr_pag_req1;
465 var PCUIF_Message pcu_msg;
466 var octetstring imsi_suff_octstr;
467 var integer pag_group_rx;
468 var octetstring macblock;
469
470 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
471 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
472
473 /* First 3 bytes contain IMSI suffix to calculate paging group: */
474 imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);
475 pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +
476 str2int(oct2char(imsi_suff_octstr[1])) * 10 +
477 str2int(oct2char(imsi_suff_octstr[2]));
478
479 /* Make sure we've got RR Paging Request Type 1 for a given MI */
480 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
481 rr_pag_req1 := dec_GsmRrMessage(macblock);
482 if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {
483 setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700484 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200485 }
486
487 /* Make sure that received paging froup matches the expected one */
488 if (not match(pag_group_rx, pag_group)) {
489 setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700490 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200491 }
492
493 f_pcuif_tx_data_cnf(pcu_msg);
494 return rr_pag_req1;
495}
496
497private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)
498runs on RAW_PCU_Test_CT {
499 var octetstring data;
500 /* Encode the payload of DATA.ind */
501 data := enc_RlcmacUlBlock(valueof(ul_data));
502 data := f_pad_oct(data, 23, '00'O); /* CS-1 */
503
504 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
505 f_pcuif_tx_data_ind(data, lqual_cb, fn);
506}
507
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200508private function f_tx_rlcmac_ul_n_blocks(uint5_t tfi, integer num_blocks := 1, template (omit) GprsTlli tlli := omit)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200509runs on RAW_PCU_Test_CT {
510 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200511 tfi := tfi,
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200512 cv := num_blocks - 1, /* num UL blocks to be sent (to be overridden in loop) */
513 bsn := 0, /* TODO: what should be here? */
514 blocks := { /* To be generated in loop */ });
515
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +0200516 if (not istemplatekind(tlli, "omit")) {
517 ul_data.data.mac_hdr.tlli_ind := true;
518 ul_data.data.tlli := tlli;
519 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200520
521 for (var integer i := 0; i < num_blocks; i := i + 1) {
522 /* Prepare a new UL block (CV, random payload) */
523 ul_data.data.mac_hdr.countdown := (num_blocks - i - 1);
524 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
525 f_tx_rlcmac_ul_block(ul_data);
526 }
527}
528
529private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
530runs on RAW_PCU_Test_CT {
531 var PCUIF_Message pcu_msg;
532 f_pcuif_rx_data_req(pcu_msg);
533 dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
534 dl_fn := pcu_msg.u.data_req.fn;
535
536 var integer len := lengthof(pcu_msg.u.data_req.data);
537 var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)
538 if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {
539 setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700540 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200541 }
542}
543
544private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
545runs on RAW_PCU_Test_CT {
546 var uint32_t dl_fn;
547
548 f_rx_rlcmac_dl_block(dl_block, dl_fn);
549 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
550 setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700551 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200552 }
553
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700554 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200555}
556
557private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
558runs on RAW_PCU_Test_CT {
559 var uint32_t dl_fn;
560
561 f_rx_rlcmac_dl_block(dl_block, dl_fn);
562 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
563 setverdict(fail, "Failed to match Packet DUMMY DL");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700564 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200565 }
566}
567
568private function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
569runs on RAW_PCU_Test_CT {
570 var uint32_t dl_fn;
571
572 f_rx_rlcmac_dl_block(dl_block, dl_fn);
573 if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
574 setverdict(fail, "Failed to match Packet Downlink Assignment");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700575 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200576 }
577
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700578 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200579}
580
581private function f_rx_rlcmac_dl_block_exp_pkt_ul_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
582runs on RAW_PCU_Test_CT {
583 var uint32_t dl_fn;
584
585 f_rx_rlcmac_dl_block(dl_block, dl_fn);
586 if (not match(dl_block, tr_RLCMAC_UL_PACKET_ASS())) {
587 setverdict(fail, "Failed to match Packet Uplink Assignment");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700588 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200589 }
590
Vadim Yanitskiy2742bcd2020-05-10 12:45:18 +0700591 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200592}
593
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +0200594private function f_rx_rlcmac_dl_block_exp_pkt_dl_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
595runs on RAW_PCU_Test_CT {
596 var uint32_t dl_fn;
597
598 f_rx_rlcmac_dl_block(dl_block, dl_fn);
599 if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
600 setverdict(fail, "Failed to match Packet Downlink Assignment");
601 f_shutdown(__BFILE__, __LINE__);
602 }
603
604 poll_fn := f_rrbp_ack_fn(dl_fn, dl_block.ctrl.mac_hdr.rrbp);
605}
606
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200607
608private function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
609runs on RAW_PCU_Test_CT {
610 var uint32_t dl_fn;
611
612 f_rx_rlcmac_dl_block(dl_block, dl_fn);
613 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
614 setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700615 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200616 }
617}
618
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700619/* This function does what could probably be done with templates */
620private function f_rlcmac_dl_block_verify_data_gprs(in RlcmacDlDataBlock data_block,
621 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700622 template (present) uint7_t exp_bsn := ?,
623 template (present) CodingScheme exp_cs := ?)
624runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700625 if (not match(data_block.mac_hdr.hdr_ext.bsn, exp_bsn)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200626 setverdict(fail, "DL block BSN doesn't match: ",
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700627 data_block.mac_hdr.hdr_ext.bsn, " vs exp ", exp_bsn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200628 }
629
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700630 if (lengthof(data_block.blocks) < 1) {
631 setverdict(fail, "DL block has no LLC payload: ", data_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700632 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200633 }
634
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700635 if (not match(data_block.blocks[0].payload, data)) {
636 setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
637 data_block.blocks[0].payload, " vs ", data);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700638 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200639 }
640
641 /* Check next data blocks contain dummy frames */
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700642 if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
643 setverdict(fail, "Second data payload is not a dummy frame: ",
644 data_block.blocks[1].payload);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700645 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200646 }
647
648 /* TODO: check exp_cs */
649}
650
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700651/* This function does what could probably be done with templates */
652private function f_rlcmac_dl_block_verify_data_egprs(in RlcmacDlEgprsDataBlock data_block,
653 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700654 template (present) uint14_t exp_bsn := ?,
655 template (present) CodingScheme exp_cs := ?)
656runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700657 if (not match(data_block.mac_hdr.bsn1, exp_bsn)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200658 setverdict(fail, "DL block BSN doesn't match: ",
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700659 data_block.mac_hdr.bsn1, " vs exp ", exp_bsn);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200660 }
661
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700662 if (lengthof(data_block.blocks) < 1) {
663 setverdict(fail, "DL block has no LLC payload: ", data_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700664 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200665 }
666
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700667 if (not match(data_block.blocks[0].payload, data)) {
668 setverdict(fail, "Failed to match content of LLC payload in DL Block: ",
669 data_block.blocks[0].payload, " vs ", data);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700670 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200671 }
672
673 /* Check next data blocks contain dummy frames */
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700674 if (lengthof(data_block.blocks) > 1 and substr(data_block.blocks[1].payload, 0, 3) != '43C001'O) {
675 setverdict(fail, "Second data payload is not a dummy frame: ",
676 data_block.blocks[1].payload);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700677 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200678 }
679
680 /* 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.
681 See wireshark's egprs_Header_type1_coding_puncturing_scheme_to_mcs. */
682}
683
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700684/* High level (task specific) helper for receiving and matching GPRS/EGPRS data blocks */
685private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t dl_fn,
686 template (present) octetstring data := ?,
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700687 template (present) uint7_t exp_bsn := ?,
688 template (present) CodingScheme exp_cs := ?)
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200689runs on RAW_PCU_Test_CT {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700690 /* FIXME: ideally we should use an alt statement with timeout here, rather than
691 * having +100500 layers of abstraction. This would facilitate developing the
692 * multi-TBF/-TRX/-BTS tests, where you cannot expect that the first received
693 * block is exactly what you need. */
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200694 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700695
696 /* Make sure it's either GPRS or EGPRS data block */
697 if (not match(dl_block, tr_RLCMAC_DATA)) {
698 setverdict(fail, "Failed to match DL DATA: ", dl_block, " vs ", tr_RLCMAC_DATA);
699 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200700 }
701
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700702 if (ischosen(dl_block.data_egprs)) {
703 f_rlcmac_dl_block_verify_data_egprs(dl_block.data_egprs, data, exp_bsn, exp_cs);
704 } else if (ischosen(dl_block.data)) {
705 f_rlcmac_dl_block_verify_data_gprs(dl_block.data, data, exp_bsn, exp_cs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200706 } else {
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700707 /* Should not happen, but the caller may theoretically give us a template for CTRL */
708 setverdict(fail, "DL block is neither GPRS nor EGPRS data block: ", dl_block);
709 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200710 }
711}
712
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700713private function f_dl_block_ack_fn(in RlcmacDlBlock dl_block, uint32_t dl_fn)
714runs on RAW_PCU_Test_CT return uint32_t {
715 var boolean rrbp_valid;
716 var MacRrbp rrbp;
717
718 /* The argument must be either a GPRS or EGPRS data block */
719 if (ischosen(dl_block.data_egprs)) {
720 rrbp_valid := true; /* always valid */
721 rrbp := dl_block.data_egprs.mac_hdr.rrbp;
722 } else if (ischosen(dl_block.data)) {
723 rrbp_valid := dl_block.data.mac_hdr.mac_hdr.rrbp_valid;
724 rrbp := dl_block.data.mac_hdr.mac_hdr.rrbp;
725 } else {
Pau Espin Pedrol1832cd82020-05-13 16:42:24 +0200726 rrbp_valid := dl_block.ctrl.mac_hdr.rrbp_valid;
727 rrbp := dl_block.ctrl.mac_hdr.rrbp;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +0700728 }
729
730 /* Make sure that the given block really needs to be ACKnowledged */
731 if (not rrbp_valid) {
732 setverdict(fail, "DL block shall not be ACKnowledged, field RRBP is not valid");
733 f_shutdown(__BFILE__, __LINE__);
734 }
735
736 return f_rrbp_ack_fn(dl_fn, rrbp);
737}
738
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200739testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
740 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
741 var GprsTlli tlli := 'FFFFFFFF'O;
742 timer T;
743
744 /* Initialize NS/BSSGP side */
745 f_init_bssgp();
746
747 /* Initialize the PCU interface abstraction */
748 f_init_raw(testcasename());
749
750 /* Establish BSSGP connection to the PCU */
751 f_bssgp_establish();
752
753 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
754
755 T.start(2.0);
756 alt {
757 [] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
758 setverdict(pass);
759 }
760 [] T.timeout {
761 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
762 }
763 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700764
765 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200766}
767
768/* Test of correct Timing Advance at the time of TBF establishment
769 * (derived from timing offset of the Access Burst). */
770testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
771 var GsmRrMessage rr_msg;
772 var boolean ok;
773
774 /* Initialize the PCU interface abstraction */
775 f_init_raw(testcasename());
776
777 /* We cannot send too many TBF requests in a short time because
778 * at some point the PCU will fail to allocate a new TBF. */
779 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
780 /* Establish an Uplink TBF (send RACH.ind with current TA) */
781 ok := f_establish_tbf(rr_msg, bts_nr := 0, ta := ta);
782 if (not ok) {
783 setverdict(fail, "Failed to establish an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700784 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200785 }
786
787 /* Make sure Timing Advance IE matches out expectations */
Vadim Yanitskiy8685b382020-05-06 16:53:26 +0700788 if (rr_msg.payload.imm_ass.timing_advance != ta) {
789 setverdict(fail, "Timing Advance mismatch: ",
790 rr_msg.payload.imm_ass.timing_advance,
791 " vs expected ", ta);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700792 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200793 }
794 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700795
796 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200797}
798
799/* Verify Timing Advance value(s) indicated during the packet Downlink assignment
800 * procedure as per 3GPP TS 44.018, section 3.5.3. There seems to be a bug in the
801 * IUT that causes it to send an unreasonable Timing Advance value > 0 despite
802 * no active TBF exists at the moment of establishment (idle mode). */
803testcase TC_ta_idle_dl_tbf_ass() runs on RAW_PCU_Test_CT {
804 var OCT4 tlli := f_rnd_octstring(4);
805 var GsmRrMessage rr_imm_ass;
806
807 /* Initialize NS/BSSGP side */
808 f_init_bssgp();
809
810 /* Initialize the PCU interface abstraction */
811 f_init_raw(testcasename());
812
813 /* Establish BSSGP connection to the PCU */
814 f_bssgp_establish();
815 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
816
817 /* SGSN sends some DL data, PCU will initiate Packet Downlink
818 * Assignment on CCCH (PCH). We don't care about the payload. */
819 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, f_rnd_octstring(10)));
820 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass); // TODO: match by TLLI!
821
822 /* Make sure that Timing Advance is 0 (the actual value is not known yet).
823 * As per 3GPP S 44.018, section 3.5.3.1.2, the network *shall* initiate
824 * the procedures defined in 3GPP TS 44.060 or use the polling mechanism. */
825 if (not match(rr_imm_ass, tr_IMM_TBF_ASS(ta := 0))) {
826 setverdict(fail, "Timing Advance value doesn't match");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200827 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700828
829 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200830}
831
832/* Verify that the PCU generates valid PTCCH/D messages
833 * while neither Uplink nor Downlink TBF is established. */
834testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
835 var PTCCHDownlinkMsg ptcch_msg;
836 var PCUIF_Message pcu_msg;
837 timer T;
838
839 /* Initialize the PCU interface abstraction */
840 f_init_raw(testcasename());
841
842 /* Sent an RTS.req for PTCCH/D */
843 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
844 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
845 arfcn := 871, block_nr := 0));
846 T.start(5.0);
847 alt {
848 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
849 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
850 log("Rx DATA.req message: ", pcu_msg);
851 setverdict(pass);
852 }
853 [] BTS.receive(PCUIF_Message:?) { repeat; }
854 [] T.timeout {
855 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700856 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200857 }
858 }
859
860 ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
861 log("Decoded PTCCH/D message: ", ptcch_msg);
862
863 /* Make sure the message is encoded correctly
864 * TODO: do we expect all TA values to be equal '1111111'B? */
865 if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
866 setverdict(fail, "Malformed PTCCH/D message");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200867 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700868
869 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200870}
871
872/* Test of correct Timing Advance during an active Uplink TBF.
873 *
874 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
875 * are not continuous and there can be long time gaps between them. This happens
876 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
877 * significantly change between such rare Uplink transmissions, so GPRS introduces
878 * additional mechanisms to control Timing Advance, and thus reduce interference
879 * between neighboring TDMA time-slots.
880 *
881 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
882 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
883 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
884 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
885 * among with the initial Timing Advance value. And here PTCCH comes to play.
886 *
887 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
888 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
889 * continuously. To ensure continuous measurements of the signal propagation
890 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
891 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
892 *
893 * The purpose of this test case is to verify the assignment of Timing Advance
894 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
895 * first establishes several Uplink TBFs, but does not transmit any Uplink
896 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
897 * indications to the PCU, checking the correctness of two received PTCCH/D
898 * messages (period of PTCCH/D is two multi-frames).
899 */
900
901/* List of ToA values for Access Bursts to be sent on PTCCH/U,
902 * each ToA (Timing of Arrival) value is in units of 1/4 of
903 * a symbol (i.e. 1 symbol is 4 QTA units). */
904type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
905const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
906 0, 0, 0, 0,
907 0, 0, 0, 0,
908 0, 0, 0, 0,
909 0, 0, 0, 0
910};
911
912private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
913 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
914runs on RAW_PCU_Test_CT {
915 var RAW_PCU_Event event;
916 var integer ss;
917
918 /* Send Access Bursts on PTCCH/U for every TA Index */
919 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
920 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700921 if (ss < 0) { /* Shall not happen */
922 f_shutdown(__BFILE__, __LINE__);
923 }
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200924
925 log("Sending an Access Burst on PTCCH/U",
926 ", sub-slot=", ss, " (TAI)",
927 ", fn=", event.data.tdma_fn,
928 ", ToA=", toa_map[ss], " (QTA)");
929 /* TODO: do we care about RA and burst format? */
930 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
931 ra := oct2int('3A'O),
932 is_11bit := 0,
933 burst_type := BURST_TYPE_0,
934 fn := event.data.tdma_fn,
935 arfcn := 871,
936 qta := toa_map[ss],
937 sapi := PCU_IF_SAPI_PTCCH));
938 repeat;
939 }
940}
941
942private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
943 template PTCCHDownlinkMsg t_ta_msg)
944runs on RAW_PCU_Test_CT {
945 var PTCCHDownlinkMsg ta_msg;
946 var PCUIF_Message pcu_msg;
947 timer T;
948
949 /* First, send an RTS.req for the upcoming PTCCH/D block */
950 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
951 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
952 arfcn := 871, block_nr := 0));
953 T.start(2.0);
954 alt {
955 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
956 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
957 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
958 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
959 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
960 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
961 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
962 log("Rx PTCCH/D message: ", ta_msg);
963
964 /* Make sure Timing Advance values match our expectations */
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700965 if (not match(ta_msg, t_ta_msg)) {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200966 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
967 }
968 }
969 [] BTS.receive { repeat; }
970 [] T.timeout {
971 setverdict(fail, "Timeout waiting for a PTCCH/D block");
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200972 }
973 }
974}
975
976testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
977 var template PacketUlAssign t_ul_tbf_ass;
978 var PacketUlAssign ul_tbf_ass[7];
979 var GsmRrMessage rr_msg[7];
980 var boolean ok;
981
982 /* Initialize the PCU interface abstraction */
983 f_init_raw(testcasename());
984
985 /* Enable forwarding of PTCCH/U TDMA events to us */
986 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
987
988 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
989 for (var integer i := 0; i < 7; i := i + 1) {
990 ok := f_establish_tbf(rr_msg[i], ta := 0);
991 if (not ok) {
992 setverdict(fail, "Failed to establish an Uplink TBF #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +0700993 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +0200994 }
995
996 /* Make sure we received an UL TBF Assignment */
997 if (match(rr_msg[i], tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
998 ul_tbf_ass[i] := rr_msg[i].payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
999 log("Rx Uplink TBF assignment for #", i, ": ", ul_tbf_ass[i]);
1000 } else {
1001 setverdict(fail, "Failed to match UL TBF Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001002 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001003 }
1004
1005 /* We expect incremental TFI/USF assignment (dynamic allocation) */
1006 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
1007 if (not match(ul_tbf_ass[i], t_ul_tbf_ass)) {
1008 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001009 break;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001010 }
1011
1012 /* We also expect Timing Advance Index to be a part of the assignment */
1013 if (ul_tbf_ass[i].dynamic.ta_index != i) {
1014 setverdict(fail, "Failed to match Timing Advance Index for #", i);
1015 /* Keep going, the current OsmoPCU does not assign TA Index */
1016 }
1017 }
1018
1019 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
1020 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
1021 for (var integer i := 0; i < 7; i := i + 1) {
1022 /* ToA in units of 1/4 of a symbol */
1023 toa_map[i] := (i + 1) * 7 * 4;
1024 }
1025
1026 /* Now we have all 7 TBFs established in one-phase access mode,
1027 * however we will not be sending any data on them. Instead, we
1028 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
1029 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
1030 *
1031 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
1032 * time-slots, so at the moment of scheduling a PTCCH/D block
1033 * the PCU has odd number of PTCCH/U Access Bursts received. */
1034 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
1035 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
1036 /* Other values are not known (yet) */
1037 tai3_ta := ?));
1038 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
1039 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
1040 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
1041 /* Other values are out of our interest */
1042 tai6_ta := ?));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001043
1044 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001045}
1046
1047/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
1048 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
1049 *
1050 * NOTE: the ranges are intentionally overlapping because OsmoPCU
1051 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
1052private template integer CS1_lqual_dB_range := (-infinity .. 6);
1053private template integer CS2_lqual_dB_range := (5 .. 8);
1054private template integer CS3_lqual_dB_range := (7 .. 13);
1055private template integer CS4_lqual_dB_range := (12 .. infinity);
1056
1057testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
1058 var GsmRrMessage rr_imm_ass;
1059 var PacketUlAssign ul_tbf_ass;
1060 var RlcmacDlBlock dl_block;
1061 var PCUIF_Message pcu_msg;
1062 var octetstring data;
1063 var boolean ok;
1064 var uint32_t unused_fn;
1065
1066 /* Initialize the PCU interface abstraction */
1067 f_init_raw(testcasename());
1068
1069 f_pcuvty_set_allowed_cs_mcs();
1070 f_pcuvty_set_link_quality_ranges();
1071
1072 /* Establish an Uplink TBF */
1073 ok := f_establish_tbf(rr_imm_ass);
1074 if (not ok) {
1075 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001076 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001077 }
1078
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001079 /* Make sure we've got an Uplink TBF assignment */
1080 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001081
1082 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1083 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1084 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
1085 bsn := 0, /* TODO: what should be here? */
1086 blocks := { /* To be generated in loop */ });
1087
1088 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1089 ul_data.data.tlli := '00000001'O;
1090
1091 /* The actual / old link quality values. We need to keep track of the old
1092 * (basically previous) link quality value, because OsmoPCU actually
1093 * changes the coding scheme if not only the actual, but also the old
1094 * value leaves the current link quality range (window). */
1095 var integer lqual := 0;
1096 var integer lqual_old;
1097
1098 /* 16 UL blocks (0 .. 15 dB, step = 1 dB) */
1099 for (var integer i := 0; i < 16; i := i + 1) {
1100 /* Prepare a new UL block (CV, random payload) */
1101 ul_data.data.mac_hdr.countdown := (15 - i);
1102 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1103
1104 /* Update the old / actual link quality */
1105 lqual_old := lqual;
1106 lqual := i;
1107
1108 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1109 log("Sending DATA.ind with link quality (dB): ", lqual);
1110 f_tx_rlcmac_ul_block(ul_data, lqual * 10);
1111
1112 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1113 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1114
1115 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
1116 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
1117
1118 /* Match the received Channel Coding Command. Since we are increasing
1119 * the link quality value on each iteration and not decreasing, there
1120 * is no need to check the both old and current link quality values. */
1121 var template ChCodingCommand ch_coding;
1122 select (lqual_old) {
1123 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
1124 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
1125 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
1126 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
1127 }
1128
1129 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
1130 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001131 }
1132 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001133
1134 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001135}
1136
1137/* Test the max UL CS set by VTY works fine */
1138testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
1139 var GsmRrMessage rr_imm_ass;
1140 var PacketUlAssign ul_tbf_ass;
1141 var RlcmacDlBlock dl_block;
1142 var boolean ok;
1143 var integer lqual_cb;
1144 var ChCodingCommand last_ch_coding;
1145 var uint32_t unused_fn;
1146
1147 /* Initialize the PCU interface abstraction */
1148 f_init_raw(testcasename());
1149
1150 /* Set initial UL CS to 3 */
1151 g_cs_initial_ul := 3;
1152 f_pcuvty_set_allowed_cs_mcs();
1153 f_pcuvty_set_link_quality_ranges();
1154
1155 /* Take lqual (dB->cB) so that we stay in that CS */
1156 lqual_cb := g_cs_lqual_ranges[2].low * 10;
1157
1158 /* Establish an Uplink TBF */
1159 ok := f_establish_tbf(rr_imm_ass);
1160 if (not ok) {
1161 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001162 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001163 }
1164
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001165 /* Make sure we've got an Uplink TBF assignment */
1166 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001167
1168 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1169 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1170 cv := 3, /* 8 UL blocks to be sent (to be overridden in loop) */
1171 bsn := 0, /* TODO: what should be here? */
1172 blocks := { /* To be generated in loop */ });
1173
1174 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1175 ul_data.data.tlli := '00000001'O;
1176
1177 /* 3 UL blocks, check we are in same initial CS: */
1178 for (var integer i := 0; i < 3; i := i + 1) {
1179 /* Prepare a new UL block (CV, random payload) */
1180 ul_data.data.mac_hdr.countdown := (7 - i);
1181 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1182
1183 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1184 f_tx_rlcmac_ul_block(ul_data, lqual_cb);
1185
1186 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1187 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1188 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1189 }
1190
1191 if (last_ch_coding != CH_CODING_CS3) {
1192 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001193 }
1194
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001195 /* Remaining UL blocks are used to make sure regardless of initial
1196 /* lqual, we can go lower at any time */
1197
1198 /* 5 UL blocks, check we are in same initial CS: */
1199 for (var integer i := 3; i < 8; i := i + 1) {
1200 /* Prepare a new UL block (CV, random payload) */
1201 ul_data.data.mac_hdr.countdown := (7 - i);
1202 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1203
1204 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1205 f_tx_rlcmac_ul_block(ul_data, 0); /* 0 dB, make sure we downgrade CS */
1206
1207 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1208 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1209
1210 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1211 }
1212
1213 if (last_ch_coding != CH_CODING_CS1) {
1214 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001215 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001216
1217 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001218}
1219
1220/* Test the max UL CS set by VTY works fine */
1221testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
1222 var GsmRrMessage rr_imm_ass;
1223 var PacketUlAssign ul_tbf_ass;
1224 var RlcmacDlBlock dl_block;
1225 var boolean ok;
1226 var ChCodingCommand last_ch_coding;
1227 var uint32_t unused_fn;
1228
1229 /* Initialize the PCU interface abstraction */
1230 f_init_raw(testcasename());
1231
1232 /* Set maximum allowed UL CS to 3 */
1233 g_cs_max_ul := 3;
1234 f_pcuvty_set_allowed_cs_mcs();
1235 f_pcuvty_set_link_quality_ranges();
1236
1237 /* Establish an Uplink TBF */
1238 ok := f_establish_tbf(rr_imm_ass);
1239 if (not ok) {
1240 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001241 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001242 }
1243
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001244 /* Make sure we've got an Uplink TBF assignment */
1245 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001246
1247 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1248 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1249 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
1250 bsn := 0, /* TODO: what should be here? */
1251 blocks := { /* To be generated in loop */ });
1252
1253 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1254 ul_data.data.tlli := '00000001'O;
1255
1256 /* 16 UL blocks */
1257 for (var integer i := 0; i < 16; i := i + 1) {
1258 /* Prepare a new UL block (CV, random payload) */
1259 ul_data.data.mac_hdr.countdown := (15 - i);
1260 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1261
1262 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1263 f_tx_rlcmac_ul_block(ul_data, 40*10); /* 40 dB */
1264
1265 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
1266 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1267
1268 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1269 }
1270
1271 if (last_ch_coding != CH_CODING_CS3) {
1272 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001273 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001274
1275 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001276}
1277
1278/* Verify PCU drops TBF after some time of inactivity. */
1279testcase TC_t3169() runs on RAW_PCU_Test_CT {
1280 var PCUIF_info_ind info_ind;
1281 var GsmRrMessage rr_imm_ass;
1282 var PacketUlAssign ul_tbf_ass;
1283 var RlcmacDlBlock dl_block;
1284 var PCUIF_Message pcu_msg;
1285 var octetstring data;
1286 var boolean ok;
1287 var uint32_t unused_fn;
1288 var OCT4 tlli := '00000001'O;
1289
1290 /* Initialize NS/BSSGP side */
1291 f_init_bssgp();
1292
1293 info_ind := valueof(ts_PCUIF_INFO_default);
1294 /* Set timer to 1 sec (default 5) to speedup test: */
1295 info_ind.t3169 := 1;
1296
1297 /* Initialize the PCU interface abstraction */
1298 f_init_raw(testcasename(), info_ind);
1299
1300 /* Establish BSSGP connection to the PCU */
1301 f_bssgp_establish();
1302 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1303
1304 /* Establish an Uplink TBF */
1305 ok := f_establish_tbf(rr_imm_ass);
1306 if (not ok) {
1307 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001308 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001309 }
1310
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001311 /* Make sure we've got an Uplink TBF assignment */
1312 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001313
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001314 /* Send one UL block (with TLLI since we are in One-Phase Access
1315 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001316 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001317 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
1318 /* UL block should be received in SGSN */
1319 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1320
1321 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
1322 f_sleep(int2float(info_ind.t3169) + 1.0);
1323
1324 /* Send an UL block once again, the TBF should be gone by now so no ACK */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001325 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, 1);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001326 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001327
1328 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001329}
1330
1331/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1332 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1333 * T3193) after DL TBF release */
1334testcase TC_t3193() runs on RAW_PCU_Test_CT {
1335 var GsmRrMessage rr_imm_ass;
1336 var PacketDlAssign dl_tbf_ass;
1337 var RlcmacDlBlock dl_block;
1338 var octetstring data := f_rnd_octstring(10);
1339 var boolean ok;
1340 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001341 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001342 var OCT4 tlli := '00000001'O;
1343 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1344
1345 /* Initialize NS/BSSGP side */
1346 f_init_bssgp();
1347
1348 /* Initialize the PCU interface abstraction */
1349 f_init_raw(testcasename());
1350
1351 /* Establish BSSGP connection to the PCU */
1352 f_bssgp_establish();
1353 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1354
1355 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1356 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1357 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001358
1359 /* Make sure we've got a Downlink TBF assignment */
1360 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1361
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001362 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1363 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001364 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001365
1366 /* ACK the DL block */
1367 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001368 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1369 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001370 /* we are done with the DL-TBF here so far, let's clean up our local state: */
1371 ack_nack_desc := valueof(t_AckNackDescription_init)
1372
1373 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
1374 (T3192 in MS) was started and until it fires the MS will be abailable
1375 on PDCH in case new data arrives from SGSN. Let's verify it: */
1376 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1377 f_rx_rlcmac_dl_block_exp_pkt_ass(dl_block, sched_fn);
1378 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1379
1380 /* 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 +07001381 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001382 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001383 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1384 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001385
1386 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001387}
1388
1389/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1390 * answered, so TBFs for uplink and later for downlink are created.
1391 */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001392private 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 +02001393 var GsmRrMessage rr_imm_ass;
1394 var PacketUlAssign ul_tbf_ass;
1395 var PacketDlAssign dl_tbf_ass;
1396 var RlcmacDlBlock dl_block;
1397 var PCUIF_Message pcu_msg;
1398 var octetstring data := f_rnd_octstring(10);
1399 var boolean ok;
1400 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001401 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001402 var OCT4 tlli := '00000001'O;
1403 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1404
1405 /* Initialize NS/BSSGP side */
1406 f_init_bssgp();
1407
1408 /* Initialize the PCU interface abstraction */
1409 f_init_raw(testcasename());
1410
1411 /* Establish BSSGP connection to the PCU */
1412 f_bssgp_establish();
1413 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1414
1415 /* Establish an Uplink TBF */
1416 ok := f_establish_tbf(rr_imm_ass);
1417 if (not ok) {
1418 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001419 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001420 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001421
1422 /* Make sure we've got an Uplink TBF assignment */
1423 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001424
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001425 /* Send one UL block (with TLLI since we are in One-Phase Access
1426 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001427 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001428 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1429 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1430 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1431
1432 /* UL block should be received in SGSN */
1433 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1434
1435 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
1436 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1437 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1438
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001439 /* Make sure we've got a Downlink TBF assignment */
1440 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001441
1442 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1443 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001444 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001445
1446 /* ACK the DL block */
1447 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001448 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1449 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001450
1451 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001452}
1453
1454/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1455 * answered, so TBFs for uplink and later for downlink are created.
1456 */
1457testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
1458 var CodingScheme exp_cs_mcs := CS_1;
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001459 f_TC_mo_ping_pong_1phase_access(exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001460}
1461
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001462/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1463 * answered, so TBFs for uplink and later for downlink are created.
1464 */
1465private function f_TC_mo_ping_pong_2phase_access(template (value) MSRadioAccessCapabilityV ms_racap, template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
1466 var GsmRrMessage rr_imm_ass;
1467 var PacketUlAssign ul_tbf_ass;
1468 var PacketDlAssign dl_tbf_ass;
1469 var RlcmacDlBlock dl_block;
1470 var PCUIF_Message pcu_msg;
1471 var octetstring data := f_rnd_octstring(10);
1472 var boolean ok;
1473 var uint32_t sched_fn;
1474 var uint32_t dl_fn;
1475 var OCT4 tlli := '00000001'O;
1476 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1477 /* 0111 0xxx: Single block packet access; one block period on a PDCH is needed for two phase packet access or other RR signalling purpose. */
1478 var uint16_t ra := oct2int('70'O);
1479
1480 /* Initialize NS/BSSGP side */
1481 f_init_bssgp();
1482
1483 /* Initialize the PCU interface abstraction */
1484 f_init_raw(testcasename());
1485
1486 /* Establish BSSGP connection to the PCU */
1487 f_bssgp_establish();
1488 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1489
1490 /* Establish an Uplink TBF */
1491 ok := f_establish_tbf(rr_imm_ass, ra := ra);
1492 if (not ok) {
1493 setverdict(fail, "Failed to establish TBF");
1494 f_shutdown(__BFILE__, __LINE__);
1495 }
1496
1497 /* Make sure we've got an Uplink TBF assignment */
1498 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass, tr_PacketUlSglAssign);
1499
1500 /* Send PACKET RESOURCE REQUEST to upgrade to EGPRS
1501 * (see 3GPP TS 04.60 "7.1.3.1 Initiation of the Packet resource request procedure")
1502 */
1503 f_tx_rlcmac_ul_block(ts_RLC_UL_CTRL_ACK(valueof(ts_RlcMacUlCtrl_PKT_RES_REQ(tlli, ms_racap))), 0);
1504 f_rx_rlcmac_dl_block_exp_pkt_ul_ass(dl_block, sched_fn);
1505 if (dl_block.ctrl.payload.u.ul_assignment.identity.tlli.tlli != tlli) {
1506 setverdict(fail, "Wrong TLLI ", dl_block.ctrl.payload.u.ul_assignment.identity.tlli, " received vs exp ", tlli);
1507 f_shutdown(__BFILE__, __LINE__);
1508 }
1509
1510 /* Send one UL block (without TLLI since we are in Second-Phase Access)
1511 and make sure it is ACKED fine */
1512 f_tx_rlcmac_ul_n_blocks(f_rlcmac_dl_block_get_tfi(dl_block), 1);
1513
1514 //f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1515 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1516 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1517
1518 /* UL block should be received in SGSN */
1519 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1520
1521 /* Now SGSN sends some DL data, PCU will page on PACCH */
1522 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1523 f_rx_rlcmac_dl_block_exp_pkt_dl_ass(dl_block, sched_fn);
1524 /* DL Ass sets poll+rrbp requesting PACKET CONTROL ACK */
1525 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1526
1527 /* After acking the dl assignment, dl tbf goes into FLOW state and PCU will provide DL data when BTS asks for it */
1528 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
1529
1530 /* ACK the DL block */
1531 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
1532 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1533 0, f_dl_block_ack_fn(dl_block, dl_fn));
1534
1535 f_shutdown(__BFILE__, __LINE__, final := true);
1536}
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001537
1538testcase TC_mo_ping_pong_with_ul_racap() runs on RAW_PCU_Test_CT {
1539 var MultislotCap_GPRS mscap_gprs := {
1540 gprsmultislotclass := '00011'B,
1541 gprsextendeddynalloccap := '0'B
1542 };
1543 var MSRadioAccessCapabilityV ms_racap := { valueof(ts_RaCapRec('0001'B /* E-GSM */, mscap_gprs, omit)) };
1544 var CodingScheme exp_cs_mcs := CS_2;
1545
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001546 f_TC_mo_ping_pong_2phase_access(ms_racap, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001547}
1548
1549/* Test scenario where SGSN wants to send some data against MS and it is
1550 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1551 */
1552private 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 {
1553 var GsmRrMessage rr_imm_ass;
1554 var PacketUlAssign ul_tbf_ass;
1555 var PacketDlAssign dl_tbf_ass;
1556 var RlcmacDlBlock dl_block;
1557 var PCUIF_Message pcu_msg;
1558 var octetstring data := f_rnd_octstring(10);
1559 var boolean ok;
1560 var uint32_t sched_fn;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001561 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001562 var OCT4 tlli := '00000001'O;
1563 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1564
1565 /* Initialize NS/BSSGP side */
1566 f_init_bssgp();
1567
1568 /* Initialize the PCU interface abstraction */
1569 f_init_raw(testcasename());
1570
1571 /* Establish BSSGP connection to the PCU */
1572 f_bssgp_establish();
1573 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1574
1575 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1576 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
1577 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1578
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001579 /* Make sure we've got a Downlink TBF assignment */
1580 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001581
1582 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1583 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001584 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001585
1586 /* ACK the DL block */
1587 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001588 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1589 0, f_dl_block_ack_fn(dl_block, dl_fn));
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001590
1591 /* Now MS wants to answer the DL data, Establish an Uplink TBF */
1592 ok := f_establish_tbf(rr_imm_ass);
1593 if (not ok) {
1594 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001595 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001596 }
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001597
1598 /* Make sure we've got an Uplink TBF assignment */
1599 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001600
Pau Espin Pedrol4aac3d02020-05-13 15:13:49 +02001601 /* Send one UL block (with TLLI since we are in One-Phase Access
1602 contention resoultion) and make sure it is ACKED fine */
Pau Espin Pedrol02c972d2020-05-13 15:56:16 +02001603 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass.dynamic.tfi_assignment, 1, tlli);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001604 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1605 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1606 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1607
1608 /* UL block should be received in SGSN */
1609 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001610
1611 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001612}
1613
1614testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
1615 var CodingScheme exp_cs_mcs := CS_1;
1616 f_TC_mt_ping_pong(omit, exp_cs_mcs);
1617}
1618
1619/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1620/* information about the MS */
1621testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1622 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1623 gprsmultislotclass := '00011'B,
1624 gprsextendeddynalloccap := '0'B
1625 } ;
1626 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
1627 var CodingScheme exp_cs_mcs := CS_2;
1628 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
1629}
1630
1631/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1632 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1633 * timeout occurs (specified by sent RRBP on DL block). */
1634testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
1635 var GsmRrMessage rr_imm_ass;
1636 var PacketDlAssign dl_tbf_ass;
1637 var RlcmacDlBlock dl_block;
1638 var octetstring data := f_rnd_octstring(10);
1639 var boolean ok;
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001640 var uint32_t dl_fn;
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001641 var OCT4 tlli := '00000001'O;
1642 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1643
1644 /* Initialize NS/BSSGP side */
1645 f_init_bssgp();
1646
1647 /* Initialize the PCU interface abstraction */
1648 f_init_raw(testcasename());
1649
1650 /* Establish BSSGP connection to the PCU */
1651 f_bssgp_establish();
1652 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1653
1654 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1655 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1656 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001657
1658 /* Make sure we've got a Downlink TBF assignment */
1659 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001660
1661 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1662 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001663 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001664
1665 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1666 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1667 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
1668 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001669
1670 /* Make sure we've got a Downlink TBF assignment */
1671 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1672
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001673 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1674 f_sleep(X2002);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001675 f_rx_rlcmac_dl_block_exp_data(dl_block, dl_fn, data, 0);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001676
1677 /* ACK the DL block */
1678 f_acknackdesc_ack_block(ack_nack_desc, dl_block, '1'B);
Vadim Yanitskiyb6733a62020-05-10 14:39:00 +07001679 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(f_rlcmac_dl_block_get_tfi(dl_block), ack_nack_desc),
1680 0, f_dl_block_ack_fn(dl_block, dl_fn));
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001681
1682 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001683}
1684
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07001685/* Verify scheduling of multiple Downlink data blocks during one RRBP. */
1686testcase TC_dl_flow_more_blocks() runs on RAW_PCU_Test_CT {
1687 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1688 var octetstring data := f_rnd_octstring(16);
1689 var OCT4 tlli := f_rnd_octstring(4);
1690 var PacketDlAssign dl_tbf_ass;
1691 var GsmRrMessage rr_imm_ass;
1692 var RlcmacDlBlock dl_block;
1693 var uint32_t ack_fn;
1694 var uint32_t fn;
1695 timer T := 5.0;
1696
1697 /* Initialize NS/BSSGP side */
1698 f_init_bssgp();
1699
1700 /* Initialize the PCU interface abstraction */
1701 f_init_raw(testcasename());
1702
1703 /* Establish BSSGP connection to the PCU */
1704 f_bssgp_establish();
1705 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1706
1707 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1708 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1709 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1710
1711 /* Make sure we've got a Downlink TBF assignment with DL TFI */
1712 f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1713 if (not ispresent(dl_tbf_ass.group1)) {
1714 setverdict(fail, "Immediate Assignment contains no DL TFI");
1715 f_shutdown(__BFILE__, __LINE__);
1716 }
1717
1718 /* Get DL TFI from received Downlink TBF assignment */
1719 var uint5_t tfi := dl_tbf_ass.group1.tfi_assignment;
1720
1721 /* Wait timer X2002 and DL block is available after CCCH IMM ASS */
1722 f_sleep(X2002);
1723
1724 /* Expect the first (GPRS DL) block with bsn=0 and rrbp_valid=1 */
1725 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, 0);
1726 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1727
1728 /* TDMA frame number on which we are supposed to send the ACK */
1729 ack_fn := f_dl_block_ack_fn(dl_block, fn);
1730
1731 /* SGSN sends more blocks during the indicated RRBP */
1732 for (var integer bsn := 1; bsn < 63; bsn := bsn + 1) {
1733 data := f_rnd_octstring(16); /* Random LLC data */
1734 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1735
1736 f_rx_rlcmac_dl_block_exp_data(dl_block, fn, data, bsn);
1737
1738 /* Make sure this block has the same TFI as was assigned
1739 * FIXME: this is only valid for GPRS, not EGPRS. */
1740 if (dl_block.data.mac_hdr.hdr_ext.tfi != tfi) {
1741 setverdict(fail, "Rx DL data block with unexpected TFI: ",
1742 dl_block.data.mac_hdr.hdr_ext.tfi);
1743 f_shutdown(__BFILE__, __LINE__);
1744 }
1745
1746 /* Keep Ack/Nack description updated */
1747 f_acknackdesc_ack_block(ack_nack_desc, dl_block);
1748
1749 /* Break if this is the end of RRBP */
1750 if (fn == ack_fn) {
1751 ack_nack_desc.final_ack := '1'B;
1752 break;
1753 }
1754 }
1755
1756 /* This is the end of RRBP, send Packet Downlink Ack/Nack */
1757 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(tfi, ack_nack_desc), fn := fn);
1758
1759 /* Make sure that the next block (after the Ack) is dummy */
1760 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
1761
1762 f_shutdown(__BFILE__, __LINE__, final := true);
1763}
1764
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001765private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi)
1766runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001767 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
1768 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
1769
1770 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
1771 setverdict(fail, "Mobile Identity length mismatch: ",
1772 "expected: 8, got: ", mi_lv.len);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001773 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001774 }
1775
1776 /* Make sure MI contains IMSI before referencing it */
1777 if (mi.typeOfIdentity != '001'B) {
1778 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
1779 "got: ", mi.typeOfIdentity);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001780 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001781 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
1782 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
1783 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001784 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001785 }
1786}
1787
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001788private function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi)
1789runs on RAW_PCU_Test_CT {
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001790 if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {
1791 setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",
1792 "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001793 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001794 }
1795}
1796
1797/* Test CS paging over the BTS<->PCU socket.
1798 * 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.
1799 * Paging should be send on the PACCH.
1800 *
1801 * 1. Send a Paging Request over PCU socket.
1802 * 2. Send a Ready-To-Send message over PCU socket
1803 * 3. Expect a Paging Frame
1804 */
1805testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
1806 var GsmRrMessage rr_imm_ass;
1807 var PacketUlAssign ul_tbf_ass;
1808 var RlcmacDlBlock dl_block;
1809 var boolean ok;
1810 var OCT4 tlli := '00000001'O;
1811 var MobileIdentityLV mi;
1812 var octetstring mi_enc_lv;
1813 var hexstring imsi := f_gen_imsi(42);
1814
1815 /* Initialize NS/BSSGP side */
1816 f_init_bssgp();
1817
1818 /* Initialize the PCU interface abstraction */
1819 f_init_raw(testcasename());
1820
1821 /* Establish BSSGP connection to the PCU */
1822 f_bssgp_establish();
1823 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1824
1825 /* Establish an Uplink TBF */
1826 ok := f_establish_tbf(rr_imm_ass);
1827 if (not ok) {
1828 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001829 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001830 }
1831
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001832 /* Make sure we've got an Uplink TBF assignment */
1833 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001834
1835 /* build mobile Identity */
1836 mi := valueof(ts_MI_IMSI_LV(imsi));
1837 mi_enc_lv := enc_MobileIdentityLV(mi);
1838 /* Send paging request */
1839 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
1840 sapi :=PCU_IF_SAPI_PDTCH));
1841
1842 /* Receive it on BTS side towards MS */
1843 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1844
1845 /* Make sure that Packet Paging Request contains the same IMSI */
1846 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1847
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001848 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001849}
1850
1851/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
1852 */
1853private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1854runs on RAW_PCU_Test_CT {
1855 var GsmRrMessage rr_imm_ass;
1856 var PacketUlAssign ul_tbf_ass;
1857 var RlcmacDlBlock dl_block;
1858 var boolean ok;
1859 var OCT4 tlli := '00000001'O;
1860 var hexstring imsi := f_gen_imsi(42);
1861 var GsmTmsi tmsi;
1862
1863 /* Initialize NS/BSSGP side */
1864 f_init_bssgp();
1865
1866 /* Initialize the PCU interface abstraction */
1867 f_init_raw(testcasename());
1868
1869 /* Establish BSSGP connection to the PCU */
1870 f_bssgp_establish();
1871 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1872
1873 /* Establish an Uplink TBF */
1874 ok := f_establish_tbf(rr_imm_ass);
1875 if (not ok) {
1876 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001877 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001878 }
1879
Vadim Yanitskiy2e213ae2020-05-06 22:26:17 +07001880 /* Make sure we've got an Uplink TBF assignment */
1881 f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001882
1883 /* Send paging request with or without TMSI */
1884 if (use_ptmsi) {
1885 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
1886 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
1887 } else {
1888 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
1889 }
1890
1891 /* Receive it on BTS side towards MS */
1892 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1893
1894 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
1895 if (use_ptmsi) {
1896 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
1897 } else {
1898 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1899 }
1900
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001901 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001902}
1903
1904testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1905 f_tc_paging_cs_from_sgsn(0, true);
1906}
1907
1908testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1909 f_tc_paging_cs_from_sgsn(0);
1910}
1911
1912testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1913 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
1914}
1915
1916/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
1917 */
1918private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1919runs on RAW_PCU_Test_CT {
1920 var OCT4 tlli := '00000001'O;
1921 var integer imsi_suff_tx := 423;
1922 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
1923
1924 /* Initialize NS/BSSGP side */
1925 f_init_bssgp();
1926
1927 /* Initialize the PCU interface abstraction */
1928 f_init_raw(testcasename());
1929
1930 /* Establish BSSGP connection to the PCU */
1931 f_bssgp_establish();
1932 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1933
1934 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
1935 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
1936 if (use_ptmsi) {
1937 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
1938 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
1939 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
1940 } else {
1941 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
1942 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
1943 }
1944
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001945 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001946}
1947
1948testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1949 f_tc_paging_ps_from_sgsn(0, true);
1950}
1951
1952testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1953 f_tc_paging_ps_from_sgsn(0);
1954}
1955
1956testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1957 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
1958}
1959
1960private function f_TC_egprs_pkt_chan_req(in EGPRSPktChRequest req,
1961 template GsmRrMessage t_imm_ass := ?,
1962 PCUIF_BurstType bt := BURST_TYPE_1)
1963runs on RAW_PCU_Test_CT {
1964 var GsmRrMessage rr_msg;
1965 var uint16_t ra11;
1966 var boolean ok;
1967
1968 ra11 := enc_EGPRSPktChRequest2uint(req);
1969 log("Sending EGPRS Packet Channel Request (", ra11, "): ", req);
1970
1971 ok := f_establish_tbf(rr_msg, ra := ra11, is_11bit := 1, burst_type := bt);
1972 if (not ok) {
1973 setverdict(fail, "Failed to establush an Uplink TBF");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001974 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001975 }
1976
1977 if (not match(rr_msg, t_imm_ass)) {
1978 setverdict(fail, "Immediate Assignment does not match");
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07001979 f_shutdown(__BFILE__, __LINE__);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02001980 }
1981
1982 setverdict(pass);
1983}
1984
1985testcase TC_egprs_pkt_chan_req_signalling() runs on RAW_PCU_Test_CT {
1986 var template GsmRrMessage imm_ass;
1987 var template IaRestOctets rest;
1988 var template EgprsUlAss ul_ass;
1989
1990 /* Initialize the PCU interface abstraction */
1991 f_init_raw(testcasename());
1992
1993 var EGPRSPktChRequest req := {
1994 /* NOTE: other fields are set in the loop */
1995 signalling := { tag := '110011'B }
1996 };
1997
1998 for (var integer i := 0; i < 6; i := i + 1) {
1999 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2000 req.signalling.random_bits := ext_ra;
2001
2002 /* For signalling, do we expect Multiblock UL TBF Assignment? */
2003 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2004 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2005 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2006
2007 f_TC_egprs_pkt_chan_req(req, imm_ass);
2008 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002009
2010 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002011}
2012
2013testcase TC_egprs_pkt_chan_req_one_phase() runs on RAW_PCU_Test_CT {
2014 var template GsmRrMessage imm_ass;
2015 var template IaRestOctets rest;
2016 var template EgprsUlAss ul_ass;
2017
2018 /* Initialize the PCU interface abstraction */
2019 f_init_raw(testcasename());
2020
2021 var EGPRSPktChRequest req := {
2022 /* NOTE: other fields are set in the loop */
2023 one_phase := { tag := '0'B }
2024 };
2025
2026 for (var integer i := 0; i < 6; i := i + 1) {
2027 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2028 var BIT5 mslot_class := int2bit(f_rnd_int(32), 5);
2029 var BIT2 priority := substr(ext_ra, 0, 2);
2030 var BIT3 rand := substr(ext_ra, 2, 3);
2031
2032 req.one_phase.multislot_class := mslot_class;
2033 req.one_phase.priority := priority;
2034 req.one_phase.random_bits := rand;
2035
2036 /* For one phase access, do we expect Dynamic UL TBF Assignment? */
2037 ul_ass := tr_EgprsUlAssDynamic(ext_ra := ext_ra);
2038 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2039 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2040
2041 f_TC_egprs_pkt_chan_req(req, imm_ass);
2042 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002043
2044 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002045}
2046
2047testcase TC_egprs_pkt_chan_req_two_phase() runs on RAW_PCU_Test_CT {
2048 var template GsmRrMessage imm_ass;
2049 var template IaRestOctets rest;
2050 var template EgprsUlAss ul_ass;
2051
2052 /* Initialize the PCU interface abstraction */
2053 f_init_raw(testcasename());
2054
2055 var EGPRSPktChRequest req := {
2056 /* NOTE: other fields are set in the loop */
2057 two_phase := { tag := '110000'B }
2058 };
2059
2060 for (var integer i := 0; i < 6; i := i + 1) {
2061 var BIT5 ext_ra := int2bit(f_rnd_int(32), 5);
2062 var BIT2 priority := substr(ext_ra, 0, 2);
2063 var BIT3 rand := substr(ext_ra, 2, 3);
2064
2065 req.two_phase.priority := priority;
2066 req.two_phase.random_bits := rand;
2067
2068 /* For two phase access, do we expect Multiblock UL TBF Assignment? */
2069 ul_ass := tr_EgprsUlAssMultiblock(ext_ra := ext_ra);
2070 rest := tr_IaRestOctets_EGPRSULAss(ul_ass);
2071 imm_ass := tr_IMM_TBF_ASS(dl := false, rest := rest);
2072
2073 f_TC_egprs_pkt_chan_req(req, imm_ass);
2074 }
Vadim Yanitskiy91f8a092020-05-06 21:41:05 +07002075
2076 f_shutdown(__BFILE__, __LINE__, final := true);
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002077}
2078
2079control {
2080 execute( TC_pcuif_suspend() );
2081 execute( TC_ta_ptcch_idle() );
2082 execute( TC_ta_rach_imm_ass() );
2083 execute( TC_ta_idle_dl_tbf_ass() );
2084 execute( TC_ta_ptcch_ul_multi_tbf() );
2085 execute( TC_cs_lqual_ul_tbf() );
2086 execute( TC_cs_initial_ul() );
2087 execute( TC_cs_max_ul() );
2088 execute( TC_t3169() );
2089 execute( TC_t3193() );
2090 execute( TC_mo_ping_pong() );
2091 execute( TC_mo_ping_pong_with_ul_racap() );
2092 execute( TC_mt_ping_pong() );
2093 execute( TC_mt_ping_pong_with_dl_racap() );
2094 execute( TC_imm_ass_dl_block_retrans() );
Vadim Yanitskiy71238c12020-05-11 03:48:06 +07002095 execute( TC_dl_flow_more_blocks() );
Pau Espin Pedrol8dd59fb2020-04-29 15:08:16 +02002096 execute( TC_paging_cs_from_bts() );
2097 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
2098 execute( TC_paging_cs_from_sgsn_sign() );
2099 execute( TC_paging_cs_from_sgsn_ptp() );
2100 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
2101 execute( TC_paging_ps_from_sgsn_sign() );
2102 execute( TC_paging_ps_from_sgsn_ptp() );
2103
2104 /* EGPRS specific test cases */
2105 execute( TC_egprs_pkt_chan_req_signalling() );
2106 execute( TC_egprs_pkt_chan_req_one_phase() );
2107 execute( TC_egprs_pkt_chan_req_two_phase() );
2108}
2109
2110
2111
2112
2113
2114
Harald Weltea419df22019-03-21 17:23:04 +01002115}