blob: 8e1d349994b999512ee805c5e14257776974ecdc [file] [log] [blame]
Harald Welte9fbcf4b2018-12-07 07:56:52 +01001module PCU_Tests_RAW {
2
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
Harald Welte34b5a952019-05-27 11:54:11 +02009/* (C) 2018-2019 Harald Welte <laforge@gnumonks.org>
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +020010 * (C) 2019 Vadim Yanitskiy <axilirator@gmail.com>
Harald Welte34b5a952019-05-27 11:54:11 +020011 * All rights reserved.
12 *
13 * Released under the terms of GNU General Public License, Version 2 or
14 * (at your option) any later version.
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
18
Pau Espin Pedrol4536c822019-12-30 13:22:32 +010019friend module PCU_Tests_RAW_NS;
20
Harald Welte9fbcf4b2018-12-07 07:56:52 +010021import from General_Types all;
22import from Osmocom_Types all;
Harald Welte7fd25cf2019-03-21 22:14:02 +010023import from GSM_Types all;
24import from GSM_RR_Types all;
25
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +010026import from Osmocom_VTY_Functions all;
27import from TELNETasp_PortType all;
28
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +020029import from RLCMAC_CSN1_Types all;
30import from RLCMAC_Types all;
31
Oliver Smith8f9daab2019-10-09 09:27:19 +020032import from MobileL3_CommonIE_Types all;
33import from L3_Templates all;
34
Harald Welte9fbcf4b2018-12-07 07:56:52 +010035import from NS_Types all;
36import from BSSGP_Types all;
37import from Osmocom_Gb_Types all;
38
39import from BSSGP_Emulation all; /* BssgpConfig */
40import from NS_Emulation all; /* NSConfiguration */
41
42import from UD_Types all;
43import from PCUIF_Types all;
44import from PCUIF_CodecPort all;
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +020045import from PCUIF_RAW_Components all;
Harald Welte9fbcf4b2018-12-07 07:56:52 +010046import from IPL4asp_Types all;
Harald Welte9fbcf4b2018-12-07 07:56:52 +010047import from Native_Functions all;
48import from PCU_Tests all;
49
50modulepar {
51 charstring mp_pcu_sock_path := PCU_SOCK_DEFAULT;
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +010052
53 float X2002 := 0.2; /* Timer -2002, IMM ASSIGN confirm delay */
Harald Welte9fbcf4b2018-12-07 07:56:52 +010054}
55
Harald Welte9fbcf4b2018-12-07 07:56:52 +010056
Pau Espin Pedrolf787b092019-10-04 18:34:05 +020057/* FIXME: make sure to use parameters from mp_gb_cfg.cell_id in the PCU INFO IND */
Pau Espin Pedrol4536c822019-12-30 13:22:32 +010058private template (value) PCUIF_info_ind ts_PCUIF_INFO_default := {
Pau Espin Pedrolf787b092019-10-04 18:34:05 +020059 version := PCU_IF_VERSION,
60 flags := c_PCUIF_Flags_default,
61 trx := valueof(ts_PCUIF_InfoTrxs_def),
62 bsic := 7,
63 mcc := 262,
64 mnc := 42,
65 mnc_3_digits := 0,
66 lac := 13135,
67 rac := 0,
68 nsei := mp_nsconfig.nsei,
69 nse_timer := { 3, 3, 3, 3, 30, 3, 10 },
70 cell_timer := { 3, 3, 3, 3, 3, 10, 3, 10, 3, 10, 3 },
71 cell_id := 20960,
72 repeat_time := 5 * 50,
73 repeat_count := 3,
74 bvci := mp_gb_cfg.bvci,
75 t3142 := 20,
76 t3169 := 5,
77 t3191 := 5,
78 t3193_10ms := 160,
79 t3195 := 5,
80 t3101 := 10,
81 t3103 := 4,
82 t3105 := 8,
83 cv_countdown := 15,
84 dl_tbf_ext := 250 * 10, /* ms */
85 ul_tbf_ext := 250 * 10, /* ms */
86 initial_cs := 2,
87 initial_mcs := 6,
88 nsvci := { mp_nsconfig.nsvci, 0 },
89 local_pprt := { mp_nsconfig.remote_udp_port, 0 },
90 remote_port := { mp_nsconfig.local_udp_port, 0 },
91 remote_ip := { f_inet_haddr(mp_nsconfig.local_ip) , '00000000'O }
92}
93
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +010094type record lqual_range {
95 /* component reference to the IPA_Client component used for RSL */
96 uint8_t low,
97 uint8_t high
98}
99
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200100type component RAW_PCU_Test_CT extends bssgp_CT {
101 /* Connection to the BTS component (one for now) */
102 port RAW_PCU_MSG_PT BTS;
103 /* Connection to the PCUIF component */
104 port RAW_PCU_MSG_PT PCUIF;
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +0100105 /* VTY connection to the PCU */
106 port TELNETasp_PT PCUVTY;
107
108 /* Uplink CS/MCS thresholds, default from pcu_main.c: */
109 var lqual_range g_cs_lqual_ranges[4] := {{low := 0, high := 6},
110 {low := 5, high := 8},
111 {low := 7, high := 13},
112 {low := 12,high := 35}};
113 var lqual_range g_mcs_lqual_ranges[9] := {{low := 0, high := 6},
114 {low := 5, high := 8},
115 {low := 7, high := 13},
116 {low := 12,high := 15},
117 {low := 14, high := 17},
118 {low := 16, high := 18},
119 {low := 17,high := 20},
120 {low := 19, high := 24},
121 {low := 23,high := 35}};
122 var uint8_t g_cs_initial_dl := 1;
123 var uint8_t g_cs_initial_ul := 1;
124 var uint8_t g_mcs_initial_dl := 1;
125 var uint8_t g_mcs_initial_ul := 1;
126 var uint8_t g_cs_max_dl := 4;
127 var uint8_t g_cs_max_ul := 4;
128 var uint8_t g_mcs_max_dl := 9;
129 var uint8_t g_mcs_max_ul := 9;
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200130
131 /* Guard timeout */
132 timer g_T_guard := 60.0;
133};
134
135private altstep as_Tguard_RAW() runs on RAW_PCU_Test_CT {
136 [] g_T_guard.timeout {
137 setverdict(fail, "Timeout of T_guard");
138 mtc.stop;
139 }
140}
141
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +0100142private function f_pcuvty_set_allowed_cs_mcs() runs on RAW_PCU_Test_CT {
143 f_vty_config2(PCUVTY, {"pcu"}, "cs " & int2str(g_cs_initial_dl) & " " & int2str(g_cs_initial_ul));
144 f_vty_config2(PCUVTY, {"pcu"}, "cs max " & int2str(g_cs_max_dl) & " " & int2str(g_cs_max_ul));
145
146 f_vty_config2(PCUVTY, {"pcu"}, "mcs " & int2str(g_mcs_initial_dl) & " " & int2str(g_mcs_initial_ul));
147 f_vty_config2(PCUVTY, {"pcu"}, "mcs max " & int2str(g_mcs_max_dl) & " " & int2str(g_mcs_max_ul));
148}
149
150private function f_pcuvty_set_link_quality_ranges() runs on RAW_PCU_Test_CT {
151 var charstring cmd;
152
153 cmd := "cs link-quality-ranges" &
154 " cs1 " & int2str(g_cs_lqual_ranges[0].high) &
155 " cs2 " & int2str(g_cs_lqual_ranges[1].low) & " " & int2str(g_cs_lqual_ranges[1].high) &
156 " cs3 " & int2str(g_cs_lqual_ranges[2].low) & " " & int2str(g_cs_lqual_ranges[2].high) &
157 " cs4 " & int2str(g_cs_lqual_ranges[3].low);
158 f_vty_config2(PCUVTY, {"pcu"}, cmd);
159
160 cmd := "mcs link-quality-ranges" &
161 " mcs1 " & int2str(g_mcs_lqual_ranges[0].high) &
162 " mcs2 " & int2str(g_mcs_lqual_ranges[1].low) & " " & int2str(g_mcs_lqual_ranges[1].high) &
163 " mcs3 " & int2str(g_mcs_lqual_ranges[2].low) & " " & int2str(g_mcs_lqual_ranges[2].high) &
164 " mcs4 " & int2str(g_mcs_lqual_ranges[3].low) & " " & int2str(g_mcs_lqual_ranges[3].high) &
165 " mcs5 " & int2str(g_mcs_lqual_ranges[4].low) & " " & int2str(g_mcs_lqual_ranges[4].high) &
166 " mcs6 " & int2str(g_mcs_lqual_ranges[5].low) & " " & int2str(g_mcs_lqual_ranges[5].high) &
167 " mcs7 " & int2str(g_mcs_lqual_ranges[6].low) & " " & int2str(g_mcs_lqual_ranges[6].high) &
168 " mcs8 " & int2str(g_mcs_lqual_ranges[7].low) & " " & int2str(g_mcs_lqual_ranges[7].high) &
169 " mcs9 " & int2str(g_mcs_lqual_ranges[8].low);
170 f_vty_config2(PCUVTY, {"pcu"}, cmd);
171}
172
173private function f_init_vty(charstring id) runs on RAW_PCU_Test_CT {
174 map(self:PCUVTY, system:PCUVTY);
175 f_vty_set_prompts(PCUVTY);
176 f_vty_transceive(PCUVTY, "enable");
177}
178
Pau Espin Pedrolf787b092019-10-04 18:34:05 +0200179private function f_init_raw(charstring id, template (value) PCUIF_info_ind info_ind := ts_PCUIF_INFO_default)
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200180runs on RAW_PCU_Test_CT {
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200181 var RAW_PCUIF_CT vc_PCUIF;
182 var RAW_PCU_BTS_CT vc_BTS;
183
184 /* Start the guard timer */
185 g_T_guard.start;
186 activate(as_Tguard_RAW());
187
188 /* Init PCU interface component */
189 vc_PCUIF := RAW_PCUIF_CT.create("PCUIF-" & id);
190 connect(vc_PCUIF:MTC, self:PCUIF);
191 map(vc_PCUIF:PCU, system:PCU);
192
193 /* Create one BTS component (we may want more some day) */
194 vc_BTS := RAW_PCU_BTS_CT.create("BTS-" & id);
195 connect(vc_BTS:PCUIF, vc_PCUIF:BTS);
196 connect(vc_BTS:TC, self:BTS);
197
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +0100198 f_init_vty(id);
199
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200200 vc_PCUIF.start(f_PCUIF_CT_handler(mp_pcu_sock_path));
Pau Espin Pedrolf787b092019-10-04 18:34:05 +0200201 vc_BTS.start(f_BTS_CT_handler(0, valueof(info_ind)));
Vadim Yanitskiyf7d9c0f2019-09-06 00:08:17 +0200202
203 /* Wait until the BTS is ready (SI13 negotiated) */
204 BTS.receive(tr_RAW_PCU_EV(BTS_EV_SI13_NEGO));
205}
206
Pau Espin Pedrol89486332019-12-05 14:05:46 +0100207template AckNackDescription t_AckNackDescription_init := {
208 final_ack := '0'B,
209 starting_seq_nr := 0,
210 receive_block_bitmap := '0000000000000000000000000000000000000000000000000000000000000000'B
211}
212
213/* TS 44.060 sec 12.3 Ack/Nack Description */
214private function f_acknackdesc_ack_block(inout AckNackDescription desc, uint7_t bsn, BIT1 final_ack := '0'B)
215{
216 var integer i;
217 var integer inc := bsn - desc.starting_seq_nr + 1;
218 /* Filling hole? */
219 if (bsn < desc.starting_seq_nr) {
220 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - (desc.starting_seq_nr - bsn)] := int2bit(1, 1);
221 return;
222 }
223
224 /* SSN is increased, and so RBB values need to be moved */
225 for (i := 0; i < lengthof(desc.receive_block_bitmap) - inc; i := i+1) {
226 desc.receive_block_bitmap[i] := desc.receive_block_bitmap[i + inc];
227 }
228 for (i := lengthof(desc.receive_block_bitmap) - inc; i < lengthof(desc.receive_block_bitmap) - 1; i := i+1) {
229 desc.receive_block_bitmap[i] := int2bit(0, 1);
230 }
231 /* Now we can set current bit and update SSN */
232 desc.starting_seq_nr := bsn + 1;
233 desc.receive_block_bitmap[lengthof(desc.receive_block_bitmap) - 1] := int2bit(1, 1);
234
235 /* Finally update the final_ack bit as requested: */
236 desc.final_ack := final_ack;
237}
238
Vadim Yanitskiy8ae978c2020-04-01 23:01:55 +0700239private function f_pcuif_rx_imm_ass(out GsmRrMessage rr_imm_ass,
240 template GsmRrMessage t_imm_ass := ?,
241 uint8_t bts_nr := 0)
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200242runs on RAW_PCU_Test_CT return boolean {
243 var PCUIF_Message pcu_msg;
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200244 timer T;
245
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200246 T.start(2.0);
247 alt {
Vadim Yanitskiy36558d92019-11-17 02:23:51 +0700248 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200249 sapi := PCU_IF_SAPI_AGCH, data := ?))
250 -> value pcu_msg {
251 rr_imm_ass := dec_GsmRrMessage(pcu_msg.u.data_req.data);
252 log("Rx Immediate Assignment: ", rr_imm_ass);
253
Vadim Yanitskiy8ae978c2020-04-01 23:01:55 +0700254 if (match(rr_imm_ass, t_imm_ass)) {
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200255 setverdict(pass);
256 return true;
257 }
258
259 /* Not for us? Wait for more. */
260 repeat;
261 }
262 [] BTS.receive { repeat; }
263 [] T.timeout {
264 setverdict(fail, "Timeout waiting for Immediate Assignment");
265 }
266 }
267
268 return false;
269}
270
Vadim Yanitskiy8ae978c2020-04-01 23:01:55 +0700271/* FIXME: properly encode RA (see TS 24.060, table 11.2.5.2) */
272private function f_establish_tbf(out GsmRrMessage rr_imm_ass, uint8_t bts_nr := 0,
273 uint16_t ra := oct2int('3A'O), uint8_t is_11bit := 0,
274 PCUIF_BurstType burst_type := BURST_TYPE_0,
275 TimingAdvance ta := 0)
276runs on RAW_PCU_Test_CT return boolean {
277 var uint32_t fn;
278
279 /* FIXME: ask the BTS component to give us the current TDMA fn */
280 fn := 1337 + ta;
281
282 /* Send RACH.ind */
283 log("Sending RACH.ind on fn=", fn, " with RA=", ra, ", TA=", ta);
284 BTS.send(ts_PCUIF_RACH_IND(bts_nr := bts_nr, trx_nr := 0, ts_nr := 0,
285 ra := ra, is_11bit := is_11bit,
286 burst_type := burst_type,
287 fn := fn, arfcn := 871,
288 qta := ta * 4));
289
290 /* Expect Immediate (TBF) Assignment on TS0/AGCH */
291 return f_pcuif_rx_imm_ass(rr_imm_ass, tr_IMM_TBF_ASS(?, ra, fn), bts_nr);
292}
293
Pau Espin Pedrol6c1b4be2019-10-04 19:31:02 +0200294private function f_imm_ass_verify_ul_tbf_ass(GsmRrMessage rr_imm_ass, out PacketUlAssign ul_tbf_ass)
295runs on RAW_PCU_Test_CT return boolean {
296
297 /* Make sure we received an UL TBF Assignment */
298 if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
299 ul_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
300 log("Rx Uplink TBF assignment: ", ul_tbf_ass);
301 setverdict(pass);
302 } else {
303 setverdict(fail, "Failed to match UL TBF Assignment");
304 return false;
305 }
306
307 /* Make sure we have got a TBF with Dynamic Block Allocation */
308 if (ul_tbf_ass.dynamic == omit) {
309 setverdict(fail, "Single Block Allocation is not handled by ", testcasename());
310 return false;
311 }
312
313 return true;
314}
315
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +0200316private function f_imm_ass_verify_dl_tbf_ass(GsmRrMessage rr_imm_ass, out PacketDlAssign dl_tbf_ass)
317runs on RAW_PCU_Test_CT return boolean {
318
319 /* Make sure we received a DL TBF Assignment */
320 if (match(rr_imm_ass, tr_IMM_TBF_ASS(dl := true, rest := tr_IaRestOctets_DLAss(?)))) {
321 dl_tbf_ass := rr_imm_ass.payload.imm_ass.rest_octets.hh.pa.uldl.ass.dl;
322 log("Rx Downlink TBF assignment: ", dl_tbf_ass);
323 setverdict(pass);
324 } else {
325 setverdict(fail, "Failed to match DL TBF Assignment");
326 return false;
327 }
328
329 return true;
330}
331
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200332/* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100333private function f_pcuif_tx_data_ind(octetstring data, int16_t lqual_cb := 0, uint32_t fn := 0)
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200334runs on RAW_PCU_Test_CT {
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100335 var template RAW_PCU_EventParam ev_param := {tdma_fn := ? };
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200336 BTS.send(ts_PCUIF_DATA_IND(bts_nr := 0, trx_nr := 0, ts_nr := 7, block_nr := 0,
337 sapi := PCU_IF_SAPI_PDTCH, data := data,
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100338 fn := fn, arfcn := 871, lqual_cb := lqual_cb));
339 if (fn != 0) {
340 ev_param := {tdma_fn := fn };
341 }
342 BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PDTCH_BLOCK_SENT, ev_param));
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200343}
344
345/* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
346private function f_pcuif_rx_data_req(out PCUIF_Message pcu_msg)
347runs on RAW_PCU_Test_CT {
348 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
349 sapi := PCU_IF_SAPI_PDTCH, fn := 0,
350 arfcn := 871, block_nr := 0));
351 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
352 sapi := PCU_IF_SAPI_PDTCH)) -> value pcu_msg;
353}
354
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +0200355/* Expect an Immediate Assignment (paging) from PCU on PCUIF on specified sapi. */
356private function f_pcuif_rx_pch_imm_tbf_ass(out GsmRrMessage rr_imm_ass)
357runs on RAW_PCU_Test_CT {
358 var PCUIF_Message pcu_msg;
359 var octetstring macblock;
360 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
361 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
362 /* First 3 bytes contain paging group: */
363 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
364 rr_imm_ass := dec_GsmRrMessage(macblock);
365 if (not match(rr_imm_ass, tr_IMM_TBF_ASS())) {
366 setverdict(fail, "Failed to match Immediate Assignment: ", rr_imm_ass);
367 mtc.stop;
368 }
369 BTS.send(ts_PCUIF_DATA_CNF(bts_nr := 0, trx_nr := 0, ts_nr := 0, block_nr := 0,
Pau Espin Pedrolf04ba542019-12-23 14:47:44 +0100370 fn := pcu_msg.u.data_req.fn, arfcn := 871, sapi := PCU_IF_SAPI_PCH, data := macblock));
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +0200371}
372
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100373/* Expect a Paging Request Type 1 from PCU on PCUIF on specified sapi. */
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700374private function f_pcuif_rx_pch_pag_req1(template MobileIdentityV mi1 := ?,
375 template integer pag_group := ?)
376runs on RAW_PCU_Test_CT return GsmRrMessage {
377 var GsmRrMessage rr_pag_req1;
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100378 var PCUIF_Message pcu_msg;
Pau Espin Pedrol925818a2020-01-02 14:06:51 +0100379 var octetstring imsi_suff_octstr;
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700380 var integer pag_group_rx;
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100381 var octetstring macblock;
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700382
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100383 BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 0,
384 sapi := PCU_IF_SAPI_PCH)) -> value pcu_msg;
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700385
Pau Espin Pedrol925818a2020-01-02 14:06:51 +0100386 /* First 3 bytes contain IMSI suffix to calculate paging group: */
387 imsi_suff_octstr := substr(pcu_msg.u.data_req.data, 0, 3);
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700388 pag_group_rx := str2int(oct2char(imsi_suff_octstr[0])) * 100 +
Pau Espin Pedrol925818a2020-01-02 14:06:51 +0100389 str2int(oct2char(imsi_suff_octstr[1])) * 10 +
390 str2int(oct2char(imsi_suff_octstr[2]));
391
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700392 /* Make sure we've got RR Paging Request Type 1 for a given MI */
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100393 macblock := substr(pcu_msg.u.data_req.data, 3, pcu_msg.u.data_req.len - 3);
394 rr_pag_req1 := dec_GsmRrMessage(macblock);
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700395 if (not match(rr_pag_req1, tr_PAG_REQ1(tr_MI_LV(mi1)))) {
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100396 setverdict(fail, "Failed to match Paging Request Type 1: ", rr_pag_req1);
397 mtc.stop;
398 }
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700399
400 /* Make sure that received paging froup matches the expected one */
401 if (not match(pag_group_rx, pag_group)) {
402 setverdict(fail, "Paging group", pag_group_rx, " does not match expected ", pag_group);
403 mtc.stop;
404 }
405
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100406 BTS.send(ts_PCUIF_DATA_CNF(bts_nr := 0, trx_nr := 0, ts_nr := 0, block_nr := 0,
407 fn := pcu_msg.u.data_req.fn, arfcn := 871, sapi := PCU_IF_SAPI_PCH, data := macblock));
Vadim Yanitskiy9c513132020-03-28 04:33:07 +0700408
409 return rr_pag_req1;
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +0100410}
411
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100412private function f_tx_rlcmac_ul_block(template (value) RlcmacUlBlock ul_data, int16_t lqual_cb := 0, uint32_t fn := 0)
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200413runs on RAW_PCU_Test_CT {
414 var octetstring data;
415 /* Encode the payload of DATA.ind */
416 data := enc_RlcmacUlBlock(valueof(ul_data));
417 data := f_pad_oct(data, 23, '00'O); /* CS-1 */
418
419 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100420 f_pcuif_tx_data_ind(data, lqual_cb, fn);
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200421}
422
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200423private function f_tx_rlcmac_ul_n_blocks(PacketUlAssign ul_tbf_ass, integer num_blocks := 1)
424runs on RAW_PCU_Test_CT {
425 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
426 tfi := ul_tbf_ass.dynamic.tfi_assignment,
427 cv := num_blocks - 1, /* num UL blocks to be sent (to be overridden in loop) */
428 bsn := 0, /* TODO: what should be here? */
429 blocks := { /* To be generated in loop */ });
430
431 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
432 ul_data.data.tlli := '00000001'O;
433
434 for (var integer i := 0; i < num_blocks; i := i + 1) {
435 /* Prepare a new UL block (CV, random payload) */
436 ul_data.data.mac_hdr.countdown := (num_blocks - i - 1);
437 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
438 f_tx_rlcmac_ul_block(ul_data);
439 }
440}
441
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +0100442private function f_rx_rlcmac_dl_block(out RlcmacDlBlock dl_block, out uint32_t dl_fn, template (present) CodingScheme exp_cs_mcs := ?)
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200443runs on RAW_PCU_Test_CT {
444 var PCUIF_Message pcu_msg;
445 f_pcuif_rx_data_req(pcu_msg);
446 dl_block := dec_RlcmacDlBlock(pcu_msg.u.data_req.data);
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100447 dl_fn := pcu_msg.u.data_req.fn;
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +0100448
449 var integer len := lengthof(pcu_msg.u.data_req.data);
450 var CodingScheme cs_mcs := f_rlcmac_block_len2cs_mcs(len)
451 if (not match(f_rlcmac_block_len2cs_mcs(len), exp_cs_mcs)) {
452 setverdict(fail, "Failed to match Coding Scheme exp ", exp_cs_mcs, " vs ", cs_mcs, " (", len, ")");
453 mtc.stop;
454 }
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200455}
456
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100457private function f_rx_rlcmac_dl_block_exp_ack_nack(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200458runs on RAW_PCU_Test_CT {
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100459 var uint32_t dl_fn;
460
461 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Pau Espin Pedrol21659632019-12-02 19:12:08 +0100462 if (not match(dl_block, tr_RLCMAC_UL_ACK_NACK(ul_tfi := ?, tlli := ?))) {
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200463 setverdict(fail, "Failed to match Packet Uplink ACK / NACK");
464 mtc.stop;
465 }
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100466
467 poll_fn := dl_fn + f_rrbp_fn_delay(dl_block.ctrl.mac_hdr.rrbp);
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200468}
469
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200470private function f_rx_rlcmac_dl_block_exp_dummy(out RlcmacDlBlock dl_block)
471runs on RAW_PCU_Test_CT {
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100472 var uint32_t dl_fn;
473
474 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Pau Espin Pedrol596faa42019-10-04 19:31:29 +0200475 if (not match(dl_block, tr_RLCMAC_DUMMY_CTRL())) {
476 setverdict(fail, "Failed to match Packet DUMMY DL");
477 mtc.stop;
478 }
479}
480
Pau Espin Pedrolff8da192019-12-05 17:23:58 +0100481private function f_rx_rlcmac_dl_block_exp_pkt_ass(out RlcmacDlBlock dl_block, out uint32_t poll_fn)
482runs on RAW_PCU_Test_CT {
483 var uint32_t dl_fn;
484
485 f_rx_rlcmac_dl_block(dl_block, dl_fn);
486 if (not match(dl_block, tr_RLCMAC_DL_PACKET_ASS())) {
487 setverdict(fail, "Failed to match Packet Downlink Assignment");
488 mtc.stop;
489 }
490
491 poll_fn := dl_fn + f_rrbp_fn_delay(dl_block.ctrl.mac_hdr.rrbp);
492}
493
Oliver Smith8f9daab2019-10-09 09:27:19 +0200494private function f_rx_rlcmac_dl_block_exp_pkt_pag_req(out RlcmacDlBlock dl_block)
495runs on RAW_PCU_Test_CT {
496 var uint32_t dl_fn;
497
498 f_rx_rlcmac_dl_block(dl_block, dl_fn);
499 if (not match(dl_block, tr_RLCMAC_PACKET_PAG_REQ())) {
500 setverdict(fail, "Failed to match Packet Paging Request: ", dl_block, " vs ", tr_RLCMAC_PACKET_PAG_REQ());
501 mtc.stop;
502 }
503}
504
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +0100505private function f_rx_rlcmac_dl_block_exp_data(out RlcmacDlBlock dl_block, out uint32_t ack_fn, octetstring data, template (present) uint7_t exp_bsn := ?, template (present) CodingScheme exp_cs := ?)
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100506runs on RAW_PCU_Test_CT {
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100507 var PCUIF_Message pcu_msg;
508 var uint32_t dl_fn;
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100509 var template RlcmacDlBlock dl_template := tr_RLCMAC_DATA_RRBP;
510 dl_template.data.blocks := ?;
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100511
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100512 f_rx_rlcmac_dl_block(dl_block, dl_fn);
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100513 if (not match(dl_block, dl_template)) {
514 setverdict(fail, "Failed to match Packet data: ", dl_block, " vs ", dl_template);
515 mtc.stop;
516 }
Pau Espin Pedrol6e3b6892019-12-04 19:24:16 +0100517
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +0100518 ack_fn := dl_fn + f_rrbp_fn_delay(dl_block.data.mac_hdr.mac_hdr.rrbp);
519
Pau Espin Pedrol89486332019-12-05 14:05:46 +0100520 if (not match(dl_block.data.mac_hdr.hdr_ext.bsn, exp_bsn)) {
521 setverdict(fail, "DL block BSN doesn't match: ",
522 dl_block.data.blocks[0].hdr.length_ind, " vs exp ", exp_bsn);
523 }
524
Pau Espin Pedrol6e3b6892019-12-04 19:24:16 +0100525 if (lengthof(dl_block.data.blocks) < 1) {
526 setverdict(fail, "DL block has no LLC payload: ", dl_block);
527 mtc.stop;
528 }
529
530 if (ispresent(dl_block.data.blocks[0].hdr) and dl_block.data.blocks[0].hdr.length_ind != lengthof(data)) {
531 setverdict(fail, "DL block has LLC header with wrong expected size: ",
532 dl_block.data.blocks[0].hdr.length_ind, " vs ", lengthof(data));
533 mtc.stop;
534 }
535
536 if (dl_block.data.blocks[0].payload != data) {
537 setverdict(fail, "Failed to match content of LLC payload in DL Block: ", dl_block, " vs ", data);
538 mtc.stop;
539 }
540
541 /* Check next data blocks contain dummy frames */
542 if (lengthof(dl_block.data.blocks) > 1 and substr(dl_block.data.blocks[1].payload, 0, 3) != '43C001'O) {
543 setverdict(fail, "Second data payload is not a dummy frame: ", dl_block.data.blocks[1].payload);
544 mtc.stop;
545 }
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +0100546}
547
Vadim Yanitskiy740ae762019-09-29 16:13:41 +0700548testcase TC_pcuif_suspend() runs on RAW_PCU_Test_CT {
549 var octetstring ra_id := enc_RoutingAreaIdentification(mp_gb_cfg.cell_id.ra_id);
550 var GprsTlli tlli := 'FFFFFFFF'O;
551 timer T;
552
553 /* Initialize NS/BSSGP side */
554 f_init_bssgp();
555
556 /* Initialize the PCU interface abstraction */
557 f_init_raw(testcasename());
558
559 /* Establish BSSGP connection to the PCU */
560 f_bssgp_establish();
561
562 BTS.send(ts_PCUIF_SUSP_REQ(0, tlli, ra_id, 0));
563
564 T.start(2.0);
565 alt {
566 [] BSSGP_SIG[0].receive(tr_BSSGP_SUSPEND(tlli, mp_gb_cfg.cell_id.ra_id)) {
567 setverdict(pass);
568 }
569 [] T.timeout {
570 setverdict(fail, "Timeout waiting for BSSGP SUSPEND");
571 }
572 }
573}
574
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +0200575/* Test of correct Timing Advance at the time of TBF establishment
576 * (derived from timing offset of the Access Burst). */
577testcase TC_ta_rach_imm_ass() runs on RAW_PCU_Test_CT {
578 var GsmRrMessage rr_msg;
579 var boolean ok;
580
581 /* Initialize the PCU interface abstraction */
582 f_init_raw(testcasename());
583
584 /* We cannot send too many TBF requests in a short time because
585 * at some point the PCU will fail to allocate a new TBF. */
586 for (var TimingAdvance ta := 0; ta < 64; ta := ta + 16) {
587 /* Establish an Uplink TBF (send RACH.ind with current TA) */
588 ok := f_establish_tbf(rr_msg, bts_nr := 0, ta := ta);
589 if (not ok) {
590 setverdict(fail, "Failed to establish an Uplink TBF");
591 mtc.stop;
592 }
593
594 /* Make sure Timing Advance IE matches out expectations */
595 if (match(rr_msg, tr_IMM_TBF_ASS(dl := false, ta := ta))) {
596 setverdict(pass);
597 }
598 }
599}
600
Vadim Yanitskiy1f72b0a2019-10-01 05:58:45 +0700601/* Verify that the PCU generates valid PTCCH/D messages
602 * while neither Uplink nor Downlink TBF is established. */
603testcase TC_ta_ptcch_idle() runs on RAW_PCU_Test_CT {
604 var PTCCHDownlinkMsg ptcch_msg;
605 var PCUIF_Message pcu_msg;
606 timer T;
607
608 /* Initialize the PCU interface abstraction */
609 f_init_raw(testcasename());
610
611 /* Sent an RTS.req for PTCCH/D */
612 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
613 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
614 arfcn := 871, block_nr := 0));
615 T.start(5.0);
616 alt {
617 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
618 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
619 log("Rx DATA.req message: ", pcu_msg);
620 setverdict(pass);
621 }
622 [] BTS.receive(PCUIF_Message:?) { repeat; }
623 [] T.timeout {
624 setverdict(fail, "Timeout waiting for a PTCCH/D block");
625 mtc.stop;
626 }
627 }
628
629 ptcch_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
630 log("Decoded PTCCH/D message: ", ptcch_msg);
631
632 /* Make sure the message is encoded correctly
633 * TODO: do we expect all TA values to be equal '1111111'B? */
634 if (not match(ptcch_msg, tr_PTCCHDownlinkMsg)) {
635 setverdict(fail, "Malformed PTCCH/D message");
636 mtc.stop;
637 }
638}
639
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700640/* Test of correct Timing Advance during an active Uplink TBF.
641 *
642 * Unlike the circuit-switched domain, Uplink transmissions on PDCH time-slots
643 * are not continuous and there can be long time gaps between them. This happens
644 * due to a bursty nature of packet data. The actual Timing Advance of a MS may
645 * significantly change between such rare Uplink transmissions, so GPRS introduces
646 * additional mechanisms to control Timing Advance, and thus reduce interference
647 * between neighboring TDMA time-slots.
648 *
649 * At the moment of Uplink TBF establishment, initial Timing Advance is measured
650 * from ToA (Timing of Arrival) of an Access Burst. This is covered by another
651 * test case - TC_ta_rach_imm_ass. In response to that Access Burst the network
652 * sends Immediate Assignment on AGCH, which _may_ contain Timing Advance Index
653 * among with the initial Timing Advance value. And here PTCCH comes to play.
654 *
655 * PTCCH is a unidirectional channel on which the network can instruct a sub-set
656 * of 16 MS (whether TBFs are active or not) to adjust their Timing Advance
657 * continuously. To ensure continuous measurements of the signal propagation
658 * delay, the MSs shall transmit Access Bursts on Uplink (PTCCH/U) on sub-slots
659 * defined by an assigned Timing Advance Index (see 3GPP TS 45.002).
660 *
661 * The purpose of this test case is to verify the assignment of Timing Advance
662 * Index, and the process of Timing Advance notification on PTCCH/D. The MTC
663 * first establishes several Uplink TBFs, but does not transmit any Uplink
664 * blocks on them. During 4 TDMA multi-frame periods the MTC is sending RACH
665 * indications to the PCU, checking the correctness of two received PTCCH/D
666 * messages (period of PTCCH/D is two multi-frames).
667 */
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700668
669/* List of ToA values for Access Bursts to be sent on PTCCH/U,
670 * each ToA (Timing of Arrival) value is in units of 1/4 of
671 * a symbol (i.e. 1 symbol is 4 QTA units). */
672type record length(16) of int16_t PTCCH_TAI_ToA_MAP;
673const PTCCH_TAI_ToA_MAP ptcch_toa_map_def := {
674 0, 0, 0, 0,
675 0, 0, 0, 0,
676 0, 0, 0, 0,
677 0, 0, 0, 0
678};
679
Vadim Yanitskiy36558d92019-11-17 02:23:51 +0700680private altstep as_ta_ptcch(uint8_t bts_nr := 0, uint8_t trx_nr := 0, uint8_t ts_nr := 7,
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700681 in PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def)
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700682runs on RAW_PCU_Test_CT {
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700683 var RAW_PCU_Event event;
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700684 var integer ss;
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700685
686 /* Send Access Bursts on PTCCH/U for every TA Index */
687 [] BTS.receive(tr_RAW_PCU_EV(TDMA_EV_PTCCH_UL_BURST)) -> value event {
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700688 ss := f_tdma_ptcch_fn2ss(event.data.tdma_fn);
689 if (ss < 0) { mtc.stop; } /* Shall not happen */
690
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700691 log("Sending an Access Burst on PTCCH/U",
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700692 ", sub-slot=", ss, " (TAI)",
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700693 ", fn=", event.data.tdma_fn,
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700694 ", ToA=", toa_map[ss], " (QTA)");
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700695 /* TODO: do we care about RA and burst format? */
Vadim Yanitskiy36558d92019-11-17 02:23:51 +0700696 BTS.send(ts_PCUIF_RACH_IND(bts_nr, trx_nr, ts_nr,
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700697 ra := oct2int('3A'O),
698 is_11bit := 0,
699 burst_type := BURST_TYPE_0,
700 fn := event.data.tdma_fn,
701 arfcn := 871,
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700702 qta := toa_map[ss],
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700703 sapi := PCU_IF_SAPI_PTCCH));
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700704 repeat;
705 }
706}
707
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700708private function f_TC_ta_ptcch_ul_multi_tbf(in PTCCH_TAI_ToA_MAP ptcch_toa_map,
709 template PTCCHDownlinkMsg t_ta_msg)
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700710runs on RAW_PCU_Test_CT {
711 var PTCCHDownlinkMsg ta_msg;
712 var PCUIF_Message pcu_msg;
713 timer T;
714
715 /* First, send an RTS.req for the upcoming PTCCH/D block */
716 BTS.send(ts_PCUIF_RTS_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
717 sapi := PCU_IF_SAPI_PTCCH, fn := 0,
718 arfcn := 871, block_nr := 0));
719 T.start(2.0);
720 alt {
721 /* Keep sending of Access Bursts during two multi-frames (period of PTCCH/D)
722 * with increasing ToA (Timing of Arrival) values: 0, 7, 14, 28, 35... */
Vadim Yanitskiy36558d92019-11-17 02:23:51 +0700723 [] as_ta_ptcch(bts_nr := 0, trx_nr := 0, ts_nr := 7, toa_map := ptcch_toa_map);
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700724 /* In the end of 2nd multi-frame we should receive a PTCCH/D block */
725 [] BTS.receive(tr_PCUIF_DATA_REQ(bts_nr := 0, trx_nr := 0, ts_nr := 7,
726 sapi := PCU_IF_SAPI_PTCCH)) -> value pcu_msg {
727 ta_msg := dec_PTCCHDownlinkMsg(pcu_msg.u.data_req.data);
728 log("Rx PTCCH/D message: ", ta_msg);
729
730 /* Make sure Timing Advance values match our expectations */
731 if (match(ta_msg, t_ta_msg)) {
732 setverdict(pass);
733 } else {
734 setverdict(fail, "PTCCH/D message does not match: ", t_ta_msg);
735 }
736 }
737 [] BTS.receive { repeat; }
738 [] T.timeout {
739 setverdict(fail, "Timeout waiting for a PTCCH/D block");
740 mtc.stop;
741 }
742 }
743}
744
745testcase TC_ta_ptcch_ul_multi_tbf() runs on RAW_PCU_Test_CT {
746 var template PacketUlAssign t_ul_tbf_ass;
747 var PacketUlAssign ul_tbf_ass[7];
748 var GsmRrMessage rr_msg[7];
749 var boolean ok;
750
751 /* Initialize the PCU interface abstraction */
752 f_init_raw(testcasename());
753
754 /* Enable forwarding of PTCCH/U TDMA events to us */
755 BTS.send(ts_RAW_PCU_CMD(TDMA_CMD_ENABLE_PTCCH_UL_FWD));
756
757 /* Establish 7 Uplink TBFs (USF flag is 3 bits long, '111'B is reserved) */
758 for (var integer i := 0; i < 7; i := i + 1) {
759 ok := f_establish_tbf(rr_msg[i], ta := 0);
760 if (not ok) {
761 setverdict(fail, "Failed to establish an Uplink TBF #", i);
762 mtc.stop;
763 }
764
765 /* Make sure we received an UL TBF Assignment */
766 if (match(rr_msg[i], tr_IMM_TBF_ASS(dl := false, rest := tr_IaRestOctets_ULAss(?)))) {
767 ul_tbf_ass[i] := rr_msg[i].payload.imm_ass.rest_octets.hh.pa.uldl.ass.ul;
768 log("Rx Uplink TBF assignment for #", i, ": ", ul_tbf_ass[i]);
769 } else {
770 setverdict(fail, "Failed to match UL TBF Assignment for #", i);
771 mtc.stop;
772 }
773
774 /* We expect incremental TFI/USF assignment (dynamic allocation) */
775 t_ul_tbf_ass := tr_PacketUlDynAssign(tfi := i, usf := i);
776 if (not match(ul_tbf_ass[i], t_ul_tbf_ass)) {
777 setverdict(fail, "Failed to match Packet Uplink Assignment for #", i);
778 mtc.stop;
779 }
780
781 /* We also expect Timing Advance Index to be a part of the assignment */
782 if (ul_tbf_ass[i].dynamic.ta_index != i) {
783 setverdict(fail, "Failed to match Timing Advance Index for #", i);
784 /* Keep going, the current OsmoPCU does not assign TA Index */
785 }
786 }
787
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700788 /* Prepare a list of ToA values for Access Bursts to be sent on PTCCH/U */
789 var PTCCH_TAI_ToA_MAP toa_map := ptcch_toa_map_def;
790 for (var integer i := 0; i < 7; i := i + 1) {
791 /* ToA in units of 1/4 of a symbol */
792 toa_map[i] := (i + 1) * 7 * 4;
793 }
794
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700795 /* Now we have all 7 TBFs established in one-phase access mode,
796 * however we will not be sending any data on them. Instead, we
797 * will be sending RACH.ind on PTCCH/U during 4 multi-frame
798 * periods (TAI 0..8), and then will check two PTCCH/D blocks.
799 *
800 * Why not 4 TBFs at once? Because Uplink is delayed by 3 TDMA
801 * time-slots, so at the moment of scheduling a PTCCH/D block
802 * the PCU has odd number of PTCCH/U Access Bursts received. */
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700803 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700804 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
805 /* Other values are not known (yet) */
806 tai3_ta := ?));
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700807 f_TC_ta_ptcch_ul_multi_tbf(toa_map, tr_PTCCHDownlinkMsg(
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700808 tai0_ta := 7, tai1_ta := 14, tai2_ta := 21,
809 tai3_ta := 28, tai4_ta := 35, tai5_ta := 42,
Vadim Yanitskiy20f87002019-10-06 00:51:50 +0700810 /* Other values are out of our interest */
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +0700811 tai6_ta := ?));
812}
813
Vadim Yanitskiy26cd2442019-11-08 05:39:06 +0700814/* Default link quality adaptation (Coding Scheme) ranges (inclusive).
815 * OsmoPCU (VTY): cs link-quality-ranges cs1 6 cs2 5 8 cs3 7 13 cs4 12
816 *
817 * NOTE: the ranges are intentionally overlapping because OsmoPCU
818 * does not change CS/MCS on the range borders (5-6, 7-8, 12-13). */
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200819private template integer CS1_lqual_dB_range := (-infinity .. 6);
820private template integer CS2_lqual_dB_range := (5 .. 8);
821private template integer CS3_lqual_dB_range := (7 .. 13);
822private template integer CS4_lqual_dB_range := (12 .. infinity);
823
824testcase TC_cs_lqual_ul_tbf() runs on RAW_PCU_Test_CT {
Pau Espin Pedrol6c1b4be2019-10-04 19:31:02 +0200825 var GsmRrMessage rr_imm_ass;
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200826 var PacketUlAssign ul_tbf_ass;
827 var RlcmacDlBlock dl_block;
828 var PCUIF_Message pcu_msg;
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200829 var octetstring data;
830 var boolean ok;
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100831 var uint32_t unused_fn;
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200832
833 /* Initialize the PCU interface abstraction */
834 f_init_raw(testcasename());
835
Pau Espin Pedrol2a45a502019-11-29 12:48:16 +0100836 f_pcuvty_set_allowed_cs_mcs();
837 f_pcuvty_set_link_quality_ranges();
838
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200839 /* Establish an Uplink TBF */
Pau Espin Pedrol6c1b4be2019-10-04 19:31:02 +0200840 ok := f_establish_tbf(rr_imm_ass);
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200841 if (not ok) {
Pau Espin Pedrol6c1b4be2019-10-04 19:31:02 +0200842 setverdict(fail, "Failed to establish TBF");
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200843 mtc.stop;
844 }
845
Pau Espin Pedrol6c1b4be2019-10-04 19:31:02 +0200846 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
847 if (not ok) {
848 setverdict(fail, "Immediate Assignment not an Uplink TBF");
Vadim Yanitskiy6276b6c2019-09-29 19:48:26 +0700849 mtc.stop;
850 }
851
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200852 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
853 tfi := ul_tbf_ass.dynamic.tfi_assignment,
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +0100854 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200855 bsn := 0, /* TODO: what should be here? */
856 blocks := { /* To be generated in loop */ });
857
858 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
859 ul_data.data.tlli := '00000001'O;
860
Vadim Yanitskiy26cd2442019-11-08 05:39:06 +0700861 /* The actual / old link quality values. We need to keep track of the old
862 * (basically previous) link quality value, because OsmoPCU actually
863 * changes the coding scheme if not only the actual, but also the old
864 * value leaves the current link quality range (window). */
865 var integer lqual := 0;
866 var integer lqual_old;
867
868 /* 16 UL blocks (0 .. 15 dB, step = 1 dB) */
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200869 for (var integer i := 0; i < 16; i := i + 1) {
870 /* Prepare a new UL block (CV, random payload) */
871 ul_data.data.mac_hdr.countdown := (15 - i);
872 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
873
Vadim Yanitskiy26cd2442019-11-08 05:39:06 +0700874 /* Update the old / actual link quality */
875 lqual_old := lqual;
876 lqual := i;
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200877
878 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
879 log("Sending DATA.ind with link quality (dB): ", lqual);
Pau Espin Pedrolc3a77322019-10-03 19:40:08 +0200880 f_tx_rlcmac_ul_block(ul_data, lqual * 10);
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200881
882 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100883 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200884
885 log("Rx Packet Uplink ACK / NACK with Channel Coding Command: ",
886 dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd);
887
Vadim Yanitskiy26cd2442019-11-08 05:39:06 +0700888 /* Match the received Channel Coding Command. Since we are increasing
889 * the link quality value on each iteration and not decreasing, there
890 * is no need to check the both old and current link quality values. */
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200891 var template ChCodingCommand ch_coding;
Vadim Yanitskiy26cd2442019-11-08 05:39:06 +0700892 select (lqual_old) {
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +0200893 case (CS1_lqual_dB_range) { ch_coding := CH_CODING_CS1; }
894 case (CS2_lqual_dB_range) { ch_coding := CH_CODING_CS2; }
895 case (CS3_lqual_dB_range) { ch_coding := CH_CODING_CS3; }
896 case (CS4_lqual_dB_range) { ch_coding := CH_CODING_CS4; }
897 }
898
899 if (not match(dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd, ch_coding)) {
900 setverdict(fail, "Channel Coding does not match our expectations: ", ch_coding);
901 } else {
902 setverdict(pass);
903 }
904 }
905}
906
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +0100907/* Test the max UL CS set by VTY works fine */
908testcase TC_cs_initial_ul() runs on RAW_PCU_Test_CT {
909 var GsmRrMessage rr_imm_ass;
910 var PacketUlAssign ul_tbf_ass;
911 var RlcmacDlBlock dl_block;
912 var boolean ok;
913 var integer lqual_cb;
914 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100915 var uint32_t unused_fn;
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +0100916
917 /* Initialize the PCU interface abstraction */
918 f_init_raw(testcasename());
919
920 /* Set initial UL CS to 3 */
921 g_cs_initial_ul := 3;
922 f_pcuvty_set_allowed_cs_mcs();
923 f_pcuvty_set_link_quality_ranges();
924
925 /* Take lqual (dB->cB) so that we stay in that CS */
926 lqual_cb := g_cs_lqual_ranges[2].low * 10;
927
928 /* Establish an Uplink TBF */
929 ok := f_establish_tbf(rr_imm_ass);
930 if (not ok) {
931 setverdict(fail, "Failed to establish TBF");
932 mtc.stop;
933 }
934
935 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
936 if (not ok) {
937 setverdict(fail, "Immediate Assignment not an Uplink TBF");
938 mtc.stop;
939 }
940
941 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
942 tfi := ul_tbf_ass.dynamic.tfi_assignment,
943 cv := 3, /* 8 UL blocks to be sent (to be overridden in loop) */
944 bsn := 0, /* TODO: what should be here? */
945 blocks := { /* To be generated in loop */ });
946
947 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
948 ul_data.data.tlli := '00000001'O;
949
950 /* 3 UL blocks, check we are in same initial CS: */
951 for (var integer i := 0; i < 3; i := i + 1) {
952 /* Prepare a new UL block (CV, random payload) */
953 ul_data.data.mac_hdr.countdown := (7 - i);
954 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
955
956 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
957 f_tx_rlcmac_ul_block(ul_data, lqual_cb);
958
959 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100960 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +0100961 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
962 }
963
964 if (last_ch_coding != CH_CODING_CS3) {
965 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
966 mtc.stop;
967 }
968
969 setverdict(pass);
970
971 /* Remaining UL blocks are used to make sure regardless of initial
972 /* lqual, we can go lower at any time */
973
974 /* 5 UL blocks, check we are in same initial CS: */
975 for (var integer i := 3; i < 8; i := i + 1) {
976 /* Prepare a new UL block (CV, random payload) */
977 ul_data.data.mac_hdr.countdown := (7 - i);
978 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
979
980 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
981 f_tx_rlcmac_ul_block(ul_data, 0); /* 0 dB, make sure we downgrade CS */
982
983 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
Pau Espin Pedrol7503c872019-12-05 12:55:08 +0100984 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +0100985
986 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
987 }
988
989 if (last_ch_coding != CH_CODING_CS1) {
990 setverdict(fail, "Channel Coding does not match our expectations (CS-1): ", last_ch_coding);
991 } else {
992 setverdict(pass);
993 }
994}
995
996/* Test the max UL CS set by VTY works fine */
997testcase TC_cs_max_ul() runs on RAW_PCU_Test_CT {
998 var GsmRrMessage rr_imm_ass;
999 var PacketUlAssign ul_tbf_ass;
1000 var RlcmacDlBlock dl_block;
1001 var boolean ok;
1002 var ChCodingCommand last_ch_coding;
Pau Espin Pedrol7503c872019-12-05 12:55:08 +01001003 var uint32_t unused_fn;
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +01001004
1005 /* Initialize the PCU interface abstraction */
1006 f_init_raw(testcasename());
1007
1008 /* Set maximum allowed UL CS to 3 */
1009 g_cs_max_ul := 3;
1010 f_pcuvty_set_allowed_cs_mcs();
1011 f_pcuvty_set_link_quality_ranges();
1012
1013 /* Establish an Uplink TBF */
1014 ok := f_establish_tbf(rr_imm_ass);
1015 if (not ok) {
1016 setverdict(fail, "Failed to establish TBF");
1017 mtc.stop;
1018 }
1019
1020 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1021 if (not ok) {
1022 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1023 mtc.stop;
1024 }
1025
1026 var template (value) RlcmacUlBlock ul_data := t_RLCMAC_UL_DATA(
1027 tfi := ul_tbf_ass.dynamic.tfi_assignment,
1028 cv := 15, /* 16 UL blocks to be sent (to be overridden in loop) */
1029 bsn := 0, /* TODO: what should be here? */
1030 blocks := { /* To be generated in loop */ });
1031
1032 /* HACK: patch missing TLLI; otherwise OsmoPCU rejects DATA.req */
1033 ul_data.data.tlli := '00000001'O;
1034
1035 /* 16 UL blocks */
1036 for (var integer i := 0; i < 16; i := i + 1) {
1037 /* Prepare a new UL block (CV, random payload) */
1038 ul_data.data.mac_hdr.countdown := (15 - i);
1039 ul_data.data.blocks := { valueof(t_RLCMAC_LLCBLOCK(f_rnd_octstring(10))) };
1040
1041 /* Enqueue DATA.ind (both TDMA frame and block numbers to be patched) */
1042 f_tx_rlcmac_ul_block(ul_data, 40*10); /* 40 dB */
1043
1044 /* Enqueue RTS.req, expect DATA.req with UL ACK from the PCU */
Pau Espin Pedrol7503c872019-12-05 12:55:08 +01001045 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +01001046
1047 last_ch_coding := dl_block.ctrl.payload.u.ul_ack_nack.gprs.ch_coding_cmd;
1048 }
1049
1050 if (last_ch_coding != CH_CODING_CS3) {
1051 setverdict(fail, "Channel Coding does not match our expectations (CS-3): ", last_ch_coding);
1052 } else {
1053 setverdict(pass);
1054 }
1055}
1056
Pau Espin Pedrol596faa42019-10-04 19:31:29 +02001057/* Verify PCU drops TBF after some time of inactivity. */
1058testcase TC_t3169() runs on RAW_PCU_Test_CT {
1059 var PCUIF_info_ind info_ind;
1060 var GsmRrMessage rr_imm_ass;
1061 var PacketUlAssign ul_tbf_ass;
1062 var RlcmacDlBlock dl_block;
1063 var PCUIF_Message pcu_msg;
1064 var octetstring data;
1065 var boolean ok;
Pau Espin Pedrol7503c872019-12-05 12:55:08 +01001066 var uint32_t unused_fn;
Pau Espin Pedrolcf47a922019-10-07 15:26:52 +02001067 var OCT4 tlli := '00000001'O;
1068
1069 /* Initialize NS/BSSGP side */
1070 f_init_bssgp();
Pau Espin Pedrol596faa42019-10-04 19:31:29 +02001071
1072 info_ind := valueof(ts_PCUIF_INFO_default);
1073 /* Set timer to 1 sec (default 5) to speedup test: */
1074 info_ind.t3169 := 1;
1075
1076 /* Initialize the PCU interface abstraction */
1077 f_init_raw(testcasename(), info_ind);
1078
Pau Espin Pedrolcf47a922019-10-07 15:26:52 +02001079 /* Establish BSSGP connection to the PCU */
1080 f_bssgp_establish();
1081 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1082
Pau Espin Pedrol596faa42019-10-04 19:31:29 +02001083 /* Establish an Uplink TBF */
1084 ok := f_establish_tbf(rr_imm_ass);
1085 if (not ok) {
1086 setverdict(fail, "Failed to establish TBF");
1087 mtc.stop;
1088 }
1089
1090 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1091 if (not ok) {
1092 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1093 mtc.stop;
1094 }
1095
1096 /* Send one UL block and make sure it is ACKED fine */
1097 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
Pau Espin Pedrol7503c872019-12-05 12:55:08 +01001098 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, unused_fn);
Pau Espin Pedrolcf47a922019-10-07 15:26:52 +02001099 /* UL block should be received in SGSN */
1100 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
Pau Espin Pedrol596faa42019-10-04 19:31:29 +02001101
1102 /* Wait until T3169 fires (plus 1 extra sec to make sure) */
1103 f_sleep(int2float(info_ind.t3169) + 1.0);
1104
1105 /* Send an UL block once again, the TBF should be gone by now so no ACK */
1106 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
1107 f_rx_rlcmac_dl_block_exp_dummy(dl_block);
1108}
1109
Pau Espin Pedrolff8da192019-12-05 17:23:58 +01001110/* Verify that a Downlink TBF can be assigned using PACCH shortly after the
1111 * release of prev DL TBF due to MS staying in PDCH for a while (T3192, in PCU
1112 * T3193) after DL TBF release */
1113testcase TC_t3193() runs on RAW_PCU_Test_CT {
1114 var GsmRrMessage rr_imm_ass;
1115 var PacketDlAssign dl_tbf_ass;
1116 var RlcmacDlBlock dl_block;
1117 var octetstring data := f_rnd_octstring(10);
1118 var boolean ok;
1119 var uint32_t sched_fn;
1120 var OCT4 tlli := '00000001'O;
1121 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1122
1123 /* Initialize NS/BSSGP side */
1124 f_init_bssgp();
1125
1126 /* Initialize the PCU interface abstraction */
1127 f_init_raw(testcasename());
1128
1129 /* Establish BSSGP connection to the PCU */
1130 f_bssgp_establish();
1131 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1132
1133 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1134 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1135 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1136 ok := f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1137 if (not ok) {
1138 setverdict(fail, "Immediate Assignment not a Downlink TBF");
1139 mtc.stop;
1140 }
1141 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1142 f_sleep(X2002);
1143 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0);
1144
1145 /* ACK the DL block */
1146 f_acknackdesc_ack_block(ack_nack_desc, dl_block.data.mac_hdr.hdr_ext.bsn, '1'B);
1147 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
1148 /* we are done with the DL-TBF here so far, let's clean up our local state: */
1149 ack_nack_desc := valueof(t_AckNackDescription_init)
1150
1151 /* Now that final DL block is ACKED and TBF is released, T3193 in PCU
1152 (T3192 in MS) was started and until it fires the MS will be abailable
1153 on PDCH in case new data arrives from SGSN. Let's verify it: */
1154 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1155 f_rx_rlcmac_dl_block_exp_pkt_ass(dl_block, sched_fn);
1156 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1157
1158 /* Now that we confirmed the new assignment in the dl-tbf, lets receive the data and ack it */
1159 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0);
1160 f_acknackdesc_ack_block(ack_nack_desc, dl_block.data.mac_hdr.hdr_ext.bsn, '1'B);
1161 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
1162}
1163
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001164/* Test scenario where MS wants to send some data on PDCH against SGSN and it is
1165 * answered, so TBFs for uplink and later for downlink are created.
1166 */
1167testcase TC_mo_ping_pong() runs on RAW_PCU_Test_CT {
1168 var GsmRrMessage rr_imm_ass;
1169 var PacketUlAssign ul_tbf_ass;
1170 var PacketDlAssign dl_tbf_ass;
1171 var RlcmacDlBlock dl_block;
1172 var PCUIF_Message pcu_msg;
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +01001173 var octetstring data := f_rnd_octstring(10);
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001174 var boolean ok;
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +01001175 var uint32_t sched_fn;
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001176 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol89486332019-12-05 14:05:46 +01001177 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001178
1179 /* Initialize NS/BSSGP side */
1180 f_init_bssgp();
1181
1182 /* Initialize the PCU interface abstraction */
1183 f_init_raw(testcasename());
1184
1185 /* Establish BSSGP connection to the PCU */
1186 f_bssgp_establish();
1187 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1188
1189 /* Establish an Uplink TBF */
1190 ok := f_establish_tbf(rr_imm_ass);
1191 if (not ok) {
1192 setverdict(fail, "Failed to establish TBF");
1193 mtc.stop;
1194 }
1195 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1196 if (not ok) {
1197 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1198 mtc.stop;
1199 }
1200
1201 /* Send one UL block and make sure it is ACKED fine */
1202 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
Pau Espin Pedrol7503c872019-12-05 12:55:08 +01001203 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1204 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1205 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001206
1207 /* UL block should be received in SGSN */
1208 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1209
1210 /* Now SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +01001211 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001212 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1213
1214 ok := f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1215 if (not ok) {
1216 setverdict(fail, "Immediate Assignment not a Downlink TBF");
1217 mtc.stop;
1218 }
1219
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +01001220 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1221 f_sleep(X2002);
Pau Espin Pedrol89486332019-12-05 14:05:46 +01001222 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0);
Pau Espin Pedrola3f0a852019-12-02 19:16:26 +01001223
1224 /* ACK the DL block */
Pau Espin Pedrol89486332019-12-05 14:05:46 +01001225 f_acknackdesc_ack_block(ack_nack_desc, dl_block.data.mac_hdr.hdr_ext.bsn, '1'B);
Pau Espin Pedrol65bab9e2019-12-04 21:05:10 +01001226 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001227}
Harald Welte9fbcf4b2018-12-07 07:56:52 +01001228
Pau Espin Pedrole7cabe62020-01-23 14:35:15 +01001229/* Test scenario where SGSN wants to send some data against MS and it is
1230 * answered by the MS on PDCH, so TBFs for downlink and later for uplink are created.
1231 */
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +01001232private function f_TC_mt_ping_pong(template (omit) MSRadioAccessCapabilityV_BSSGP ms_racap := omit, template (present) CodingScheme exp_cs_mcs := ?) runs on RAW_PCU_Test_CT {
Pau Espin Pedrole7cabe62020-01-23 14:35:15 +01001233 var GsmRrMessage rr_imm_ass;
1234 var PacketUlAssign ul_tbf_ass;
1235 var PacketDlAssign dl_tbf_ass;
1236 var RlcmacDlBlock dl_block;
1237 var PCUIF_Message pcu_msg;
1238 var octetstring data := f_rnd_octstring(10);
1239 var boolean ok;
1240 var uint32_t sched_fn;
1241 var OCT4 tlli := '00000001'O;
1242 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1243
1244 /* Initialize NS/BSSGP side */
1245 f_init_bssgp();
1246
1247 /* Initialize the PCU interface abstraction */
1248 f_init_raw(testcasename());
1249
1250 /* Establish BSSGP connection to the PCU */
1251 f_bssgp_establish();
1252 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1253
1254 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
Pau Espin Pedrol2422d1f2020-01-23 17:51:04 +01001255 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data, ms_racap));
Pau Espin Pedrole7cabe62020-01-23 14:35:15 +01001256 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1257
1258 ok := f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1259 if (not ok) {
1260 setverdict(fail, "Immediate Assignment not a Downlink TBF");
1261 mtc.stop;
1262 }
1263
1264 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1265 f_sleep(X2002);
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +01001266 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0, exp_cs_mcs);
Pau Espin Pedrole7cabe62020-01-23 14:35:15 +01001267
1268 /* ACK the DL block */
1269 f_acknackdesc_ack_block(ack_nack_desc, dl_block.data.mac_hdr.hdr_ext.bsn, '1'B);
1270 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
1271
1272 /* Now MS wants to answer the DL data, Establish an Uplink TBF */
1273 ok := f_establish_tbf(rr_imm_ass);
1274 if (not ok) {
1275 setverdict(fail, "Failed to establish TBF");
1276 mtc.stop;
1277 }
1278 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1279 if (not ok) {
1280 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1281 mtc.stop;
1282 }
1283
1284 /* Send one UL block and make sure it is ACKED fine */
1285 f_tx_rlcmac_ul_n_blocks(ul_tbf_ass, 1);
1286 f_rx_rlcmac_dl_block_exp_ack_nack(dl_block, sched_fn);
1287 /* DL ACK/NACK sets poll+rrbp requesting PACKET CONTROL ACK */
1288 f_tx_rlcmac_ul_block(ts_RLCMAC_CTRL_ACK(tlli), 0, sched_fn);
1289
1290 /* UL block should be received in SGSN */
1291 BSSGP[0].receive(tr_BSSGP_UL_UD(tlli, mp_gb_cfg.cell_id));
1292}
1293
Pau Espin Pedrol2422d1f2020-01-23 17:51:04 +01001294testcase TC_mt_ping_pong() runs on RAW_PCU_Test_CT {
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +01001295 var CodingScheme exp_cs_mcs := CS_1;
1296 f_TC_mt_ping_pong(omit, exp_cs_mcs);
Pau Espin Pedrol2422d1f2020-01-23 17:51:04 +01001297}
1298
1299/* TC_mt_ping_pong, but DL-UNITDATA contains RA Access capability with (M)CS
1300/* information about the MS */
1301testcase TC_mt_ping_pong_with_dl_racap() runs on RAW_PCU_Test_CT {
1302 var MultislotCap_GPRS_BSSGP mscap_gprs := {
1303 gprsmultislotclass := '00011'B,
1304 gprsextendeddynalloccap := '0'B
1305 } ;
1306 var MSRadioAccessCapabilityV_BSSGP ms_racap := { valueof(ts_RaCapRec_BSSGP('0001'B /* E-GSM */, mscap_gprs, omit)) };
Pau Espin Pedroldc9666f2020-03-18 20:30:16 +01001307 var CodingScheme exp_cs_mcs := CS_2;
1308 f_TC_mt_ping_pong(ms_racap, exp_cs_mcs);
Pau Espin Pedrol2422d1f2020-01-23 17:51:04 +01001309}
1310
Pau Espin Pedrola7b75662019-12-05 16:39:55 +01001311/* Verify that if PCU doesn't get an ACK for first DL block after IMM ASS, it
1312 * will retry by retransmitting both the IMM ASS + DL block after poll (ack)
1313 * timeout occurs (specified by sent RRBP on DL block). */
1314testcase TC_imm_ass_dl_block_retrans() runs on RAW_PCU_Test_CT {
1315 var GsmRrMessage rr_imm_ass;
1316 var PacketDlAssign dl_tbf_ass;
1317 var RlcmacDlBlock dl_block;
1318 var octetstring data := f_rnd_octstring(10);
1319 var boolean ok;
1320 var uint32_t sched_fn;
1321 var OCT4 tlli := '00000001'O;
1322 var AckNackDescription ack_nack_desc := valueof(t_AckNackDescription_init);
1323
1324 /* Initialize NS/BSSGP side */
1325 f_init_bssgp();
1326
1327 /* Initialize the PCU interface abstraction */
1328 f_init_raw(testcasename());
1329
1330 /* Establish BSSGP connection to the PCU */
1331 f_bssgp_establish();
1332 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1333
1334 /* SGSN sends some DL data, PCU will page on CCCH (PCH) */
1335 BSSGP[0].send(ts_BSSGP_DL_UD(tlli, data));
1336 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1337 ok := f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1338 if (not ok) {
1339 setverdict(fail, "Immediate Assignment not a Downlink TBF");
1340 mtc.stop;
1341 }
1342
1343 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1344 f_sleep(X2002);
1345 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0);
1346
1347 /* Now we don't ack the dl block (emulate MS failed receiveing IMM ASS
1348 * or GPRS DL, or DL ACK was lost for some reason). As a result, PCU
1349 * should retrigger IMM ASS + GPRS DL procedure after poll timeout. */
1350 f_pcuif_rx_pch_imm_tbf_ass(rr_imm_ass);
1351 ok := f_imm_ass_verify_dl_tbf_ass(rr_imm_ass, dl_tbf_ass);
1352 if (not ok) {
1353 setverdict(fail, "Immediate Assignment not a Downlink TBF");
1354 mtc.stop;
1355 }
1356 /* Wait timer X2002 and DL block is available after CCCH IMM ASS: */
1357 f_sleep(X2002);
1358 f_rx_rlcmac_dl_block_exp_data(dl_block, sched_fn, data, 0);
1359
1360 /* ACK the DL block */
1361 f_acknackdesc_ack_block(ack_nack_desc, dl_block.data.mac_hdr.hdr_ext.bsn, '1'B);
1362 f_tx_rlcmac_ul_block(ts_RLCMAC_DL_ACK_NACK(dl_block.data.mac_hdr.hdr_ext.tfi, ack_nack_desc), 0, sched_fn);
1363}
1364
Vadim Yanitskiy322c7932020-01-01 23:03:47 +01001365private function f_pkt_paging_match_imsi(in PacketPagingReq req, hexstring imsi) {
1366 var MobileIdentityLV_Paging mi_lv := req.repeated_pageinfo.cs.mobile_identity;
1367 var MobileIdentityV mi := dec_MobileIdentityV(mi_lv.mobile_id);
1368
1369 if (mi_lv.len != 8) { /* 8 octets: type of ID (3 bits) + even/odd flag (1 bit) + 15 BCD-encoded digits (60 bits) */
1370 setverdict(fail, "Mobile Identity length mismatch: ",
1371 "expected: 8, got: ", mi_lv.len);
1372 mtc.stop;
1373 }
1374
1375 /* Make sure MI contains IMSI before referencing it */
1376 if (mi.typeOfIdentity != '001'B) {
1377 setverdict(fail, "Mobile Identity must be of type IMSI ('001'B), ",
1378 "got: ", mi.typeOfIdentity);
1379 mtc.stop;
1380 } else if (mi.oddEvenInd_identity.imsi.digits != imsi) {
1381 setverdict(fail, "Mobile Identity contains unexpected IMSI, ",
1382 "expected: ", imsi, " got: ", mi.oddEvenInd_identity.imsi.digits);
1383 mtc.stop;
1384 }
1385}
1386
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001387private function f_pkt_paging_match_tmsi(in PacketPagingReq req, template GsmTmsi tmsi) {
1388 if (not match(req.repeated_pageinfo.cs.tmsi, tmsi)) {
1389 setverdict(fail, "Mobile Identity (TMSI/P-TMSI) mismatch: ",
1390 "expected: ", tmsi, "got: ", req.repeated_pageinfo.cs.tmsi);
1391 mtc.stop;
1392 }
1393}
1394
Oliver Smith8f9daab2019-10-09 09:27:19 +02001395/* Test CS paging over the BTS<->PCU socket.
1396 * 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.
1397 * Paging should be send on the PACCH.
1398 *
1399 * 1. Send a Paging Request over PCU socket.
1400 * 2. Send a Ready-To-Send message over PCU socket
1401 * 3. Expect a Paging Frame
1402 */
1403testcase TC_paging_cs_from_bts() runs on RAW_PCU_Test_CT {
1404 var GsmRrMessage rr_imm_ass;
1405 var PacketUlAssign ul_tbf_ass;
1406 var RlcmacDlBlock dl_block;
1407 var boolean ok;
1408 var OCT4 tlli := '00000001'O;
Vadim Yanitskiy98bb2d52020-03-28 00:57:21 +07001409 var MobileIdentityLV mi;
Oliver Smith8f9daab2019-10-09 09:27:19 +02001410 var octetstring mi_enc_lv;
Oliver Smith8f9daab2019-10-09 09:27:19 +02001411 var hexstring imsi := f_gen_imsi(42);
1412
1413 /* Initialize NS/BSSGP side */
1414 f_init_bssgp();
1415
1416 /* Initialize the PCU interface abstraction */
1417 f_init_raw(testcasename());
1418
1419 /* Establish BSSGP connection to the PCU */
1420 f_bssgp_establish();
1421 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1422
1423 /* Establish an Uplink TBF */
1424 ok := f_establish_tbf(rr_imm_ass);
1425 if (not ok) {
1426 setverdict(fail, "Failed to establish TBF");
1427 mtc.stop;
1428 }
1429
1430 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1431 if (not ok) {
1432 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1433 mtc.stop;
1434 }
1435
1436
1437 /* build mobile Identity */
1438 mi := valueof(ts_MI_IMSI_LV(imsi));
1439 mi_enc_lv := enc_MobileIdentityLV(mi);
1440 /* Send paging request */
1441 BTS.send(ts_PCUIF_PAG_REQ(bts_nr := 0, id_lv := mi_enc_lv, chan_needed := 0,
1442 sapi :=PCU_IF_SAPI_PDTCH));
1443
1444 /* Receive it on BTS side towards MS */
1445 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
Vadim Yanitskiy5e518732020-01-01 21:27:18 +01001446
Vadim Yanitskiy322c7932020-01-01 23:03:47 +01001447 /* Make sure that Packet Paging Request contains the same IMSI */
1448 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1449
Oliver Smith8f9daab2019-10-09 09:27:19 +02001450 setverdict(pass);
1451}
1452
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001453/* Test CS paging over Gb (SGSN->PCU->BTS[PDCH]).
1454 */
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001455private function f_tc_paging_cs_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1456runs on RAW_PCU_Test_CT {
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001457 var GsmRrMessage rr_imm_ass;
1458 var PacketUlAssign ul_tbf_ass;
1459 var RlcmacDlBlock dl_block;
1460 var boolean ok;
1461 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001462 var hexstring imsi := f_gen_imsi(42);
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001463 var GsmTmsi tmsi;
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001464
1465 /* Initialize NS/BSSGP side */
1466 f_init_bssgp();
1467
1468 /* Initialize the PCU interface abstraction */
1469 f_init_raw(testcasename());
1470
1471 /* Establish BSSGP connection to the PCU */
1472 f_bssgp_establish();
1473 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1474
1475 /* Establish an Uplink TBF */
1476 ok := f_establish_tbf(rr_imm_ass);
1477 if (not ok) {
1478 setverdict(fail, "Failed to establish TBF");
1479 mtc.stop;
1480 }
1481
1482 ok := f_imm_ass_verify_ul_tbf_ass(rr_imm_ass, ul_tbf_ass);
1483 if (not ok) {
1484 setverdict(fail, "Immediate Assignment not an Uplink TBF");
1485 mtc.stop;
1486 }
1487
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001488 /* Send paging request with or without TMSI */
1489 if (use_ptmsi) {
1490 tmsi := oct2int(f_rnd_octstring(4)); /* Random P-TMSI */
1491 BSSGP[0].send(ts_BSSGP_CS_PAGING_PTMSI(bvci, imsi, tmsi));
1492 } else {
1493 BSSGP[0].send(ts_BSSGP_CS_PAGING_IMSI(bvci, imsi));
1494 }
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001495
1496 /* Receive it on BTS side towards MS */
1497 f_rx_rlcmac_dl_block_exp_pkt_pag_req(dl_block);
1498
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001499 /* Make sure that Packet Paging Request contains the same P-TMSI/IMSI */
1500 if (use_ptmsi) {
1501 f_pkt_paging_match_tmsi(dl_block.ctrl.payload.u.paging, tmsi);
1502 } else {
1503 f_pkt_paging_match_imsi(dl_block.ctrl.payload.u.paging, imsi);
1504 }
Vadim Yanitskiy322c7932020-01-01 23:03:47 +01001505
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001506 setverdict(pass);
1507}
1508
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001509testcase TC_paging_cs_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1510 f_tc_paging_cs_from_sgsn(0, true);
1511}
1512
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001513testcase TC_paging_cs_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1514 f_tc_paging_cs_from_sgsn(0);
1515}
1516
1517testcase TC_paging_cs_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1518 f_tc_paging_cs_from_sgsn(mp_gb_cfg.bvci);
1519}
1520
1521/* Test PS paging over Gb (SGSN->PCU->BTS[CCCH]).
1522 */
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001523private function f_tc_paging_ps_from_sgsn(Nsvci bvci, boolean use_ptmsi := false)
1524runs on RAW_PCU_Test_CT {
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001525 var OCT4 tlli := '00000001'O;
Pau Espin Pedrol925818a2020-01-02 14:06:51 +01001526 var integer imsi_suff_tx := 423;
1527 var hexstring imsi := f_gen_imsi(imsi_suff_tx);
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001528
1529 /* Initialize NS/BSSGP side */
1530 f_init_bssgp();
1531
1532 /* Initialize the PCU interface abstraction */
1533 f_init_raw(testcasename());
1534
1535 /* Establish BSSGP connection to the PCU */
1536 f_bssgp_establish();
1537 f_bssgp_client_llgmm_assign('FFFFFFFF'O, tlli);
1538
Vadim Yanitskiy9c513132020-03-28 04:33:07 +07001539 /* Send BSSGP PAGING-PS (with or without TMSI), wait for RR Paging Request Type 1.
1540 * Make sure that both paging group (IMSI suffix) and Mobile Identity match. */
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001541 if (use_ptmsi) {
Vadim Yanitskiy9c513132020-03-28 04:33:07 +07001542 var OCT4 tmsi := f_rnd_octstring(4); /* Random P-TMSI */
1543 BSSGP[0].send(ts_BSSGP_PS_PAGING_PTMSI(bvci, imsi, oct2int(tmsi)));
1544 f_pcuif_rx_pch_pag_req1(t_MI_TMSI(tmsi), imsi_suff_tx);
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001545 } else {
1546 BSSGP[0].send(ts_BSSGP_PS_PAGING_IMSI(bvci, imsi));
Vadim Yanitskiy9c513132020-03-28 04:33:07 +07001547 f_pcuif_rx_pch_pag_req1(tr_MI_IMSI(imsi), imsi_suff_tx);
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001548 }
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001549
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001550 setverdict(pass);
1551}
1552
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001553testcase TC_paging_ps_from_sgsn_sign_ptmsi() runs on RAW_PCU_Test_CT {
1554 f_tc_paging_ps_from_sgsn(0, true);
1555}
1556
Pau Espin Pedrol88bf5372019-12-09 21:12:28 +01001557testcase TC_paging_ps_from_sgsn_sign() runs on RAW_PCU_Test_CT {
1558 f_tc_paging_ps_from_sgsn(0);
1559}
1560
1561testcase TC_paging_ps_from_sgsn_ptp() runs on RAW_PCU_Test_CT {
1562 f_tc_paging_ps_from_sgsn(mp_gb_cfg.bvci);
1563}
1564
Harald Welte9fbcf4b2018-12-07 07:56:52 +01001565control {
Harald Welte7fd25cf2019-03-21 22:14:02 +01001566 execute( TC_pcuif_suspend() );
Vadim Yanitskiy1f72b0a2019-10-01 05:58:45 +07001567 execute( TC_ta_ptcch_idle() );
Vadim Yanitskiy3e1d3182019-09-11 16:53:45 +02001568 execute( TC_ta_rach_imm_ass() );
Vadim Yanitskiy02f77d82019-10-04 17:12:35 +07001569 execute( TC_ta_ptcch_ul_multi_tbf() );
Vadim Yanitskiy0eb26622019-09-14 20:35:28 +02001570 execute( TC_cs_lqual_ul_tbf() );
Pau Espin Pedrol3eef95c2019-11-29 14:07:24 +01001571 execute( TC_cs_initial_ul() );
1572 execute( TC_cs_max_ul() );
Pau Espin Pedrol596faa42019-10-04 19:31:29 +02001573 execute( TC_t3169() );
Pau Espin Pedrolff8da192019-12-05 17:23:58 +01001574 execute( TC_t3193() );
Pau Espin Pedrol1755fab2019-10-08 11:18:54 +02001575 execute( TC_mo_ping_pong() );
Pau Espin Pedrole7cabe62020-01-23 14:35:15 +01001576 execute( TC_mt_ping_pong() );
Pau Espin Pedrol2422d1f2020-01-23 17:51:04 +01001577 execute( TC_mt_ping_pong_with_dl_racap() );
Pau Espin Pedrola7b75662019-12-05 16:39:55 +01001578 execute( TC_imm_ass_dl_block_retrans() );
Oliver Smith8f9daab2019-10-09 09:27:19 +02001579 execute( TC_paging_cs_from_bts() );
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001580 execute( TC_paging_cs_from_sgsn_sign_ptmsi() );
Vadim Yanitskiycca15a32020-03-24 21:27:00 +07001581 execute( TC_paging_cs_from_sgsn_sign() );
1582 execute( TC_paging_cs_from_sgsn_ptp() );
Vadim Yanitskiy7b224212020-03-26 02:43:55 +07001583 execute( TC_paging_ps_from_sgsn_sign_ptmsi() );
Vadim Yanitskiycca15a32020-03-24 21:27:00 +07001584 execute( TC_paging_ps_from_sgsn_sign() );
1585 execute( TC_paging_ps_from_sgsn_ptp() );
Harald Welte9fbcf4b2018-12-07 07:56:52 +01001586}
1587
1588
1589
1590
1591
1592
1593}