blob: cbe6bad7c52a0b6f9b675e911307ae7ffc014c36 [file] [log] [blame]
Harald Welte28d943e2017-11-25 15:00:50 +01001module BSC_Tests {
2
Harald Welte21b46bd2017-12-17 19:46:32 +01003/* Integration Tests for OsmoBSC
Harald Weltea0630032018-03-20 21:09:55 +01004 * (C) 2017-2018 by Harald Welte <laforge@gnumonks.org>
Harald Welte21b46bd2017-12-17 19:46:32 +01005 * All rights reserved.
6 *
7 * Released under the terms of GNU General Public License, Version 2 or
8 * (at your option) any later version.
9 *
Harald Welte34b5a952019-05-27 11:54:11 +020010 * SPDX-License-Identifier: GPL-2.0-or-later
11 *
Harald Welte21b46bd2017-12-17 19:46:32 +010012 * This test suite tests OsmoBSC while emulating both multiple BTS + MS as
13 * well as the MSC. See README for more details.
14 *
15 * There are test cases that run in so-called 'handler mode' and test cases
16 * that run directly on top of the BSSAP and RSL CodecPorts. The "handler mode"
17 * tests abstract the multiplexing/demultiplexing of multiple SCCP connections
18 * and/or RSL channels and are hence suitable for higher-level test cases, while
19 * the "raw" tests directly on top of the CodecPorts are more suitable for lower-
20 * level testing.
21 */
22
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +020023friend module BSC_Tests_VAMOS;
24
Neels Hofmeyr4f118412020-06-04 15:25:10 +020025import from Misc_Helpers all;
Harald Welte4003d112017-12-09 22:35:39 +010026import from General_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010027import from Osmocom_Types all;
Harald Welteae026692017-12-09 01:03:01 +010028import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +010029import from IPL4asp_Types all;
30
Harald Welte6f521d82017-12-11 19:52:02 +010031import from BSSAP_Types all;
Harald Welte6811d102019-04-14 22:23:14 +020032import from RAN_Adapter all;
Harald Welte47cd0e32020-08-21 12:39:11 +020033import from BSSAP_LE_Adapter all;
34import from BSSAP_LE_CodecPort all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020035import from BSSAP_LE_Types all;
36import from BSSLAP_Types all;
Harald Welteae026692017-12-09 01:03:01 +010037import from BSSAP_CodecPort all;
38import from BSSMAP_Templates all;
Harald Welte28d943e2017-11-25 15:00:50 +010039import from IPA_Emulation all;
Stefan Sperling830dc9d2018-02-12 21:08:28 +010040import from IPA_CodecPort all;
Harald Welteae026692017-12-09 01:03:01 +010041import from IPA_Types all;
Stefan Sperling0796a822018-10-05 13:01:39 +020042import from IPA_Testing all;
Harald Welteae026692017-12-09 01:03:01 +010043import from RSL_Types all;
Harald Welte624f9632017-12-16 19:26:04 +010044import from RSL_Emulation all;
Daniel Willmann191e0d92018-01-17 12:44:35 +010045import from MGCP_Emulation all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010046import from MGCP_Templates all;
47import from MGCP_Types all;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +020048import from MGCP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010049
Harald Welte96c94412017-12-09 03:12:45 +010050import from Osmocom_CTRL_Functions all;
Harald Weltea5d2ab22017-12-09 14:21:42 +010051import from Osmocom_CTRL_Types all;
Harald Welteffe55fc2018-01-17 22:39:54 +010052import from Osmocom_CTRL_Adapter all;
Harald Welte96c94412017-12-09 03:12:45 +010053
Daniel Willmannebdecc02020-08-12 15:30:17 +020054import from StatsD_Types all;
55import from StatsD_CodecPort all;
56import from StatsD_CodecPort_CtrlFunct all;
57import from StatsD_Checker all;
58
Harald Weltebc03c762018-02-12 18:09:38 +010059import from Osmocom_VTY_Functions all;
60import from TELNETasp_PortType all;
61
Harald Welte6f521d82017-12-11 19:52:02 +010062import from MobileL3_CommonIE_Types all;
Harald Weltee3bd6582018-01-31 22:51:25 +010063import from MobileL3_Types all;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010064import from MobileL3_RRM_Types all;
Harald Welte6f521d82017-12-11 19:52:02 +010065import from L3_Templates all;
66import from GSM_RR_Types all;
67
Stefan Sperlingc307e682018-06-14 15:15:46 +020068import from SCCP_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010069import from BSSMAP_Templates all;
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020070import from BSSMAP_LE_Templates all;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010071
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010072import from SCCPasp_Types all;
73
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020074import from GSM_SystemInformation all;
75import from GSM_RestOctets all;
Neels Hofmeyrad132f22020-07-08 02:20:16 +020076import from TCCConversion_Functions all;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020077
Harald Welte5d1a2202017-12-13 19:51:29 +010078const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020079const integer NUM_BTS_CFG := 4; /* we have 4 BTS in the osmo-bsc.cfg (for inter-BSC HO tests) but use only 3 */
Neels Hofmeyrf246a922020-05-13 02:27:10 +020080const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010081const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010082
Harald Welte799c97b2017-12-14 17:50:30 +010083/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020084const integer NUM_TCHH_PER_BTS := 2;
85const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020086const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010087
Harald Welte4003d112017-12-09 22:35:39 +010088
Harald Welte21b46bd2017-12-17 19:46:32 +010089/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +010090type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +010091 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +010092 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +010093}
94
Neels Hofmeyr22c3f792020-06-17 02:49:28 +020095/* Default list of counters for an 'msc' entity. */
96const CounterNameVals counternames_msc_mscpool := {
97 { "mscpool:subscr:new", 0 },
98 { "mscpool:subscr:known", 0 },
99 { "mscpool:subscr:reattach", 0 },
100 { "mscpool:subscr:attach_lost", 0 },
101 { "mscpool:subscr:paged", 0 }
102};
103
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000104/* List of global mscpool counters, not related to a specific 'msc' entity. */
105const CounterNameVals counternames_bsc_mscpool := {
106 { "mscpool:subscr:no_msc", 0 }
107};
108
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000109/* Default list of counters for 'bsc' and 'bts' entities. */
110const CounterNameVals counternames_bsc_bts_handover := {
111 { "assignment:attempted", 0 },
112 { "assignment:completed", 0 },
113 { "assignment:stopped", 0 },
114 { "assignment:no_channel", 0 },
115 { "assignment:timeout", 0 },
116 { "assignment:failed", 0 },
117 { "assignment:error", 0 },
118
119 { "handover:attempted", 0 },
120 { "handover:completed", 0 },
121 { "handover:stopped", 0 },
122 { "handover:no_channel", 0 },
123 { "handover:timeout", 0 },
124 { "handover:failed", 0 },
125 { "handover:error", 0 },
126
127 { "intra_cell_ho:attempted", 0 },
128 { "intra_cell_ho:completed", 0 },
129 { "intra_cell_ho:stopped", 0 },
130 { "intra_cell_ho:no_channel", 0 },
131 { "intra_cell_ho:timeout", 0 },
132 { "intra_cell_ho:failed", 0 },
133 { "intra_cell_ho:error", 0 },
134
135 { "intra_bsc_ho:attempted", 0 },
136 { "intra_bsc_ho:completed", 0 },
137 { "intra_bsc_ho:stopped", 0 },
138 { "intra_bsc_ho:no_channel", 0 },
139 { "intra_bsc_ho:timeout", 0 },
140 { "intra_bsc_ho:failed", 0 },
141 { "intra_bsc_ho:error", 0 },
142
143 { "interbsc_ho_out:attempted", 0 },
144 { "interbsc_ho_out:completed", 0 },
145 { "interbsc_ho_out:stopped", 0 },
146 { "interbsc_ho_out:timeout", 0 },
147 { "interbsc_ho_out:failed", 0 },
148 { "interbsc_ho_out:error", 0 },
149
150 { "interbsc_ho_in:attempted", 0 },
151 { "interbsc_ho_in:completed", 0 },
152 { "interbsc_ho_in:stopped", 0 },
153 { "interbsc_ho_in:no_channel", 0 },
154 { "interbsc_ho_in:timeout", 0 },
155 { "interbsc_ho_in:failed", 0 },
156 { "interbsc_ho_in:error", 0 }
157};
158
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200159/* Set of all System Information received during one RSL port's startup.
160 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
161 * broadcast that SI type. That will be reflected as 'omit' here.
162 */
163type record SystemInformationConfig {
164 SystemInformationType1 si1 optional,
165 SystemInformationType2 si2 optional,
166 SystemInformationType2bis si2bis optional,
167 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200168 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200169 SystemInformationType3 si3 optional,
170 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100171 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200172 SystemInformationType5 si5 optional,
173 SystemInformationType5bis si5bis optional,
174 SystemInformationType5ter si5ter optional,
175 SystemInformationType6 si6 optional
176};
177
178const SystemInformationConfig SystemInformationConfig_omit := {
179 si1 := omit,
180 si2 := omit,
181 si2bis := omit,
182 si2ter := omit,
183 si2quater := omit,
184 si3 := omit,
185 si4 := omit,
186 si13 := omit,
187 si5 := omit,
188 si5bis := omit,
189 si5ter := omit,
190 si6 := omit
191};
192
193/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
194template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
195 template uint3_t meas_bw := 3)
196:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
197 meas_bw_presence := '1'B,
198 meas_bw := meas_bw);
199
200/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200201template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200202 template uint3_t prio := 3,
203 template (present) uint5_t thresh_high := 20,
204 template uint5_t thresh_low := 10,
205 template uint5_t qrxlevmin := 22)
206:= tr_EUTRAN_NeighbourCells(
207 cell_desc_list := cell_desc_list,
208 prio_presence := '1'B,
209 prio := prio,
210 thresh_high := thresh_high,
211 thresh_low_presence := '1'B,
212 thresh_low := thresh_low,
213 qrxlevmin_presence := '1'B,
214 qrxlevmin := qrxlevmin);
215
216template SystemInformationConfig SystemInformationConfig_default := {
217 si1 := {
218 cell_chan_desc := '8FB38000000000000000000000000000'O,
219 rach_control := {
220 max_retrans := RACH_MAX_RETRANS_7,
221 tx_integer := '1001'B,
222 cell_barr_access := false,
223 re_not_allowed := true,
224 acc := '0000010000000000'B
225 },
226 rest_octets := ?
227 },
228 si2 := {
229 bcch_freq_list := '00000000000000000000000000000000'O,
230 ncc_permitted := '11111111'B,
231 rach_control := {
232 max_retrans := RACH_MAX_RETRANS_7,
233 tx_integer := '1001'B,
234 cell_barr_access := false,
235 re_not_allowed := true,
236 acc := '0000010000000000'B
237 }
238 },
239 si2bis := omit,
240 si2ter := {
241 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
242 rest_octets := ?
243 },
244 si2quater := {
245 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
246 },
247 si3 := {
248 cell_id := 0,
249 lai := {
250 mcc_mnc := '001F01'H,
251 lac := 1
252 },
253 ctrl_chan_desc := {
254 msc_r99 := true,
255 att := true,
256 bs_ag_blks_res := 1,
257 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
258 si22ind := false,
259 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
260 spare := '00'B,
261 bs_pa_mfrms := 3,
262 t3212 := 30
263 },
264 cell_options := {
265 dn_ind := false,
266 pwrc := false,
267 dtx := MS_SHALL_USE_UL_DTX,
268 radio_link_tout_div4 := 7
269 },
270 cell_sel_par := {
271 cell_resel_hyst_2dB := 2,
272 ms_txpwr_max_cch := 7,
273 acs := '0'B,
274 neci := true,
275 rxlev_access_min := 0
276 },
277 rach_control := {
278 max_retrans := RACH_MAX_RETRANS_7,
279 tx_integer := '1001'B,
280 cell_barr_access := false,
281 re_not_allowed := true,
282 acc := '0000010000000000'B
283 },
284 rest_octets := {
285 sel_params := {
286 presence := '0'B,
287 params := omit
288 },
289 pwr_offset := {
290 presence := '0'B,
291 offset := omit
292 },
293 si_2ter_ind := '1'B,
294 early_cm_ind := '0'B,
295 sched_where := {
296 presence := '0'B,
297 where := omit
298 },
299 gprs_ind := {
300 presence := '1'B,
301 ind := {
302 ra_colour := 0,
303 si13_pos := '0'B
304 }
305 },
306 umts_early_cm_ind := '1'B,
307 si2_quater_ind := {
308 presence := '1'B,
309 ind := '0'B
310 },
311 iu_mode_ind := omit,
312 si21_ind := {
313 presence := '0'B,
314 pos := omit
315 }
316 }
317 },
318 si4 := {
319 lai := {
320 mcc_mnc := '001F01'H,
321 lac := 1
322 },
323 cell_sel_par := {
324 cell_resel_hyst_2dB := 2,
325 ms_txpwr_max_cch := 7,
326 acs := '0'B,
327 neci := true,
328 rxlev_access_min := 0
329 },
330 rach_control := {
331 max_retrans := RACH_MAX_RETRANS_7,
332 tx_integer := '1001'B,
333 cell_barr_access := false,
334 re_not_allowed := true,
335 acc := '0000010000000000'B
336 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200337 cbch_chan_desc := {
338 iei := '64'O,
339 v := {
340 chan_nr := {
341 u := {
342 sdcch4 := {
343 tag := '001'B,
344 sub_chan := 2
345 }
346 },
347 tn := 0
348 },
349 tsc := 2,
350 h := false,
351 arfcn := 871,
352 maio_hsn := omit
353 }
354 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200355 cbch_mobile_alloc := omit,
356 rest_octets := {
357 sel_params := {
358 presence := '0'B,
359 params := omit
360 },
361 pwr_offset := {
362 presence := '0'B,
363 offset := omit
364 },
365 gprs_ind := {
366 presence := '1'B,
367 ind := {
368 ra_colour := 0,
369 si13_pos := '0'B
370 }
371 },
372 s_presence := '0'B,
373 s := omit
374 }
375 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100376 si13 := {
377 rest_octets := {
378 presence := '1'B,
379 bcch_change_mark := ?,
380 si_change_field := '0000'B,
381 presence2 := '0'B,
382 si13_change_mark := omit,
383 gprs_ma := omit,
384 zero := '0'B, /* PBCCH not present in cell */
385 rac := 0,
386 spgc_ccch_sup := '0'B,
387 priority_access_thr := '110'B,
388 network_control_order := '00'B,
389 gprs_cell_opts := {
390 nmo := '01'B,
391 t3168 := '011'B,
392 t3192 := '010'B,
393 drx_timer_max := '011'B,
394 access_burst_type := '0'B,
395 control_ack_type := '1'B,
396 bs_cv_max := 15,
397 pan_presence := '1'B,
398 pan_dec := 1,
399 pan_inc := 1,
400 pan_max := '111'B,
401 ext_info_presence := ?,
402 ext_info_length := *,
403 ext_info := *
404 },
405 gprs_pwr_ctrl_params := {
406 alpha := 0,
407 t_avg_w := '10000'B,
408 t_avg_t := '10000'B,
409 pc_meas_chan := '0'B,
410 n_avg_i := '1000'B
411 }
412 }
413 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200414 si5 := {
415 bcch_freq_list := '10000000000000000000000000000000'O
416 },
417 si5bis := omit,
418 si5ter := {
419 extd_bcch_freq_list := '9E050020000000000000000000000000'O
420 },
421 si6 := {
422 cell_id := 0,
423 lai := {
424 mcc_mnc := '001F01'H,
425 lac := 1
426 },
427 cell_options := {
428 dtx_ext := '1'B,
429 pwrc := false,
430 dtx := '01'B,
431 radio_link_timeout := '0111'B
432 },
433 ncc_permitted := '11111111'B,
434 rest_octets := ?
435 }
436 };
437
438
439/* List of all the System Information received on all RSL ports */
440type record of SystemInformationConfig SystemInformationConfig_list;
441
442function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
443{
444 var RSL_IE_Body sysinfo_type_ie;
445 var RSL_IE_SysinfoType si_type;
446 var octetstring data;
447
448 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
449 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
450 mtc.stop;
451 }
452 si_type := sysinfo_type_ie.sysinfo_type;
453
454 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
455 var RSL_IE_Body bcch_ie;
456 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
457 data := bcch_ie.other.payload;
458 }
459 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
460 var RSL_IE_Body l3_ie;
461 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
462 data := l3_ie.l3_info.payload;
463 }
464 } else {
465 setverdict(fail, "Don't understand this System Information message");
466 mtc.stop;
467 }
468
469 var boolean handled := false;
470
471 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
472 handled := true;
473
474 if (si_type == RSL_SYSTEM_INFO_1) {
475 if (not isbound(data)) {
476 si.si1 := omit;
477 } else {
478 si.si1 := dec_SystemInformation(data).payload.si1;
479 }
480 } else if (si_type == RSL_SYSTEM_INFO_2) {
481 if (not isbound(data)) {
482 si.si2 := omit;
483 } else {
484 si.si2 := dec_SystemInformation(data).payload.si2;
485 }
486 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
487 if (not isbound(data)) {
488 si.si2bis := omit;
489 } else {
490 si.si2bis := dec_SystemInformation(data).payload.si2bis;
491 }
492 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
493 if (not isbound(data)) {
494 si.si2ter := omit;
495 } else {
496 si.si2ter := dec_SystemInformation(data).payload.si2ter;
497 }
498 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
499 if (not isbound(data)) {
500 si.si2quater := {};
501 } else {
502 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
503 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
504 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
505 }
506 } else if (si_type == RSL_SYSTEM_INFO_3) {
507 if (not isbound(data)) {
508 si.si3 := omit;
509 } else {
510 si.si3 := dec_SystemInformation(data).payload.si3;
511 }
512 } else if (si_type == RSL_SYSTEM_INFO_4) {
513 if (not isbound(data)) {
514 si.si4 := omit;
515 } else {
516 si.si4 := dec_SystemInformation(data).payload.si4;
517 }
518 } else if (si_type == RSL_SYSTEM_INFO_13) {
519 if (not isbound(data)) {
520 si.si13 := omit;
521 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100522 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200523 }
524 } else {
525 handled := false;
526 }
527 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
528 handled := true;
529
530 if (si_type == RSL_SYSTEM_INFO_5) {
531 if (not isbound(data)) {
532 si.si5 := omit;
533 } else {
534 si.si5 := dec_SystemInformation(data).payload.si5;
535 }
536 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
537 if (not isbound(data)) {
538 si.si5bis := omit;
539 } else {
540 si.si5bis := dec_SystemInformation(data).payload.si5bis;
541 }
542 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
543 if (not isbound(data)) {
544 si.si5ter := omit;
545 } else {
546 si.si5ter := dec_SystemInformation(data).payload.si5ter;
547 }
548 } else if (si_type == RSL_SYSTEM_INFO_6) {
549 if (not isbound(data)) {
550 si.si6 := omit;
551 } else {
552 si.si6 := dec_SystemInformation(data).payload.si6;
553 }
554 } else {
555 handled := false;
556 }
557 }
558
559 if (not handled) {
560 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
561 }
562}
563
Harald Weltea4ca4462018-02-09 00:17:14 +0100564type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100565 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100566 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100567 /* RSL common Channel Port (for RSL_Emulation) */
568 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100569 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100570 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100571 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200572 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
573 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100574
Daniel Willmann191e0d92018-01-17 12:44:35 +0100575 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100576 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100577
Daniel Willmannebdecc02020-08-12 15:30:17 +0200578 /* StatsD */
579 var StatsD_Checker_CT vc_STATSD;
580
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200581 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200582 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100583 /* for old legacy-tests only */
584 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200585 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100586
Harald Welte21b46bd2017-12-17 19:46:32 +0100587 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100588 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100589
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200590 /* Osmux is enabled through VTY */
591 var boolean g_osmux_enabled := false;
592
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100593 /*Configure T(tias) over VTY, seconds */
594 var integer g_bsc_sccp_timer_ias := 7 * 60;
595 /*Configure T(tiar) over VTY, seconds */
596 var integer g_bsc_sccp_timer_iar := 15 * 60;
597
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200598 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100599 timer T_guard := 30.0;
600
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200601 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000602 var CounterNameValsList g_ctr_bsc;
603 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200604
605 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
606 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100607}
608
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200609type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100610modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100611 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100612 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100613 /* port number to which to establish the IPA OML connections */
614 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100615 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100616 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100617 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100618 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200619 /* port number to which to listen for STATSD metrics */
620 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100621 /* IP address at which the test binds */
622 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100623
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200624 RAN_Configurations mp_bssap_cfg := {
625 {
626 transport := BSSAP_TRANSPORT_AoIP,
627 sccp_service_type := "mtp3_itu",
628 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
629 own_pc := 185, /* 0.23.1 first MSC emulation */
630 own_ssn := 254,
631 peer_pc := 187, /* 0.23.3 osmo-bsc */
632 peer_ssn := 254,
633 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200634 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200635 },
636 {
637 transport := BSSAP_TRANSPORT_AoIP,
638 sccp_service_type := "mtp3_itu",
639 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
640 own_pc := 2, /* 0.0.2 second MSC emulation */
641 own_ssn := 254,
642 peer_pc := 187, /* 0.23.3 osmo-bsc */
643 peer_ssn := 254,
644 sio := '83'O,
645 rctx := 2
646 },
647 {
648 transport := BSSAP_TRANSPORT_AoIP,
649 sccp_service_type := "mtp3_itu",
650 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
651 own_pc := 3, /* 0.0.3 third MSC emulation */
652 own_ssn := 254,
653 peer_pc := 187, /* 0.23.3 osmo-bsc */
654 peer_ssn := 254,
655 sio := '83'O,
656 rctx := 3
657 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100658 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200659
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200660 /* Must match per BTS config in osmo-bsc.cfg */
661 phys_chan_configs phys_chan_config := {
662 "CCCH+SDCCH4+CBCH",
663 "TCH/F",
664 "TCH/F",
665 "TCH/F",
666 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600667 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200668 "PDCH",
669 "PDCH"
670 };
671
Harald Welte47cd0e32020-08-21 12:39:11 +0200672 BSSAP_LE_Configuration mp_bssap_le_cfg := {
673 sccp_service_type := "mtp3_itu",
674 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200675 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200676 own_ssn := 252, /* SMLC side SSN */
677 peer_pc := 187, /* 0.23.3 osmo-bsc */
678 peer_ssn := 250, /* BSC side SSN */
679 sio := '83'O,
680 rctx := 6
681 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200682 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200683
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +0200684 /* Whether to enable dyn TS SDCCH8 tests. Can be dropped completely and enable
685 unconditionally once new version of osmo-bsc is released (current
686 version: 1.7.0) */
687 boolean mp_enable_dyn_sdcch8_test := true;
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100688 /* Value set in osmo-bsc.cfg "ms max power" */
689 uint8_t mp_exp_ms_power_level := 7;
Harald Weltea4ca4462018-02-09 00:17:14 +0100690}
691
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200692friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200693
694 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200695 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200696 pars.aoip := true;
697 } else {
698 pars.aoip := false;
699 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100700 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200701 pars.mscpool.bssap_idx := bssap_idx;
Philipp Maier48604732018-10-09 15:00:37 +0200702
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200703 /* BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2 */
704 pars.expect_tsc := 2;
705
Philipp Maier48604732018-10-09 15:00:37 +0200706 return pars;
707}
708
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200709/* Convenience functions for rate counters using g_ctr_msc. */
710
711private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
712 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
713 log("initial msc rate counters: ", g_ctr_msc);
714}
715
716private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200717 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200718}
719
720/* f_ctrs_msc_init();
721 * f_do_thing(on_msc := 0);
722 * f_do_thing(on_msc := 0);
723 * f_do_other(on_msc := 1);
724 * f_ctrs_msc_add(0, "thing", 2);
725 * f_ctrs_msc_add(1, "other");
726 * f_ctrs_msc_verify();
727 */
728private function f_ctrs_msc_verify() runs on test_CT {
729 log("verifying msc rate counters: ", g_ctr_msc);
730 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
731}
732
733/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
734 * f_ctrs_msc_init();
735 * f_do_thing(on_msc := 0);
736 * f_do_thing(on_msc := 0);
737 * f_do_thing(on_msc := 0);
738 * f_ctrs_msc_expect(0, "thing", 3);
739 */
740private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
741 f_ctrs_msc_add(msc_nr, countername, val);
742 f_ctrs_msc_verify();
743}
744
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000745/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
746
747private function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
748 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
749 log("initial bts rate counters: ", g_ctr_bts);
750 f_ctrs_bsc_init(counternames);
751}
752
753private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
754 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
755 f_ctrs_bsc_add(countername, val);
756}
757
758/* f_ctrs_bsc_and_bts_init();
759 * f_do_thing(on_bts := 0);
760 * f_do_thing(on_bts := 0);
761 * f_do_other(on_bts := 1);
762 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
763 * f_ctrs_bsc_and_bts_add(1, "other");
764 * f_ctrs_bsc_and_bts_verify();
765 */
766private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
767 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
768 f_ctrs_bsc_verify();
769}
770
771/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
772 * f_ctrs_bsc_and_bts_init();
773 * f_do_thing(on_bts := 0);
774 * f_do_thing(on_bts := 0);
775 * f_do_thing(on_bts := 0);
776 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
777 */
778private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
779 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
780 f_ctrs_bsc_and_bts_verify();
781}
782
783
784/* Convenience functions for rate counters using g_ctr_bsc. */
785
786private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
787 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
788 log("initial bsc rate counters: ", g_ctr_bsc);
789}
790
791private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
792 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
793}
794
795/* f_ctrs_bsc_init();
796 * f_do_thing();
797 * f_do_thing();
798 * f_do_other();
799 * f_ctrs_bsc_add("thing", 2);
800 * f_ctrs_bsc_add("other");
801 * f_ctrs_bsc_verify();
802 */
803private function f_ctrs_bsc_verify() runs on test_CT {
804 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
805}
806
807/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
808 * f_ctrs_bsc_init();
809 * f_do_thing();
810 * f_ctrs_bsc_expect("thing", 1);
811 */
812private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
813 f_ctrs_bsc_add(countername, val);
814 f_ctrs_bsc_verify();
815}
816
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200817
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200818friend function f_shutdown_helper() runs on test_CT {
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200819 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100820 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200821 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100822}
823
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200824private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100825 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200826 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100827 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200828 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
829 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100830 T.start;
831 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200832 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
833 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200834 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100835 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200836 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200837 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100838 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200839 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200840 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100841 repeat;
842 }
843 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200844 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200845 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200846 /* If we received a RESET after ours was sent, it
847 may be a race condition where the other peer beacame
848 available after we sent it, but we are in a desired
849 state anyway, so go forward. */
850 if (not reset_received) {
851 setverdict(fail);
852 }
853 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100854 }
Harald Welte28d943e2017-11-25 15:00:50 +0100855}
856
Harald Welteae026692017-12-09 01:03:01 +0100857type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100858 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100859 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100860 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100861 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100862 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100863 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100864 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100865 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100866}
867
Harald Welte21b46bd2017-12-17 19:46:32 +0100868/*! Start the IPA/RSL related bits for one IPA_Client.
869 * \param clnt IPA_Client for which to establish
870 * \param bsc_host IP address / hostname of the BSC
871 * \param bsc_port TCP port number of the BSC
872 * \param i number identifying this BTS
873 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100874function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
875 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100876runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100877 timer T := 10.0;
878
Harald Welte96c94412017-12-09 03:12:45 +0100879 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welteae026692017-12-09 01:03:01 +0100880 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA");
881 clnt.ccm_pars := c_IPA_default_ccm_pars;
882 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
883 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100884 if (handler_mode) {
885 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL");
Harald Welte89ab1912018-02-23 18:56:29 +0100886 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100887 }
Harald Welteae026692017-12-09 01:03:01 +0100888
889 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Harald Welte624f9632017-12-16 19:26:04 +0100890 if (handler_mode) {
891 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
892 } else {
893 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
894 }
Harald Welteae026692017-12-09 01:03:01 +0100895
Harald Welte5d1a2202017-12-13 19:51:29 +0100896 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100897 if (handler_mode) {
898 clnt.vc_RSL.start(RSL_Emulation.main());
899 return;
900 }
Harald Welteae026692017-12-09 01:03:01 +0100901
902 /* wait for IPA RSL link to connect and send ID ACK */
903 T.start;
904 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700905 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100906 T.stop;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700907 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100908 }
Harald Welte60e823a2017-12-10 14:10:59 +0100909 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100910 [] IPA_RSL[i].receive { repeat }
911 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100912 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200913 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100914 }
915 }
916}
917
Harald Welte12055472018-03-17 20:10:08 +0100918function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
919 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
920 return;
921 }
922 clnt.vc_IPA.stop;
923 if (isbound(clnt.vc_RSL)) {
924 clnt.vc_RSL.stop;
925 }
926}
927
Harald Welte21b46bd2017-12-17 19:46:32 +0100928/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100929function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
930 timer T := secs_max;
931 T.start;
932 while (true) {
933 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
934 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +0100935 /* the 'degraded' state exists from OML connection time, and we have to wait
936 * until all MO's are initialized */
937 T.start(1.0);
938 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100939 return;
940 }
Harald Weltef0d6ac62017-12-17 17:02:21 +0100941 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +0100942 if (not T.running) {
Max99253902018-11-16 17:57:39 +0100943 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +0200944 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100945 }
946 }
947}
948
Harald Welte21b46bd2017-12-17 19:46:32 +0100949/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +0100950altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +0100951 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100952 [] T_guard.timeout {
953 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +0200954 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +0100955 }
Harald Welte60e823a2017-12-10 14:10:59 +0100956 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200957 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +0100958 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200959 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +0100960 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +0100961 }
Harald Welte28d943e2017-11-25 15:00:50 +0100962}
963
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100964altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200965 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100966 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +0200967 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +0100968 }
969}
970
Daniel Willmann191e0d92018-01-17 12:44:35 +0100971function f_init_mgcp(charstring id) runs on test_CT {
972 id := id & "-MGCP";
973
974 var MGCPOps ops := {
975 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
976 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
977 };
978 var MGCP_conn_parameters mgcp_pars := {
979 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +0100980 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +0100981 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +0200982 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +0200983 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
984 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200985 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +0100986 };
987
988 vc_MGCP := MGCP_Emulation_CT.create(id);
989 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
990}
991
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200992/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
993 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
994 * OsmuxCID IE.
995 */
996private function f_vty_allow_osmux(boolean allow) runs on test_CT {
997 f_vty_enter_cfg_msc(BSCVTY, 0);
998 if (allow) {
999 f_vty_transceive(BSCVTY, "osmux on");
1000 } else {
1001 f_vty_transceive(BSCVTY, "osmux off");
1002 }
1003 f_vty_transceive(BSCVTY, "exit");
1004 f_vty_transceive(BSCVTY, "exit");
1005 g_osmux_enabled := allow;
1006}
1007
Max2253c0b2018-11-06 19:28:05 +01001008function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001009 if (BSCVTY.checkstate("Mapped")) {
1010 /* skip initialization if already executed once */
1011 return;
1012 }
Harald Weltebc03c762018-02-12 18:09:38 +01001013 map(self:BSCVTY, system:BSCVTY);
1014 f_vty_set_prompts(BSCVTY);
1015 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001016 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1017 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001018}
1019
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001020friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001021{
1022 // log on TTCN3 log output
1023 log(log_msg);
1024 // log in stderr log
Neels Hofmeyr767548a2020-08-09 20:26:07 +00001025 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001026}
1027
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001028private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1029{
1030 if (rsl_idx >= lengthof(g_system_information)) {
1031 g_system_information[rsl_idx] := SystemInformationConfig_omit
1032 }
1033 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1034}
1035
1036altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1037 var ASP_RSL_Unitdata rx_rsl_ud;
1038
1039 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1040 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1041 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1042 repeat;
1043 }
1044 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1045 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1046 repeat;
1047 }
1048 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1049 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1050 repeat;
1051 }
1052 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1053 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1054 repeat;
1055 }
1056
1057 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1058 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1059 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1060 repeat;
1061 }
1062 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1063 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1064 repeat;
1065 }
1066 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1067 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1068 repeat;
1069 }
1070 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1071 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1072 repeat;
1073 }
1074}
1075
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001076/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1077private type record of boolean my_BooleanList;
1078
1079private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1080{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001081 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1082
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001083 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001084 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1085 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1086 * stepping into that config node. */
1087 log("msc ", msc_nr, " is not configured, skipping");
1088 continue;
1089 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001090 f_vty_enter_cfg_msc(pt, msc_nr);
1091 if (allow_attach_list[msc_nr]) {
1092 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1093 f_vty_transceive(pt, "allow-attach", strict := false);
1094 } else {
1095 f_vty_transceive(pt, "no allow-attach", strict := false);
1096 }
1097 f_vty_transceive(pt, "exit");
1098 f_vty_transceive(pt, "exit");
1099 }
1100}
1101
Harald Welte21b46bd2017-12-17 19:46:32 +01001102/* global initialization function
1103 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001104 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1105 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1106 */
1107function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001108 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001109 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001110
Harald Welteae026692017-12-09 01:03:01 +01001111 if (g_initialized) {
1112 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001113 }
Harald Welteae026692017-12-09 01:03:01 +01001114 g_initialized := true;
1115
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001116 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001117 activate(as_Tguard());
1118
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001119 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001120 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001121
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001122 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001123 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1124
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001125 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1126 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1127 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1128 }
1129
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001130 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001131 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001132 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1133 * MSC-side BSSAP emulation */
1134 if (handler_mode) {
1135 var RanOps ranops := MSC_RanOps;
1136 ranops.use_osmux := g_osmux_enabled;
1137 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1138 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1139 f_ran_adapter_start(g_bssap[bssap_idx]);
1140 } else {
1141 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1142 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1143 f_ran_adapter_start(g_bssap[bssap_idx]);
1144 f_legacy_bssap_reset();
1145 }
Harald Welte67089ee2018-01-17 22:19:03 +01001146 }
Harald Welted5833a82018-05-27 16:52:56 +02001147
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001148 if (mp_enable_lcs_tests) {
1149 if (handler_mode) {
1150 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1151 } else {
1152 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1153 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1154 }
1155 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001156 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001157
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001158 /* start the test with exactly all enabled MSCs allowed to attach */
1159 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1160
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001161 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001162
Daniel Willmann191e0d92018-01-17 12:44:35 +01001163 f_init_mgcp("VirtMSC");
1164
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001165 for (var integer i := 0; i < nr_bts; i := i+1) {
1166 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001167 }
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001168}
Harald Welte696ddb62017-12-08 14:01:43 +01001169
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001170function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1171runs on test_CT {
1172 /* wait until osmo-bts-omldummy has respawned */
1173 f_wait_oml(bts_idx, "degraded", 5.0);
1174
1175 /* start RSL connection */
1176 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1177 /* wait until BSC tells us "connected" */
1178 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001179}
1180
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001181function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1182 template SystemInformationConfig expect_si)
1183runs on test_CT {
1184 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1185
1186 f_init_bts(bts_idx, handler_mode);
1187
1188 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1189 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1190 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1191 */
1192 f_sleep(5.0);
1193 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1194
1195 deactivate(sysinfo);
1196
1197 if (match(g_system_information[bts_idx], expect_si)) {
1198 setverdict(pass);
1199 } else {
1200 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1201 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1202 setverdict(fail, "received SI does not match expectations");
1203 return;
1204 }
1205}
1206
Maxd4e56962018-10-31 19:08:25 +01001207/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001208function f_exp_ipa_rx(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001209runs on test_CT return RSL_Message {
1210 var ASP_RSL_Unitdata rx_rsl_ud;
1211 timer T := t_secs;
1212
1213 T.start;
1214 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001215 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001216 T.stop;
1217 }
1218 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001219 [] T.timeout {
1220 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001221 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001222 }
Harald Welteae026692017-12-09 01:03:01 +01001223 }
1224 return rx_rsl_ud.rsl;
1225}
1226
Harald Welte21b46bd2017-12-17 19:46:32 +01001227/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001228function f_ipa_tx(integer bts_nr, template (value) RSL_Message t_tx, IpaStreamId sid := IPAC_PROTO_RSL_TRX0)
Harald Welteae026692017-12-09 01:03:01 +01001229runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001230 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001231}
1232
1233
Harald Welte4003d112017-12-09 22:35:39 +01001234/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001235testcase TC_chan_act_noreply() runs on test_CT {
1236 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001237 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001238
Harald Welte89d42e82017-12-17 16:42:41 +01001239 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001240
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001241 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001242 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001243 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001244}
1245
Harald Welte4003d112017-12-09 22:35:39 +01001246/* verify if the "chreq:total" counter increments as expected */
1247testcase TC_chan_act_counter() runs on test_CT {
1248 var BSSAP_N_UNITDATA_ind ud_ind;
1249 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001250 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001251
Harald Welte89d42e82017-12-17 16:42:41 +01001252 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001253
1254 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001255 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001256 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Harald Welte4003d112017-12-09 22:35:39 +01001257 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total", chreq_total+1);
1258
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001259 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001260}
1261
Harald Welteae026692017-12-09 01:03:01 +01001262/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001263private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001264 var RSL_Message rx_rsl;
1265
Harald Welteae026692017-12-09 01:03:01 +01001266 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001267 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001268
1269 /* expect BSC to disable the channel again if there's no RLL EST IND */
1270 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1271
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001272 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001273}
1274
Philipp Maier9c60a622020-07-09 15:08:46 +02001275/* Normal variant */
1276testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001277 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001278 f_TC_chan_act_ack_noest();
1279}
1280
1281/* Emergency call variant */
1282testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1283 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001284 f_init(1);
1285 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001286 f_TC_chan_act_ack_noest(ra := 'A5'O);
1287}
1288
Philipp Maier606f07d2020-08-12 17:21:58 +02001289/* Emergency call variant, but emergency calls are not allowed */
1290testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1291 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1292
1293 var RSL_Message rx_rsl;
1294 var GsmRrMessage rr;
1295
1296 f_init(1);
1297 f_vty_allow_emerg_bts(false, 0);
1298
1299 IPA_RSL[0].clear;
1300 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1301
1302 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1303 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1304 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1305 setverdict(pass);
1306 } else {
1307 setverdict(fail, "immediate assignment not rejected");
1308 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001309
1310 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001311}
1312
Harald Welteae026692017-12-09 01:03:01 +01001313/* Test behavior if MSC never answers to CR */
1314testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001315 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1316 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001317 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001318 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001319
Harald Welte89d42e82017-12-17 16:42:41 +01001320 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001321
1322 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001323 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001324
1325 var octetstring l3 := '00010203040506'O
1326 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1327
1328 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1329
1330 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001331 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001332 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001333 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001334}
1335
1336/* Test behavior if MSC answers with CREF to CR */
1337testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1338 var BSSAP_N_CONNECT_ind rx_c_ind;
1339 var RSL_Message rx_rsl;
1340
Harald Welte89d42e82017-12-17 16:42:41 +01001341 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001342
1343 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001344 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001345
1346 var octetstring l3 := '00010203040506'O
1347 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1348
1349 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1350 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1351
1352 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001353 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001354 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001355}
1356
Harald Welte618ef642017-12-14 14:58:20 +01001357/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1358testcase TC_chan_act_nack() runs on test_CT {
1359 var RSL_Message rx_rsl;
1360 var integer chact_nack;
1361
Harald Welte89d42e82017-12-17 16:42:41 +01001362 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001363
1364 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1365
1366 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1367 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1368 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1369
1370 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1371
1372 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1373 f_sleep(0.5);
1374
1375 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1376
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001377 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001378}
1379
Harald Welte799c97b2017-12-14 17:50:30 +01001380/* Test for channel exhaustion due to RACH overload */
1381testcase TC_chan_exhaustion() runs on test_CT {
1382 var ASP_RSL_Unitdata rsl_ud;
1383 var integer i;
1384 var integer chreq_total, chreq_nochan;
1385
Harald Welte89d42e82017-12-17 16:42:41 +01001386 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001387
1388 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1389 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1390
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001391 /* GSM 04.08 Table 9.9a:
1392 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1393 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001394 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001395 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001396 }
1397
1398 IPA_RSL[0].clear;
1399
Harald Weltedd8cbf32018-01-28 12:07:52 +01001400 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001401 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001402
1403 /* now expect additional channel activations to fail */
1404 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1405
1406 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001407 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001408 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1409 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001410 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001411 var GsmRrMessage rr;
1412 /* match on IMM ASS REJ */
1413 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1414 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1415 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001416 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001417 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1418 chreq_nochan+1);
1419 setverdict(pass);
1420 } else {
1421 repeat;
1422 }
1423 }
1424 [] IPA_RSL[0].receive { repeat; }
1425 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001426 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001427}
1428
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001429/* Test channel deactivation due to silence from MS */
1430testcase TC_chan_deact_silence() runs on test_CT {
1431 var RslChannelNr chan_nr;
1432
1433 f_init(1);
1434
1435 /* Request for a dedicated channel */
1436 chan_nr := f_chreq_act_ack('23'O);
1437
1438 /* Wait some time until the channel is released */
1439 f_sleep(2.0);
1440
1441 /* Expect CHANnel RELease */
1442 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001443 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001444 log("Received CHANnel RELease");
1445 setverdict(pass);
1446 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001447 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001448 /* See OS#3709, OsmoBSC should not send Immediate
1449 * Assignment Reject since a dedicated channel was
1450 * already allocated, and Immediate Assignment was
1451 * already sent. */
1452 setverdict(fail, "Unexpected Immediate Assignment!");
1453 }
1454 [] IPA_RSL[0].receive {
1455 setverdict(fail, "Unexpected RSL message!");
1456 }
1457 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001458 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001459}
1460
Harald Weltecfe2c962017-12-15 12:09:32 +01001461/***********************************************************************
1462 * Assignment Testing
1463 ***********************************************************************/
1464
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001465/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1466 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001467testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001468 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001469
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001470 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1471 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001472 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001473 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001474}
1475
Harald Welte16a4adf2017-12-14 18:54:01 +01001476/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001477testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001478 var BSSAP_N_CONNECT_ind rx_c_ind;
1479 var RSL_Message rx_rsl;
1480 var DchanTuple dt;
1481
Harald Welte89d42e82017-12-17 16:42:41 +01001482 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001483
1484 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001485 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001486 /* send assignment without AoIP IEs */
1487 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1488 } else {
1489 /* Send assignmetn without CIC in IPA case */
1490 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1491 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1492 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1493 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001494 alt {
1495 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1496 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1497 }
Harald Welte235ebf12017-12-15 14:18:16 +01001498 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001499 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1500 setverdict(pass);
1501 }
1502 [] BSSAP.receive { repeat; }
1503 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001504 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001505}
1506
Harald Welteed848512018-05-24 22:27:58 +02001507/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001508function f_gen_ass_req(boolean osmux_enabled := false, integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4") return PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001509 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001510 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001511 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001512 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001513 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001514 if (osmux_enabled) {
1515 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1516 } else {
1517 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1518 }
Harald Welteed848512018-05-24 22:27:58 +02001519 } else {
1520 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001521 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001522 }
1523 return ass_cmd;
1524}
1525
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001526function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001527 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1528 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001529 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001530
1531 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1532 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1533 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1534 var template BSSMAP_IE_KC128 kc128 := omit;
1535 if (ispresent(enc)) {
1536 var TestHdlrEncrParams v_enc := valueof(enc);
1537 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg));
1538 chosenEncryptionAlgorithm := valueof(
1539 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
Oliver Smith598e1ed2021-07-09 10:28:40 +02001540 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg)), 1)));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001541 if (ispresent(v_enc.enc_kc128)) {
1542 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1543 }
1544 }
1545
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001546 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001547 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001548 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001549 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla, oldToNewBSSIEs := oldToNewBSSIEs,
1550 encryptionInformation := encryptionInformation,
1551 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1552 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001553 } else {
1554 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001555 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit, oldToNewBSSIEs := oldToNewBSSIEs,
1556 encryptionInformation := encryptionInformation,
1557 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1558 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001559 }
1560 return ho_req;
1561}
1562
Harald Welteed848512018-05-24 22:27:58 +02001563/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001564function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001565 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001566 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001567 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001568 if (expect_osmux) {
1569 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1570 } else {
1571 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1572 }
Harald Welteed848512018-05-24 22:27:58 +02001573 } else {
1574 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001575 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001576 }
1577 return exp_compl;
1578}
1579
Harald Welte235ebf12017-12-15 14:18:16 +01001580/* Run everything required up to sending a caller-specified assignment command and expect response */
1581function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
1582runs on test_CT {
1583 var BSSAP_N_CONNECT_ind rx_c_ind;
1584 var RSL_Message rx_rsl;
1585 var DchanTuple dt;
1586
Harald Welte89d42e82017-12-17 16:42:41 +01001587 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001588
1589 dt := f_est_dchan('23'O, 23, '00000000'O);
1590 /* send assignment without AoIP IEs */
1591 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1592 alt {
1593 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1594 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1595 setverdict(pass);
1596 } else {
1597 setverdict(fail, fail_text);
1598 }
1599 }
1600 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1601 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1602 setverdict(pass);
1603 } else {
1604 setverdict(fail, fail_text);
1605 }
1606 }
1607 [] BSSAP.receive { repeat; }
1608 }
1609}
1610testcase TC_assignment_csd() runs on test_CT {
1611 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001612 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001613 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1614 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1615 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001616 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001617}
1618
1619testcase TC_assignment_ctm() runs on test_CT {
1620 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001621 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001622 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1623 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
1624 f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001625 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001626}
1627
Harald Welte4003d112017-12-09 22:35:39 +01001628type record DchanTuple {
1629 integer sccp_conn_id,
1630 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001631}
1632
Harald Welted6939652017-12-13 21:02:46 +01001633/* Send CHAN RQD and wait for allocation; acknowledge it */
1634private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1635runs on test_CT return RslChannelNr {
1636 var RSL_Message rx_rsl;
1637 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1638 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1639 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1640 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001641 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001642 return chan_nr;
1643}
1644
Harald Welte4003d112017-12-09 22:35:39 +01001645/* helper function to establish a dedicated channel via BTS and MSC */
1646function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1647runs on test_CT return DchanTuple {
1648 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001649 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001650
Harald Welte4003d112017-12-09 22:35:39 +01001651 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001652 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001653
1654 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1655
1656 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1657 dt.sccp_conn_id := rx_c_ind.connectionId;
1658 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1659
1660 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001661}
1662
Harald Welte641fcbe2018-06-14 10:58:35 +02001663/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1664private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1665 var RSL_Message rx_rsl;
1666 /* expect BSC to disable the channel */
1667 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1668 /* respond with CHAN REL ACK */
1669 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1670
1671 /* expect Clear Complete from BSC */
1672 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1673
1674 /* MSC disconnects as instructed. */
1675 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1676}
1677
Harald Welte4003d112017-12-09 22:35:39 +01001678/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1679testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001680 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001681 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001682
Harald Welte89d42e82017-12-17 16:42:41 +01001683 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001684
Harald Welte4003d112017-12-09 22:35:39 +01001685 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1686
1687 /* simulate RLL REL IND */
1688 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1689
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001690 /* expect Clear Request on MSC side */
1691 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1692
1693 /* Instruct BSC to clear channel */
1694 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1695 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1696
Harald Welte4003d112017-12-09 22:35:39 +01001697 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001698 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001699
1700 /* wait for SCCP emulation to do its job */
1701 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001702
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001703 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001704}
1705
1706/* Test behavior of channel release after CONN FAIL IND from BTS */
1707testcase TC_chan_rel_conn_fail() runs on test_CT {
1708 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001709 var DchanTuple dt;
1710
Harald Welte89d42e82017-12-17 16:42:41 +01001711 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001712
1713 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1714
1715 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001716 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
Harald Welte4003d112017-12-09 22:35:39 +01001717 /* TODO: different cause values? */
1718
Harald Welte4003d112017-12-09 22:35:39 +01001719 /* expect Clear Request from BSC */
1720 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1721
1722 /* Instruct BSC to clear channel */
1723 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1724 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1725
Harald Welte6ff76ea2018-01-28 13:08:01 +01001726 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001727 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001728
1729 /* wait for SCCP emulation to do its job */
1730 f_sleep(1.0);
1731
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001732 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001733}
1734
Harald Welte99f3ca02018-06-14 13:40:29 +02001735/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1736/* See also https://www.osmocom.org/issues/3182 */
1737testcase TC_early_conn_fail() runs on test_CT {
1738 var RSL_Message rx_rsl;
1739 var DchanTuple dt;
1740
1741 f_init(1);
1742
1743 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001744 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001745
1746 /* BTS->BSC: simulate CONN FAIL IND */
1747 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1748
1749 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1750 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1751
1752 /* BTS<-BSC: respond with CHAN REL ACK */
1753 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1754
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001755 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001756}
1757
1758/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1759/* See also https://www.osmocom.org/issues/3182 */
1760testcase TC_late_conn_fail() runs on test_CT {
1761 var RSL_Message rx_rsl;
1762 var DchanTuple dt;
1763
1764 f_init(1);
1765
1766 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1767
1768 /* BSC<-MSC: Instruct BSC to clear connection */
1769 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1770
1771 /* BTS->BSC: expect BSC to deactivate SACCH */
1772 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1773
1774 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1775 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1776
1777 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1778 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1779 /* BTS->BSC: respond with CHAN REL ACK */
1780 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1781
1782 /* BSC->MSC: expect Clear Complete from BSC */
1783 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1784
1785 /* BSC<-MSC: MSC disconnects as requested. */
1786 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1787
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001788 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001789}
1790
Oliver Smithaf03bef2021-08-24 15:34:51 +02001791private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1792 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1793 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1794
1795 f_statsd_reset();
1796
1797 /* Establish SDCCH */
1798 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1799 f_establish_fully(ass_cmd, exp_fail);
1800
1801 /* Expect stats to be 0 */
1802 var StatsDExpects expect := {
1803 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1804 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1805 };
1806 f_statsd_expect(expect);
1807
1808 /* Simulate CONN FAIL IND on SDCCH */
1809 RSL.send(ts_ASP_RSL_UD(
1810 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
1811 IPAC_PROTO_RSL_TRX0));
1812
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02001813 f_sleep(1.0);
1814
Oliver Smithaf03bef2021-08-24 15:34:51 +02001815 /* Expect stats to be 1 */
1816 expect := {
1817 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
1818 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
1819 };
1820 f_statsd_expect(expect);
1821}
1822testcase TC_stats_conn_fail() runs on test_CT {
1823 var TestHdlrParams pars := f_gen_test_hdlr_pars();
1824 var MSC_ConnHdlr vc_conn;
1825
1826 f_init(1, true);
1827 f_sleep(1.0);
1828
1829 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
1830 vc_conn.done;
1831
1832 f_shutdown_helper();
1833}
1834
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01001835function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001836 boolean expect_deact_sacch := true,
1837 boolean expect_rr_chan_rel := true,
1838 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01001839 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001840 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001841 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001842 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01001843
1844 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001845 var boolean got_deact_sacch := false;
1846 var boolean got_rr_chan_rel := false;
1847 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001848 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001849 var RSL_IE_Body l3_ie;
1850 var PDU_ML3_NW_MS l3;
1851 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001852 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
1853 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01001854 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001855 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001856 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001857 repeat;
1858 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001859 [not istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE_CellSelectInd))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01001860 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001861
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001862 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1863 setverdict(fail, "cannot find L3");
1864 mtc.stop;
1865 }
1866 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1867
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001868 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001869 var CellSelIndValue cells := dec_CellSelIndValue(
1870 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
1871
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001872 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
1873 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001874 setverdict(pass);
1875 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02001876 log("EXPECTED CELLS: ", expect_cells);
1877 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02001878 }
1879 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001880
1881 if (not istemplatekind(expect_rr_cause, "omit")) {
1882 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1883 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1884 if (match(got_cause, expect_rr_cause)) {
1885 setverdict(pass);
1886 } else {
1887 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1888 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1889 }
1890 }
Harald Welte99787102019-02-04 10:41:36 +01001891 repeat;
1892 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001893 [istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001894 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02001895
1896 if (not istemplatekind(expect_rr_cause, "omit")) {
1897 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
1898 setverdict(fail, "cannot find L3");
1899 mtc.stop;
1900 }
1901 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
1902
1903 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
1904 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
1905 if (match(got_cause, expect_rr_cause)) {
1906 setverdict(pass);
1907 } else {
1908 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
1909 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
1910 }
1911 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01001912 repeat;
1913 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001914 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001915 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01001916 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001917 if (handle_rll_rel) {
1918 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
1919 }
Harald Welte91d54a52018-01-28 15:35:07 +01001920 repeat;
1921 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001922 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001923 /* respond with CHAN REL ACK */
1924 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
1925 }
1926 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001927 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01001928 repeat;
1929 }
1930 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001931
1932 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
1933 " got_rll_rel_req=", got_rll_rel_req);
1934
1935 if (expect_deact_sacch != got_deact_sacch) {
1936 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
1937 }
1938 if (expect_rr_chan_rel != got_rr_chan_rel) {
1939 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
1940 }
1941 if (expect_rll_rel_req != got_rll_rel_req) {
1942 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
1943 }
Harald Welte91d54a52018-01-28 15:35:07 +01001944}
1945
Harald Welte4003d112017-12-09 22:35:39 +01001946/* Test behavior of channel release after hard Clear Command from MSC */
1947testcase TC_chan_rel_hard_clear() runs on test_CT {
1948 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001949 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01001950
Harald Welte89d42e82017-12-17 16:42:41 +01001951 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001952
1953 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1954
1955 /* Instruct BSC to clear channel */
1956 var BssmapCause cause := 0;
1957 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1958
1959 /* expect Clear Complete from BSC on A */
1960 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1961 /* release the SCCP connection */
1962 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1963 }
1964
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001965 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001966 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001967}
1968
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02001969function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
1970 var BSSAP_N_DATA_ind rx_di;
1971 var DchanTuple dt;
1972
1973 f_init(1);
1974
1975 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1976 /* Send CommonID with some random PLMN (BSC doesn't take it into account
1977 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
1978 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
1979
1980 /* Instruct BSC to clear channel */
1981 var BssmapCause cause := 0;
1982 if (tx_csfb_ind) {
1983 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
1984 } else {
1985 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1986 }
1987
1988 /* expect Clear Complete from BSC on A */
1989 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
1990 /* release the SCCP connection */
1991 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1992 }
1993
1994 /* 1 neighbor is added by default in osmo-bts.cfg and
1995 SystemInformationConfig_default, use that: */
1996 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
1997
1998 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
1999 f_shutdown_helper();
2000}
2001
2002/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2003 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2004 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2005 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2006 Indicator or not shouldn't matter at all. */
2007testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2008 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2009}
2010
2011/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2012 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2013 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2014 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2015testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2016 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2017}
2018
2019/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2020 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2021 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2022 CSFB Indicator should not be used anymore, and hence, there should be no
2023 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2024 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002025testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2026 var BSSAP_N_DATA_ind rx_di;
2027 var DchanTuple dt;
2028
2029 f_init(1);
2030
2031 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2032
2033 /* Instruct BSC to clear channel */
2034 var BssmapCause cause := 0;
2035 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2036
2037 /* expect Clear Complete from BSC on A */
2038 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2039 /* release the SCCP connection */
2040 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2041 }
2042
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002043 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002044 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002045}
2046
Harald Welted8c36cd2017-12-09 23:05:31 +01002047/* Test behavior of channel release after hard RLSD from MSC */
2048testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002049 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002050
Harald Welte89d42e82017-12-17 16:42:41 +01002051 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002052
2053 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2054
2055 /* release the SCCP connection */
2056 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2057
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002058 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002059 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002060}
2061
Harald Welte550daf92018-06-11 19:22:13 +02002062/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2063testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2064 var DchanTuple dt;
2065
2066 f_init(1);
2067
2068 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2069
2070 /* release the SCCP connection */
2071 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2072
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002073 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002074 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002075}
2076
Harald Welte85804d42017-12-10 14:11:58 +01002077/* Test behavior of channel release after BSSMAP RESET from MSC */
2078testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002079 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002080
Harald Welte89d42e82017-12-17 16:42:41 +01002081 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002082
2083 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2084
2085 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2086 IPA_RSL[0].clear;
2087
2088 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002089 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Welte85804d42017-12-10 14:11:58 +01002090 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002091 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
Harald Welte85804d42017-12-10 14:11:58 +01002092 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2093 }
2094
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002095 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002096 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002097}
2098
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002099/* Verify T(iar) triggers and releases the channel */
2100testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2101 var DchanTuple dt;
2102
2103 /* Set T(iar) in BSC low enough that it will trigger before other side
2104 has time to keep alive with a T(ias). Keep recommended ratio of
2105 T(iar) >= T(ias)*2 */
2106 g_bsc_sccp_timer_ias := 2;
2107 g_bsc_sccp_timer_iar := 5;
2108
2109 f_init(1);
2110
2111 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2112 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002113 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002114}
2115
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002116private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2117runs on test_CT
2118{
2119 var DchanTuple dt;
2120
2121 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2122 var BssmapCause cause := 0;
2123 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2124 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2125 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2126 }
2127
2128 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_rr_cause := expect_rr_cause);
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002129}
2130
2131/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2132testcase TC_chan_rel_rr_cause() runs on test_CT {
2133 f_init(1);
2134
2135 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2136 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2137 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2138 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2139 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2140 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002141
2142 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002143}
2144
Harald Welte5cd20ed2017-12-13 21:03:20 +01002145/* Test behavior if RSL EST IND for non-active channel */
2146testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2147 timer T := 2.0;
2148
Harald Welte89d42e82017-12-17 16:42:41 +01002149 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002150
2151 var octetstring l3 := '00010203040506'O;
2152 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2153 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2154
2155 T.start;
2156 alt {
2157 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2158 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2159 }
2160 [] BSSAP.receive {}
2161 [] IPA_RSL[0].receive {}
2162 [] T.timeout {}
2163 }
2164
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002165 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002166}
2167
2168/* Test behavior if RSL EST IND for invalid SAPI */
2169testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2170 var RslChannelNr chan_nr;
2171
Harald Welte89d42e82017-12-17 16:42:41 +01002172 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002173
2174 chan_nr := f_chreq_act_ack()
2175
2176 var octetstring l3 := '00010203040506'O;
2177 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2178
2179 timer T := 2.0;
2180 T.start;
2181 alt {
2182 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2183 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2184 }
2185 [] BSSAP.receive { repeat; }
2186 [] IPA_RSL[0].receive { repeat; }
2187 [] T.timeout {}
2188 }
2189
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002190 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002191}
2192
2193/* Test behavior if RSL EST IND for invalid SAPI */
2194testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2195 timer T := 2.0;
2196
Harald Welte89d42e82017-12-17 16:42:41 +01002197 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002198
2199 var RslChannelNr chan_nr := f_chreq_act_ack();
2200
2201 var octetstring l3 := '00010203040506'O;
2202 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2203
2204 T.start;
2205 alt {
2206 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2207 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2208 }
2209 [] BSSAP.receive { repeat; }
2210 [] IPA_RSL[0].receive { repeat; }
2211 [] T.timeout {}
2212 }
2213
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002214 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002215}
2216
2217/* Test behavior if RSL EST IND for invalid SACCH */
2218testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2219 timer T := 2.0;
2220
Harald Welte89d42e82017-12-17 16:42:41 +01002221 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002222
2223 var RslChannelNr chan_nr := f_chreq_act_ack();
2224
2225 var octetstring l3 := '00010203040506'O;
2226 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2227
2228 T.start;
2229 alt {
2230 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2231 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2232 }
2233 [] BSSAP.receive { repeat; }
2234 [] IPA_RSL[0].receive { repeat; }
2235 [] T.timeout {}
2236 }
2237
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002238 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002239}
2240
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002241/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2242private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2243 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2244 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2245
2246 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2247 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2248
2249 f_establish_fully(ass_cmd, exp_compl);
2250
2251 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2252 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2253 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2254 BSSAP.receive(PDU_BSSAP:{
2255 discriminator := '1'B,
2256 spare := '0000000'B,
2257 dlci := 'C3'O,
2258 lengthIndicator := ?,
2259 pdu := { dtap := '0904'O }
2260 });
2261
2262 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2263 for (var integer i := 0; i < 32; i := i + 1) {
2264 var octetstring l3 := '09'O & f_rnd_octstring(14);
2265 var template (value) RslLinkId link_id;
2266 var template (value) OCT1 dlci;
2267
2268 if (i mod 2 == 0) {
2269 /* SAPI0 on FACCH or SDCCH */
2270 link_id := ts_RslLinkID_DCCH(0);
2271 dlci := '80'O;
2272 } else {
2273 /* SAPI3 on SACCH */
2274 link_id := ts_RslLinkID_SACCH(3);
2275 dlci := 'C3'O;
2276 }
2277
2278 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002279 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002280 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002281 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002282 }
2283}
2284testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2285 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2286 var MSC_ConnHdlr vc_conn;
2287
2288 f_init(1, true);
2289 f_sleep(1.0);
2290
2291 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2292 vc_conn.done;
2293
2294 f_shutdown_helper();
2295}
2296
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002297private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2298 template myBSSMAP_Cause cause := ?,
2299 float T_val := 2.0)
2300runs on test_CT {
2301 var BSSAP_N_DATA_ind rx_di;
2302 timer T;
2303
2304 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2305 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2306
2307 T.start(T_val);
2308 alt {
2309 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2310 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2311 if (not match(rx_cause, tr_cause)) {
2312 setverdict(fail, "Rx unexpected Cause IE: ",
2313 rx_cause, " vs expected ", tr_cause);
2314 }
2315 setverdict(pass);
2316 }
2317 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2318 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2319 }
2320 [] T.timeout {
2321 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2322 }
2323 }
2324}
2325
2326/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2327testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2328 var octetstring rnd_data := f_rnd_octstring(16);
2329 var RSL_Message rx_rsl;
2330 var DchanTuple dt;
2331
2332 f_init(1);
2333
2334 /* MS establishes a SAPI=0 link on DCCH */
2335 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2336
2337 /* MSC sends some data on (not yet established) SAPI=3 link */
2338 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2339 /* BSC attempts to establish a SAPI=3 link on DCCH */
2340 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2341
2342 /* MS sends unexpected RELease INDication on SAPI=3 */
2343 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2344 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2345 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2346
2347 /* Clean up the connection */
2348 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2349 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2350
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002351 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002352}
2353
2354/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2355testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2356 var octetstring rnd_data := f_rnd_octstring(16);
2357 var RSL_Message rx_rsl;
2358 var DchanTuple dt;
2359
2360 f_init(1);
2361
2362 /* MS establishes a SAPI=0 link on DCCH */
2363 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2364
2365 /* MSC sends some data on (not yet established) SAPI=3 link */
2366 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2367 /* BSC attempts to establish a SAPI=3 link on DCCH */
2368 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2369
2370 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2371 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2372 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2373 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2374
2375 /* Clean up the connection */
2376 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2377 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2378
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002379 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002380}
2381
2382/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2383testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2384 var octetstring rnd_data := f_rnd_octstring(16);
2385 var RSL_Message rx_rsl;
2386 var DchanTuple dt;
2387
2388 f_init(1);
2389
2390 /* MS establishes a SAPI=0 link on DCCH */
2391 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2392
2393 /* MSC sends some data on (not yet established) SAPI=3 link */
2394 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2395 /* BSC attempts to establish a SAPI=3 link on DCCH */
2396 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2397
2398 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2399 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2400
2401 /* Clean up the connection */
2402 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2403 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2404
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002405 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002406}
2407
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002408testcase TC_si_default() runs on test_CT {
2409 f_init(0);
2410 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002411 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002412}
Harald Welte4003d112017-12-09 22:35:39 +01002413
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002414/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2415 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2416private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2417{
2418 select (earfcn_index) {
2419 case (0) {
2420 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2421 return 111;
2422 }
2423 case (1) {
2424 return 1;
2425 }
2426 case (2) {
2427 return 0;
2428 }
2429 case (3) {
2430 return 65535;
2431 }
2432 case else {
2433 return 23 * (earfcn_index - 3);
2434 }
2435 }
2436}
2437
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002438function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2439 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002440
2441 f_init(0);
2442
2443 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2444 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002445 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2446 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002447 }
2448
2449 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2450
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002451 if (not istemplatekind(expect_cells, "omit")) {
2452 /* Also check that RR Channel Release contains these EARFCNs.
2453 * (copied code from TC_chan_rel_hard_clear_csfb) */
2454 var BSSAP_N_DATA_ind rx_di;
2455 var DchanTuple dt;
2456
2457 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002458 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2459 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2460 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002461
2462 /* Instruct BSC to clear channel */
2463 var BssmapCause cause := 0;
2464 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2465
2466 /* expect Clear Complete from BSC on A */
2467 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2468 /* release the SCCP connection */
2469 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2470 }
2471
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002472 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := expect_cells);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002473 }
2474
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002475 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002476 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002477 }
2478}
2479
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002480private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2481{
2482 var template SI2quaterRestOctetsList si2quater := {};
2483 var integer si2quater_count := (count + 2) / 3;
2484
2485 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002486 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002487 var integer index := i / 3;
2488 var integer earfcn_index := i mod 3;
2489 if (index >= lengthof(si2quater)) {
2490 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2491 }
2492 si2quater[index].rel_additions.rel5.rel6.rel7.rel8.prio_eutran_params_desc.desc.eutran_params_desc.desc.repeated_neigh_cells[0].cell_desc_list[earfcn_index] := tr_EUTRAN_CellDesc_default(e_arfcn := earfcn);
2493 }
2494
2495 return si2quater;
2496}
2497
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002498private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2499{
2500 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2501
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002502 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002503 for (var integer i := 0; i < count; i := i + 1) {
2504 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002505 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002506 }
2507
2508 return tr_CellSelIndValue_EUTRAN(cells);
2509}
2510
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002511private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2512{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002513 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002514 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002515 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2516 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002517}
2518
2519testcase TC_si2quater_2_earfcns() runs on test_CT {
2520 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002521 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002522}
2523
2524testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002525 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002526 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002527}
2528
2529testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002530 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002531 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002532}
2533
2534testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002535 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002536 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002537}
2538
2539testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002540 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002541 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002542}
2543
2544testcase TC_si2quater_12_earfcns() runs on test_CT {
2545 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002546 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002547}
2548
2549testcase TC_si2quater_23_earfcns() runs on test_CT {
2550 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002551 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002552}
2553
2554testcase TC_si2quater_32_earfcns() runs on test_CT {
2555 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002556 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002557}
2558
2559testcase TC_si2quater_33_earfcns() runs on test_CT {
2560 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002561 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002562}
2563
2564testcase TC_si2quater_42_earfcns() runs on test_CT {
2565 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002566 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002567}
2568
2569testcase TC_si2quater_48_earfcns() runs on test_CT {
2570 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002571 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002572}
2573
2574/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2575 * 48 EARFCNs. */
2576testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002577 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002578 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2579 f_init(0);
2580
2581 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002582 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2583 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002584 }
2585
2586 /* The 49th EARFCN no longer fits, expect VTY error */
2587 f_vty_enter_cfg_bts(BSCVTY, 0);
2588 var charstring vty_error;
2589 vty_error := f_vty_transceive_ret(BSCVTY,
2590 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2591 f_vty_transceive(BSCVTY, "end");
2592
2593 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2594 log("Got expected VTY error: ", vty_error);
2595 setverdict(pass);
2596 } else {
2597 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2598 }
2599
2600 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2601
2602 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002603 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list del earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002604 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002605 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002606}
2607
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002608private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2609{
2610 var uint8_t count := 0;
2611 for (var integer i := 5; i < 16; i := i + 1) {
2612 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2613 count := count + 1;
2614 }
2615 }
2616 return count;
2617}
2618
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002619private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2620{
2621 var ASP_RSL_Unitdata rx_rsl_ud;
2622 var SystemInformationType1 last_si1;
2623
2624 timer T := 30.0;
2625 T.start;
2626 alt {
2627 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2628 tr_RSL_BCCH_INFO,
2629 tr_RSL_NO_SACCH_FILL,
2630 tr_RSL_SACCH_FILL))
2631 ) -> value rx_rsl_ud {
2632 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2633 if (g_system_information[rsl_idx].si1 == omit) {
2634 repeat;
2635 }
2636 last_si1 := g_system_information[rsl_idx].si1;
2637 g_system_information[rsl_idx].si1 := omit;
2638 T.stop;
2639 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002640 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002641 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2642 }
2643 return last_si1;
2644}
2645
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002646/* verify ACC rotate feature */
2647testcase TC_si_acc_rotate() runs on test_CT {
2648 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002649 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002650 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002651 var uint8_t count;
2652 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2653
2654 f_init(0, guard_timeout := 60.0);
2655
2656 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2657 "access-control-class-rotate 3",
2658 "access-control-class-rotate-quantum 1"});
2659
2660 /* Init and get first sysinfo */
2661 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2662
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002663 for (var integer i:= 0; i < 20; i := i + 1) {
2664 last_si1 := f_recv_next_si1(0);
2665 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002666 count := f_acc09_count_allowed(acc);
2667 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2668
2669 if (count != 3) {
2670 log("RSL: EXPECTED SI ACC len=3");
2671 setverdict(fail, "received SI does not match expectations");
2672 break;
2673 }
2674
2675 for (var integer j := 0; j < 10; j := j + 1) {
2676 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2677 times_allowed[j] := times_allowed[j] + 1;
2678 }
2679 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002680 }
2681
2682 for (var integer j := 0; j < 10; j := j + 1) {
2683 log("ACC", j, " allowed ", times_allowed[j], " times" );
2684 if (j != 5 and times_allowed[j] < 3) {
2685 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2686 } else if (j == 5 and times_allowed[j] > 0) {
2687 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2688 }
2689 }
2690
2691 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2692 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002693 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002694}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002695
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002696/* verify ACC startup ramp+rotate feature */
2697testcase TC_si_acc_ramp_rotate() runs on test_CT {
2698 var template SystemInformationConfig sic := SystemInformationConfig_default;
2699 var SystemInformationType1 last_si1;
2700 var AccessControlClass acc;
2701 var ASP_RSL_Unitdata rx_rsl_ud;
2702 var uint8_t count;
2703 var uint8_t prev_count;
2704 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2705
2706 f_init(0, guard_timeout := 80.0);
2707
2708 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2709 "access-control-class-rotate 0",
2710 "access-control-class-rotate-quantum 1",
2711 "access-control-class-ramping",
2712 "access-control-class-ramping-step-interval 5",
2713 "access-control-class-ramping-step-size 5"});
2714
2715 /* Init and get first sysinfo */
2716 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2717 last_si1 := g_system_information[0].si1;
2718 acc := last_si1.rach_control.acc;
2719 count := f_acc09_count_allowed(acc);
2720 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2721 while (count > 0) {
2722 last_si1 := f_recv_next_si1(0);
2723 acc := last_si1.rach_control.acc;
2724 count := f_acc09_count_allowed(acc);
2725 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2726 }
2727
2728 /* Increase adm subset size, we should see ramping start up */
2729 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2730 prev_count := 0;
2731 while (true) {
2732 last_si1 := f_recv_next_si1(0);
2733 acc := last_si1.rach_control.acc;
2734 count := f_acc09_count_allowed(acc);
2735 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2736
2737 if (prev_count > count) {
2738 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2739 break;
2740 }
2741
2742 if (count == 9) {
2743 break; /* Maximum reached (10 - 1 perm barred), done here */
2744 }
2745
2746 prev_count := count;
2747 }
2748
2749 setverdict(pass);
2750
2751 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2752 "rach access-control-class 4 allowed",
2753 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002754 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002755}
2756
Harald Welte4003d112017-12-09 22:35:39 +01002757testcase TC_ctrl_msc_connection_status() runs on test_CT {
2758 var charstring ctrl_resp;
2759
Harald Welte89d42e82017-12-17 16:42:41 +01002760 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002761
2762 /* See https://osmocom.org/issues/2729 */
2763 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002764 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002765}
2766
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002767testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2768 var charstring ctrl_resp;
2769
2770 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002771
2772 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002773 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002774}
2775
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002776/* Verify correct stats on the number of configured and connected MSCs */
2777private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2778 g_pars := f_gen_test_hdlr_pars();
2779 var StatsDExpects expect := {
2780 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2781 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2782 };
2783 f_statsd_expect(expect);
2784}
2785
2786private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2787{
2788 var MSC_ConnHdlr vc_conn;
2789
2790 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
2791 f_sleep(1.0);
2792 vc_conn := f_start_handler(tc_fn);
2793 vc_conn.done;
2794
2795 /* Also verify stat exposed on CTRL interface */
2796 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
2797 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
2798
2799 f_shutdown_helper();
2800}
2801
2802/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
2803private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
2804 f_tc_stat_num_msc_connected_msc_connhdlr(1);
2805}
2806testcase TC_stat_num_msc_connected_1() runs on test_CT {
2807 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
2808}
2809
2810/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
2811private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
2812 f_tc_stat_num_msc_connected_msc_connhdlr(2);
2813}
2814testcase TC_stat_num_msc_connected_2() runs on test_CT {
2815 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
2816}
2817
2818/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
2819private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
2820 f_tc_stat_num_msc_connected_msc_connhdlr(3);
2821}
2822testcase TC_stat_num_msc_connected_3() runs on test_CT {
2823 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
2824}
2825
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02002826/* Verify correct stats on the number of configured and connected MSCs */
2827private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
2828 g_pars := f_gen_test_hdlr_pars();
2829 var StatsDExpects expect := {
2830 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
2831 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2832 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
2833 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
2834 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
2835 };
2836 f_statsd_expect(expect);
2837}
2838
2839private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
2840 var MSC_ConnHdlr vc_conn;
2841
2842 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
2843 f_sleep(1.0);
2844 vc_conn := f_start_handler(tc_fn);
2845 vc_conn.done;
2846
2847 /* Also verify stat exposed on CTRL interface */
2848 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
2849 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
2850 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
2851 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
2852
2853 f_shutdown_helper();
2854}
2855
2856/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
2857private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
2858 f_tc_stat_num_bts_connected_msc_connhdlr(1);
2859}
2860testcase TC_stat_num_bts_connected_1() runs on test_CT {
2861 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
2862}
2863
2864/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
2865private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
2866 f_tc_stat_num_bts_connected_msc_connhdlr(2);
2867}
2868testcase TC_stat_num_bts_connected_2() runs on test_CT {
2869 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
2870}
2871
2872/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
2873private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
2874 f_tc_stat_num_bts_connected_msc_connhdlr(3);
2875}
2876testcase TC_stat_num_bts_connected_3() runs on test_CT {
2877 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
2878}
2879
Harald Welte4003d112017-12-09 22:35:39 +01002880testcase TC_ctrl() runs on test_CT {
2881 var charstring ctrl_resp;
2882
Harald Welte89d42e82017-12-17 16:42:41 +01002883 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002884
2885 /* all below values must match the osmo-bsc.cfg config file used */
2886
Harald Welte6a129692018-03-17 17:30:14 +01002887 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
2888 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02002889 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01002890
2891 var integer bts_nr := 0;
2892 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
2893 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
2894 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
2895 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
2896 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
2897 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
2898 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
2899
2900 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
2901 f_sleep(2.0);
2902 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
2903 setverdict(fail, "oml-uptime not incrementing as expected");
2904 }
2905 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
2906
2907 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
2908
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002909 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01002910}
2911
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002912/* Verify that Upon receival of SET "location", BSC forwards a TRAP
2913 "location-state" over the SCCPlite IPA conn */
2914testcase TC_ctrl_location() runs on test_CT {
2915 var MSC_ConnHdlr vc_conn;
2916 var integer bts_nr := 0;
2917
2918 f_init(1, true);
2919 f_sleep(1.0);
2920
2921 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
2922 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2923 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
2924
2925 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
2926 f_sleep(2.0);
2927
2928 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
2929 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
2930 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
2931
2932 /* should match the one from config */
2933 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
2934
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002935 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02002936}
2937
Harald Welte6f521d82017-12-11 19:52:02 +01002938
2939/***********************************************************************
2940 * Paging Testing
2941 ***********************************************************************/
2942
2943type record Cell_Identity {
2944 GsmMcc mcc,
2945 GsmMnc mnc,
2946 GsmLac lac,
2947 GsmCellId ci
2948};
Harald Welte24135bd2018-03-17 19:27:53 +01002949private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01002950private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01002951
Harald Welte5d1a2202017-12-13 19:51:29 +01002952type set of integer BtsIdList;
2953
2954private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
2955 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
2956 if (bts_id == bts_ids[j]) {
2957 return true;
2958 }
2959 }
2960 return false;
2961}
Harald Welte6f521d82017-12-11 19:52:02 +01002962
2963/* core paging test helper function; used by most paging test cases */
2964private function f_pageing_helper(hexstring imsi,
2965 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01002966 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01002967 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002968 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01002969{
2970 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002971 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01002972 var RSL_Message rx_rsl;
2973 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01002974 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01002975
2976 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01002977
2978 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01002979 for (i := 0; i < NUM_BTS; i := i + 1) {
2980 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01002981 }
Harald Welte6f521d82017-12-11 19:52:02 +01002982
2983 if (isvalue(rsl_chneed)) {
2984 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
2985 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
2986 } else {
2987 bssmap_chneed := omit;
2988 }
2989
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002990 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
2991 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01002992
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002993 if (not istemplatekind(tmsi, "omit")) {
2994 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002995 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002996 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01002997 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07002998
Harald Welte5d1a2202017-12-13 19:51:29 +01002999 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003000 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003001 /* check channel type, paging group */
3002 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3003 setverdict(fail, "Paging for wrong paging group");
3004 }
3005 if (ispresent(rsl_chneed) and
3006 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3007 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3008 }
Harald Welte6f521d82017-12-11 19:52:02 +01003009 }
Harald Welte2fccd982018-01-31 15:48:19 +01003010 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003011 /* do a quick check on all not-included BTSs if they received paging */
3012 for (i := 0; i < NUM_BTS; i := i + 1) {
3013 timer T := 0.1;
3014 if (f_bts_in_list(i, bts_ids)) {
3015 continue;
3016 }
3017 T.start;
3018 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003019 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003020 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3021 }
3022 [] IPA_RSL[i].receive { repeat; }
3023 [] T.timeout { }
3024 }
Harald Welte6f521d82017-12-11 19:52:02 +01003025 }
3026
3027 setverdict(pass);
3028}
3029
Harald Welte5d1a2202017-12-13 19:51:29 +01003030const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003031const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003032const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3033const BtsIdList c_BtsId_LAC2 := { 2 };
3034
Harald Welte6f521d82017-12-11 19:52:02 +01003035/* PAGING by IMSI + TMSI */
3036testcase TC_paging_imsi_nochan() runs on test_CT {
3037 var BSSMAP_FIELD_CellIdentificationList cid_list;
3038 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003039 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003040 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003041}
3042
3043/* PAGING by IMSI + TMSI */
3044testcase TC_paging_tmsi_nochan() runs on test_CT {
3045 var BSSMAP_FIELD_CellIdentificationList cid_list;
3046 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003047 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003048 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003049}
3050
3051/* Paging with different "channel needed' values */
3052testcase TC_paging_tmsi_any() runs on test_CT {
3053 var BSSMAP_FIELD_CellIdentificationList cid_list;
3054 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003055 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003056 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003057}
3058testcase TC_paging_tmsi_sdcch() runs on test_CT {
3059 var BSSMAP_FIELD_CellIdentificationList cid_list;
3060 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003061 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003062 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003063}
3064testcase TC_paging_tmsi_tch_f() runs on test_CT {
3065 var BSSMAP_FIELD_CellIdentificationList cid_list;
3066 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003067 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003068 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003069}
3070testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3071 var BSSMAP_FIELD_CellIdentificationList cid_list;
3072 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003073 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003074 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003075}
3076
3077/* Paging by CGI */
3078testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3079 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3080 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003081 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003082 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003083}
3084
3085/* Paging by LAC+CI */
3086testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3087 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3088 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003089 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003090 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003091}
3092
3093/* Paging by CI */
3094testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3095 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3096 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003097 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003098 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003099}
3100
3101/* Paging by LAI */
3102testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3103 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3104 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003105 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003106 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003107}
3108
3109/* Paging by LAC */
3110testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3111 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3112 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003113 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003114 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003115}
3116
3117/* Paging by "all in BSS" */
3118testcase TC_paging_imsi_nochan_all() runs on test_CT {
3119 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3120 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003121 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003122 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003123}
3124
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003125/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003126testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3127 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3128 cid_list := { cIl_PLMN_LAC_RNC := { ts_BSSMAP_CI_PLMN_LAC_RNC(cid.mcc, cid.mnc, cid.lac, 12) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003129 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003130 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003131}
Harald Welte6f521d82017-12-11 19:52:02 +01003132
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003133/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003134testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3135 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3136 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003137 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003138 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003139}
3140
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003141/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003142testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3143 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3144 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003145 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003146 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003147}
3148
Harald Welte6f521d82017-12-11 19:52:02 +01003149/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003150testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3151 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3152 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3153 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003154 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003155}
3156
3157/* Paging on empty list: Verify none of them page */
3158testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3159 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3160 cid_list := { cIl_LAC := { } };
3161 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003162 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003163}
3164
Stefan Sperling049a86e2018-03-20 15:51:00 +01003165/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3166testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3167 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3168 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3169 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3170 f_shutdown_helper();
3171}
3172
Harald Welte6f521d82017-12-11 19:52:02 +01003173/* Verify paging retransmission interval + count */
3174/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003175/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003176
Harald Weltee65d40e2017-12-13 00:09:06 +01003177/* Verify PCH load */
3178testcase TC_paging_imsi_load() runs on test_CT {
3179 var BSSMAP_FIELD_CellIdentificationList cid_list;
3180 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003181 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003182 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003183 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003184
3185 /* tell BSC there is no paging space anymore */
3186 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003187 f_sleep(0.2);
3188 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003189
3190 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3191 * there would be 8 retransmissions during 4 seconds */
3192 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003193 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003194 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003195 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003196 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003197 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003198 }
Harald Welte2caa1062018-03-17 18:19:05 +01003199 [] T_retrans.timeout {
3200 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3201 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3202 T_retrans.start;
3203 repeat;
3204 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003205 [] T.timeout {
3206 setverdict(pass);
3207 }
3208 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003209
3210 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003211}
3212
Harald Welte235ebf12017-12-15 14:18:16 +01003213/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003214testcase TC_paging_counter() runs on test_CT {
3215 var BSSMAP_FIELD_CellIdentificationList cid_list;
3216 timer T := 4.0;
3217 var integer i;
3218 var integer paging_attempted_bsc;
3219 var integer paging_attempted_bts[NUM_BTS];
3220 var integer paging_expired_bts[NUM_BTS];
3221 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3222
3223 f_init();
3224
3225 /* read counters before paging */
3226 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
3227 for (i := 0; i < NUM_BTS; i := i+1) {
3228 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3229 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3230 }
3231
3232 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3233
3234 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3235 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3236 for (i := 0; i < NUM_BTS; i := i+1) {
3237 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3238 paging_attempted_bts[i]+1);
3239 }
3240
3241 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3242 f_sleep(12.0);
3243 for (i := 0; i < NUM_BTS; i := i+1) {
3244 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3245 paging_expired_bts[i]+1);
3246 }
Harald Welte1ff69992017-12-14 12:31:17 +01003247
Philipp Maier282ca4b2018-02-27 17:17:00 +01003248 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003249}
3250
3251
Harald Welte10985002017-12-12 09:29:15 +01003252/* Verify paging stops after A-RESET */
3253testcase TC_paging_imsi_a_reset() runs on test_CT {
3254 var BSSMAP_FIELD_CellIdentificationList cid_list;
3255 timer T := 3.0;
3256 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003257 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003258
3259 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003260 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own, ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Welte10985002017-12-12 09:29:15 +01003261 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003262 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[0].sccp_addr_own, g_bssap[0].sccp_addr_peer, tr_BSSMAP_ResetAck(g_osmux_enabled))) { }
Harald Welte10985002017-12-12 09:29:15 +01003263 [] BSSAP.receive { repeat; }
3264 }
3265
Daniel Willmanncbef3982018-07-30 09:22:40 +02003266 /* Wait to avoid a possible race condition if a paging message is
3267 * received right before the reset ACK. */
3268 f_sleep(0.2);
3269
Harald Welte10985002017-12-12 09:29:15 +01003270 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003271 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3272 IPA_RSL[i].clear;
3273 }
Harald Welte10985002017-12-12 09:29:15 +01003274
3275 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3276 T.start;
3277 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003278 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003279 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003280 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003281 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003282 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003283 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003284 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003285 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003286 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003287 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003288 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003289 }
Harald Welte10985002017-12-12 09:29:15 +01003290 [] T.timeout {
3291 setverdict(pass);
3292 }
3293 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003294
3295 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003296}
Harald Welteae026692017-12-09 01:03:01 +01003297
Philipp Maierf45824a2019-08-14 14:44:10 +02003298/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3299 * paging response we can not know which MSC is in charge, so we will blindly
3300 * pick the first configured MSC. This behavior is required in order to make
3301 * MT-CSFB calls working because in those cases the BSC can not know that the
3302 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3303 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003304 */
3305testcase TC_paging_resp_unsol() runs on test_CT {
3306
3307 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003308 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003309
3310 var BSSAP_N_CONNECT_ind rx_c_ind;
3311 var DchanTuple dt;
3312 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003313 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003314
3315 /* Send CHAN RQD and wait for allocation; acknowledge it */
3316 dt.rsl_chan_nr := f_chreq_act_ack();
3317
3318 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3319 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3320
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003321
Philipp Maierf45824a2019-08-14 14:44:10 +02003322 /* Expevct a CR with a matching Paging response on the A-Interface */
3323 T.start;
3324 alt {
3325 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) {
3326 setverdict(pass);
3327 }
3328 [] BSSAP.receive {
3329 setverdict(fail, "Received unexpected message on A-Interface!");
3330 }
3331 [] T.timeout {
3332 setverdict(fail, "Received nothing on A-Interface!");
3333 }
3334 }
3335
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003336 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003337}
3338
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003339/* Test RSL link drop causes counter increment */
3340testcase TC_rsl_drop_counter() runs on test_CT {
3341 var integer rsl_fail;
3342
Harald Welte89d42e82017-12-17 16:42:41 +01003343 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003344
3345 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3346
3347 bts[0].rsl.vc_IPA.stop;
3348
3349 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3350
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003351 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003352}
3353
3354/* TODO: Test OML link drop causes counter increment */
3355
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003356/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3357function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3358 timer T := 10.0;
3359
3360 bts[0].rsl.id := "IPA-0-RSL";
3361 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA");
3362 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3363 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003364 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003365
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003366 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003367
3368 f_init_mgcp("VirtMSC");
3369
3370 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3371 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3372 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3373 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3374
3375 /* wait for IPA OML link to connect and then disconnect */
3376 T.start;
3377 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003378 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003379 T.stop;
3380 return true;
3381 }
3382 [] IPA_RSL[0].receive { repeat }
3383 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003384 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003385 }
3386 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003387 return false;
3388}
3389
3390/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3391testcase TC_rsl_unknown_unit_id() runs on test_CT {
3392 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3393 setverdict(pass);
3394 } else {
3395 setverdict(fail, "Timeout RSL waiting for connection to close");
3396 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003397 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003398}
3399
3400
3401/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3402testcase TC_oml_unknown_unit_id() runs on test_CT {
3403 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3404 setverdict(pass);
3405 } else {
3406 setverdict(fail, "Timeout OML waiting for connection to close");
3407 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003408 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003409}
3410
3411
Harald Weltec1a2fff2017-12-17 11:06:19 +01003412/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003413 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003414 ***********************************************************************/
3415
Harald Welte6811d102019-04-14 22:23:14 +02003416import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003417import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003418import from RSL_Emulation all;
3419import from MSC_ConnectionHandler all;
3420
3421type function void_fn(charstring id) runs on MSC_ConnHdlr;
3422
Harald Welte336820c2018-05-31 20:34:52 +02003423/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003424private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3425 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003426 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003427 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003428 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003429 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003430 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3431 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3432 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003433 if (isvalue(bts[2])) {
3434 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3435 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3436 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003437 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003438 if (mp_enable_lcs_tests) {
3439 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3440 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3441 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003442 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003443 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003444 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003445}
3446
Neels Hofmeyrda436782021-07-20 22:09:06 +02003447function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003448runs on test_CT return MSC_ConnHdlr {
3449 var charstring id := testcasename();
3450 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003451 var integer bssap_idx := 0;
3452 if (isvalue(pars)) {
3453 bssap_idx := valueof(pars).mscpool.bssap_idx;
3454 }
Harald Welte336820c2018-05-31 20:34:52 +02003455 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003456 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003457 return vc_conn;
3458}
3459
3460function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3461runs on test_CT return MSC_ConnHdlr {
3462 var charstring id := testcasename();
Neels Hofmeyr1708d1b2020-10-10 16:56:48 +02003463 /* Emit a marker to appear in the SUT's own logging output */
Neels Hofmeyrda436782021-07-20 22:09:06 +02003464 f_logp(BSCVTY, id & "() start");
Harald Weltea0630032018-03-20 21:09:55 +01003465 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003466 return vc_conn;
3467}
3468
Neels Hofmeyrda436782021-07-20 22:09:06 +02003469function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3470runs on test_CT return MSC_ConnHdlr {
3471 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3472}
3473
Harald Weltea0630032018-03-20 21:09:55 +01003474/* first function inside ConnHdlr component; sets g_pars + starts function */
3475private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3476runs on MSC_ConnHdlr {
3477 if (isvalue(pars)) {
3478 g_pars := valueof(pars);
3479 }
3480 fn.apply(id);
3481}
3482
Oliver Smith26a3db72021-07-09 13:51:29 +02003483private function f_vty_encryption_a5(charstring options) runs on test_CT {
3484 f_vty_transceive(BSCVTY, "configure terminal");
3485 f_vty_transceive(BSCVTY, "network");
3486 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3487 f_vty_transceive(BSCVTY, "exit");
3488 f_vty_transceive(BSCVTY, "exit");
3489}
3490
3491private function f_vty_encryption_a5_reset() runs on test_CT {
3492 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
3493 f_vty_encryption_a5("0 1 3");
3494}
3495
Harald Welte3c86ea02018-05-10 22:28:05 +02003496/* Establish signalling channel (non-assignment case) followed by cipher mode */
3497private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003498 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3499 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003500 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003501 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3502 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3503 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3504 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003505
Philipp Maier23000732018-05-18 11:25:37 +02003506 f_establish_fully(ass_cmd, exp_compl);
Harald Welte3c86ea02018-05-10 22:28:05 +02003507}
3508testcase TC_ciph_mode_a5_0() runs on test_CT {
3509 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003510 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003511 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3512
3513 f_init(1, true);
3514 f_sleep(1.0);
3515 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3516 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003517 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003518}
3519testcase TC_ciph_mode_a5_1() runs on test_CT {
3520 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003521 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003522 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3523
3524 f_init(1, true);
3525 f_sleep(1.0);
3526 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3527 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003528 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003529}
Oliver Smith50b98122021-07-09 15:00:28 +02003530/* OS#4975: verify that A5/2 is preferred over A5/0 */
3531testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3532 var MSC_ConnHdlr vc_conn;
3533 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3534
3535 pars.encr := valueof(t_EncrParams('05'O, f_rnd_octstring(8))); /* A5/0 and A5/2 (0x01|0x04)*/
3536 pars.encr_exp_enc_alg := '04'O; /* A5/2 */
3537
3538 f_init(1, true);
3539 f_vty_encryption_a5("0 1 2 3");
3540 f_sleep(1.0);
3541 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3542 vc_conn.done;
3543 f_vty_encryption_a5_reset();
3544 f_shutdown_helper();
3545}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003546/* OS#4975: verify that A5/1 is preferred over A5/2 */
3547testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3548 var MSC_ConnHdlr vc_conn;
3549 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3550
3551 pars.encr := valueof(t_EncrParams('06'O, f_rnd_octstring(8))); /* A5/1 and A5/2 (0x02|0x04)*/
3552 pars.encr_exp_enc_alg := '02'O; /* A5/1 */
3553
3554 f_init(1, true);
3555 f_vty_encryption_a5("1 2");
3556 f_sleep(1.0);
3557 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3558 vc_conn.done;
3559 f_vty_encryption_a5_reset();
3560 f_shutdown_helper();
3561}
Harald Welte3c86ea02018-05-10 22:28:05 +02003562testcase TC_ciph_mode_a5_3() runs on test_CT {
3563 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003564 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003565 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3566
3567 f_init(1, true);
3568 f_sleep(1.0);
3569 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3570 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003571 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003572}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003573/* Establish a Signalling channel with A5/4 encryption. */
3574testcase TC_ciph_mode_a5_4() runs on test_CT {
3575 var MSC_ConnHdlr vc_conn;
3576 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3577 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003578
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003579 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003580 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003581 f_sleep(1.0);
3582 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3583 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003584 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003585 f_shutdown_helper();
3586}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003587/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3588private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3589 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3590 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3591 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3592 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3593
3594 f_establish_fully(ass_cmd, exp_compl);
3595}
3596testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3597 var MSC_ConnHdlr vc_conn;
3598 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3599
3600 f_init(1, true);
3601 f_sleep(1.0);
3602 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3603 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003604 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003605}
3606
Harald Welte3c86ea02018-05-10 22:28:05 +02003607
3608/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003609private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003610 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3611 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003612
Harald Welte552620d2017-12-16 23:21:36 +01003613 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3614 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003615
Harald Weltea0630032018-03-20 21:09:55 +01003616 f_establish_fully(ass_cmd, exp_compl);
Harald Welte552620d2017-12-16 23:21:36 +01003617}
Harald Welte552620d2017-12-16 23:21:36 +01003618testcase TC_assignment_fr_a5_0() runs on test_CT {
3619 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003620 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003621 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003622
Harald Welte89d42e82017-12-17 16:42:41 +01003623 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003624 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003625 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003626 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003627 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003628}
Harald Welte552620d2017-12-16 23:21:36 +01003629testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003630 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003631 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003632 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003633
Harald Welte89d42e82017-12-17 16:42:41 +01003634 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003635 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003636 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3637 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003638 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003639}
3640testcase TC_assignment_fr_a5_3() runs on test_CT {
3641 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003642 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003643 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003644
Harald Welte651fcdc2018-05-10 20:23:16 +02003645 f_init(1, true);
3646 f_sleep(1.0);
3647 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003648 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003649 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003650}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003651/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3652testcase TC_assignment_fr_a5_4() runs on test_CT {
3653 var MSC_ConnHdlr vc_conn;
3654 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3655 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3656
3657 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003658 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003659 f_sleep(1.0);
3660 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3661 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003662 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003663 f_shutdown_helper();
3664}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003665
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003666/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3667testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3668 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3669 var MSC_ConnHdlr vc_conn;
3670
3671 f_init(1, true);
3672 f_sleep(1.0);
3673
3674 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3675 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3676 vc_conn.done;
3677 f_shutdown_helper();
3678}
3679
Harald Welte552620d2017-12-16 23:21:36 +01003680/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3681private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003682 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003683 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003684 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003685
3686 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003687 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3688
Harald Weltea0630032018-03-20 21:09:55 +01003689 f_establish_fully(ass_cmd, exp_fail);
Harald Welte552620d2017-12-16 23:21:36 +01003690}
Harald Welte552620d2017-12-16 23:21:36 +01003691testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3692 var MSC_ConnHdlr vc_conn;
3693
Harald Welte89d42e82017-12-17 16:42:41 +01003694 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003695 f_sleep(1.0);
3696
Harald Welte8863fa12018-05-10 20:15:27 +02003697 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003698 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003699 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003700}
3701
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003702private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3703 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3704 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003705
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003706 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3707 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3708
3709 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3710
3711 var BSSMAP_FIELD_CodecType codecType;
3712 timer T := 10.0;
3713
3714 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3715 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3716
3717 f_create_chan_and_exp();
3718 /* we should now have a COMPL_L3 at the MSC */
3719
3720 var template PDU_BSSAP exp_l3_compl;
3721 exp_l3_compl := tr_BSSMAP_ComplL3()
3722 if (g_pars.aoip == false) {
3723 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
3724 } else {
3725 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
3726 }
3727 T.start;
3728 alt {
3729 [] BSSAP.receive(exp_l3_compl);
3730 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
3731 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
3732 }
3733 [] T.timeout {
3734 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
3735 }
3736 }
3737
3738 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003739 f_cipher_mode(g_pars.encr, exp_fail := true);
Harald Welte552620d2017-12-16 23:21:36 +01003740}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003741testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3742 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003743 var MSC_ConnHdlr vc_conn;
3744
Harald Welte89d42e82017-12-17 16:42:41 +01003745 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003746 f_sleep(1.0);
3747
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02003748 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003749 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003750 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003751 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003752}
3753
3754
Harald Welte4532e0a2017-12-23 02:05:44 +01003755private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003756 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01003757 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02003758 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01003759 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003760
3761 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01003762 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003763
3764 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02003765 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
3766 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02003767 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
3768 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
3769 };
3770 f_statsd_expect(expect);
Harald Welte4532e0a2017-12-23 02:05:44 +01003771}
3772
3773testcase TC_assignment_sign() runs on test_CT {
3774 var MSC_ConnHdlr vc_conn;
3775
3776 f_init(1, true);
3777 f_sleep(1.0);
3778
Harald Welte8863fa12018-05-10 20:15:27 +02003779 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01003780 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003781 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01003782}
3783
Harald Welte60aa5762018-03-21 19:33:13 +01003784/***********************************************************************
3785 * Codec (list) testing
3786 ***********************************************************************/
3787
3788/* check if the given rsl_mode is compatible with the a_elem */
3789private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
3790return boolean {
3791 select (a_elem.codecType) {
3792 case (GSM_FR) {
3793 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
3794 return true;
3795 }
3796 }
3797 case (GSM_HR) {
3798 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
3799 return true;
3800 }
3801 }
3802 case (GSM_EFR) {
3803 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
3804 return true;
3805 }
3806 }
3807 case (FR_AMR) {
3808 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
3809 return true;
3810 }
3811 }
3812 case (HR_AMR) {
3813 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
3814 return true;
3815 }
3816 }
3817 case else { }
3818 }
3819 return false;
3820}
3821
3822/* check if the given rsl_mode is compatible with the a_list */
3823private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
3824return boolean {
3825 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
3826 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
3827 return true;
3828 }
3829 }
3830 return false;
3831}
3832
3833/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02003834function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01003835return BSSMAP_IE_ChannelType {
3836 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
3837 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
3838 select (a_elem.codecType) {
3839 case (GSM_FR) {
3840 ret.channelRateAndType := ChRate_TCHF;
3841 ret.speechId_DataIndicator := Spdi_TCHF_FR;
3842 }
3843 case (GSM_HR) {
3844 ret.channelRateAndType := ChRate_TCHH;
3845 ret.speechId_DataIndicator := Spdi_TCHH_HR;
3846 }
3847 case (GSM_EFR) {
3848 ret.channelRateAndType := ChRate_TCHF;
3849 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
3850 }
3851 case (FR_AMR) {
3852 ret.channelRateAndType := ChRate_TCHF;
3853 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
3854 }
3855 case (HR_AMR) {
3856 ret.channelRateAndType := ChRate_TCHH;
3857 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
3858 }
3859 case else {
3860 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02003861 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01003862 }
3863 }
3864 return ret;
3865}
3866
Harald Weltea63b9102018-03-22 20:36:16 +01003867private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
3868return template RSL_IE_Body {
3869 var template RSL_IE_Body mode_ie := {
3870 chan_mode := {
3871 len := ?,
3872 reserved := ?,
3873 dtx_d := ?,
3874 dtx_u := ?,
3875 spd_ind := RSL_SPDI_SPEECH,
3876 ch_rate_type := -,
3877 coding_alg_rate := -
3878 }
3879 }
3880
3881 select (a_elem.codecType) {
3882 case (GSM_FR) {
3883 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3884 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3885 }
3886 case (GSM_HR) {
3887 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3888 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
3889 }
3890 case (GSM_EFR) {
3891 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3892 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
3893 }
3894 case (FR_AMR) {
3895 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
3896 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3897 }
3898 case (HR_AMR) {
3899 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
3900 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
3901 }
3902 }
3903 return mode_ie;
3904}
3905
Harald Welte60aa5762018-03-21 19:33:13 +01003906type record CodecListTest {
3907 BSSMAP_IE_SpeechCodecList codec_list,
3908 charstring id
3909}
3910type record of CodecListTest CodecListTests
3911
3912private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02003913 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
3914 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01003915
3916 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003917 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02003918 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3919 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
3920 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01003921 if (isvalue(g_pars.expect_mr_s0_s7)) {
3922 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
3923 g_pars.expect_mr_s0_s7;
3924 }
Harald Welte79f3f542018-05-25 20:02:37 +02003925 }
Harald Welte60aa5762018-03-21 19:33:13 +01003926 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3927 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01003928 log("expecting ASS COMPL like this: ", exp_compl);
3929
3930 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01003931
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003932 if (not g_pars.expect_channel_mode_modify) {
3933 /* Verify that the RSL-side activation actually matches our expectations */
3934 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01003935
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003936 var RSL_IE_Body mode_ie;
3937 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
3938 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02003939 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003940 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003941 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
3942 if (not match(mode_ie, t_mode_ie)) {
3943 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
3944 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003945 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003946
3947 var RSL_IE_Body mr_conf;
3948 if (g_pars.expect_mr_conf_ie != omit) {
3949 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
3950 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
3951 mtc.stop;
3952 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003953 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02003954
3955 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
3956 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
3957 g_pars.expect_mr_conf_ie);
3958 }
3959 } else {
3960 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
3961 log("found RSL MR CONFIG IE: ", mr_conf);
3962 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
3963 mtc.stop;
3964 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02003965 }
3966 }
Harald Welte60aa5762018-03-21 19:33:13 +01003967}
3968
Philipp Maierd0e64b02019-03-13 14:15:23 +01003969private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
3970
3971 var PDU_BSSAP ass_cmd := f_gen_ass_req();
3972 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
3973
3974 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003975 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01003976 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
3977 }
3978 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
3979 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
3980 log("expecting ASS FAIL like this: ", exp_fail);
3981
3982 f_establish_fully(ass_cmd, exp_fail);
3983}
3984
Harald Welte60aa5762018-03-21 19:33:13 +01003985testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003986 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01003987 var MSC_ConnHdlr vc_conn;
3988
3989 f_init(1, true);
3990 f_sleep(1.0);
3991
3992 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02003993 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01003994 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003995 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01003996}
3997
3998testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02003999 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004000 var MSC_ConnHdlr vc_conn;
4001
4002 f_init(1, true);
4003 f_sleep(1.0);
4004
4005 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004006 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004007 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004008 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004009}
4010
4011testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004012 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004013 var MSC_ConnHdlr vc_conn;
4014
4015 f_init(1, true);
4016 f_sleep(1.0);
4017
4018 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004019 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004020 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004021 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004022}
4023
Philipp Maierd0e64b02019-03-13 14:15:23 +01004024/* Allow 5,90k only (current default config) */
4025private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004026 f_vty_cfg_msc(BSCVTY, 0, {
4027 "amr-config 12_2k forbidden",
4028 "amr-config 10_2k forbidden",
4029 "amr-config 7_95k forbidden",
4030 "amr-config 7_40k forbidden",
4031 "amr-config 6_70k forbidden",
4032 "amr-config 5_90k allowed",
4033 "amr-config 5_15k forbidden",
4034 "amr-config 4_75k forbidden"
4035 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004036}
4037
4038/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4039 * ("Config-NB-Code = 1") */
4040private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004041 f_vty_cfg_msc(BSCVTY, 0, {
4042 "amr-config 12_2k allowed",
4043 "amr-config 10_2k forbidden",
4044 "amr-config 7_95k forbidden",
4045 "amr-config 7_40k allowed",
4046 "amr-config 6_70k forbidden",
4047 "amr-config 5_90k allowed",
4048 "amr-config 5_15k forbidden",
4049 "amr-config 4_75k allowed"
4050 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004051}
4052
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004053private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4054 var charstring tch;
4055 if (fr) {
4056 tch := "tch-f";
4057 } else {
4058 tch := "tch-h";
4059 }
4060 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4061}
4062
4063/* Set the AMR start-mode for this TCH back to the default configuration. */
4064private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4065 f_vty_amr_start_mode_set(fr, "auto");
4066}
4067
Harald Welte60aa5762018-03-21 19:33:13 +01004068testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004069 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004070 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004071
4072 /* Note: This setups the codec configuration. The parameter payload in
4073 * mr_conf must be consistant with the parameter codecElements in pars
4074 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004075 var RSL_IE_Body mr_conf := {
4076 other := {
4077 len := 2,
4078 payload := '2804'O
4079 }
4080 };
Harald Welte60aa5762018-03-21 19:33:13 +01004081
Philipp Maier7695a0d2018-09-27 17:52:14 +02004082 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004083 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004084 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4085 pars.expect_mr_conf_ie := mr_conf;
4086
Harald Welte60aa5762018-03-21 19:33:13 +01004087 f_init(1, true);
4088 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004089 f_vty_amr_start_mode_set(true, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004090
Harald Welte8863fa12018-05-10 20:15:27 +02004091 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004092 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004093
4094 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004095 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004096}
4097
4098testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004099 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004100 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004101
4102 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004103 var RSL_IE_Body mr_conf := {
4104 other := {
4105 len := 2,
4106 payload := '2804'O
4107 }
4108 };
Harald Welte60aa5762018-03-21 19:33:13 +01004109
Philipp Maier7695a0d2018-09-27 17:52:14 +02004110 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004111 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004112 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4113 pars.expect_mr_conf_ie := mr_conf;
4114
Harald Welte60aa5762018-03-21 19:33:13 +01004115 f_init(1, true);
4116 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004117 f_vty_amr_start_mode_set(false, "1");
Harald Welte60aa5762018-03-21 19:33:13 +01004118
Harald Welte8863fa12018-05-10 20:15:27 +02004119 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004120 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004121
4122 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004123 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004124}
4125
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004126/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4127testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4128 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4129 var MSC_ConnHdlr vc_conn;
4130
4131 f_init(1, true);
4132 f_sleep(1.0);
4133
4134 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4135 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4136 * expecting a Channel Mode Modify if the channel type is compatible. */
4137 f_disable_all_sdcch();
4138 f_disable_all_tch_h();
4139
4140 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4141 pars.expect_channel_mode_modify := true;
4142 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4143 vc_conn.done;
4144
4145 f_enable_all_sdcch();
4146 f_enable_all_tch();
4147 f_shutdown_helper();
4148}
4149
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004150/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4151testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4152 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4153 var MSC_ConnHdlr vc_conn;
4154
4155 var RSL_IE_Body mr_conf := {
4156 other := {
4157 len := 2,
4158 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4159 }
4160 };
4161
4162 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4163 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4164 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4165 pars.expect_mr_conf_ie := mr_conf;
4166
4167 f_init(1, true);
4168 f_sleep(1.0);
4169
4170 /* First set nonzero start mode bits */
4171 f_vty_amr_start_mode_set(true, "4");
4172 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4173 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4174 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4175 f_vty_amr_start_mode_set(true, "auto");
4176
4177 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4178 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004179
4180 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4181 f_vty_amr_start_mode_set(true, "1");
4182 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004183 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004184}
4185
Neels Hofmeyr21863562020-11-26 00:34:33 +00004186function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4187 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004188runs on test_CT {
4189
4190 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4191 var MSC_ConnHdlr vc_conn;
4192
4193 /* See note above */
4194 var RSL_IE_Body mr_conf := {
4195 other := {
4196 len := lengthof(mrconf),
4197 payload := mrconf
4198 }
4199 };
4200
4201 if (fr) {
4202 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4203 } else {
4204 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4205 }
4206 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4207 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4208 pars.expect_mr_conf_ie := mr_conf;
4209 pars.expect_mr_s0_s7 := exp_s8_s0;
4210
4211 f_init(1, true);
4212 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004213 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004214 f_sleep(1.0);
4215
4216 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4217 vc_conn.done;
4218 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004219 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004220}
4221
4222function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4223runs on test_CT {
4224
4225 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4226 var MSC_ConnHdlr vc_conn;
4227
4228 if (fr) {
4229 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4230 } else {
4231 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4232 }
4233 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4234 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4235
4236 f_init(1, true);
4237 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004238 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004239 f_sleep(1.0);
4240
4241 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4242 vc_conn.done;
4243 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004244 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004245}
4246
4247
4248/* Set S1, we expect an AMR multirate configuration IE with all four rates
4249 * set. */
4250testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004251 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004252 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004253}
4254
4255/* Set S1, we expect an AMR multirate configuration IE with the lower three
4256 * rates set. */
4257testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004258 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004259 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004260}
4261
4262/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4263 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4264testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004265 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004266 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004267}
4268
4269/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4270 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4271testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004272 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004273 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004274}
4275
4276/* The following block of tests selects more and more rates until all four
4277 * possible rates are in the active set (full rate) */
4278testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004279 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004280 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004281}
4282
4283testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004284 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004285 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004286}
4287
4288testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004289 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004290 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004291}
4292
4293testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004294 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004295 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004296}
4297
4298/* The following block of tests selects more and more rates until all three
4299 * possible rates are in the active set (half rate) */
4300testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004301 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004302 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004303}
4304
4305testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004306 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004307 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004308}
4309
4310testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004311 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004312 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004313}
4314
4315/* The following block tests what happens when the MSC does offer rate
4316 * configurations that are not supported by the BSC. Normally such situations
4317 * should not happen because the MSC gets informed by the BSC in advance via
4318 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4319 * to offer rates that are not applicable anyway. */
4320
4321testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004322 /* Try to include 12,2k in into the active set even though the channel
4323 * is half rate only. The BSC is expected to remove the 12,0k */
4324 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004325 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004326}
4327
4328testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004329 /* See what happens when all rates are selected at once. Since then
4330 * Also S1 is selected, this setting will be prefered and we should
4331 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4332 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004333 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004334}
4335
4336testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004337 /* Same as above, but with S1 missing, the MSC is then expected to
4338 * select the currently supported rates, which are also 12.2k, 7,40k,
4339 * 5,90k, and 4,75k, into the active set. */
4340 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004341 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004342}
4343
4344testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004345 /* Try to select no rates at all */
4346 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004347 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004348}
4349
4350testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004351 /* Try to select only unsupported rates */
4352 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004353 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004354}
4355
4356testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004357 /* Try to select 12,2k for half rate */
4358 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004359 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004360}
4361
Neels Hofmeyr21863562020-11-26 00:34:33 +00004362testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4363 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4364 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004365 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004366}
4367
4368testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4369 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4370 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004371 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004372}
4373
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004374testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004375 /* "amr tch-f modes 0 2 4 7" => total 4 modes and start mode 4 => '11'B on the wire */
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004376 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4377 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004378 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004379}
4380
4381testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004382 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4383 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004384 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004385 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004386}
4387
Philipp Maierac09bfc2019-01-08 13:41:39 +01004388private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004389 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4390 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4391 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4392 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004393}
4394
4395private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004396 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4397 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004398}
4399
4400private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004401 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4402 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4403 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4404 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4405 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4406 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004407}
4408
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004409private function f_disable_all_sdcch() runs on test_CT {
4410 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4411 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4412 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4413 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4414}
4415
4416private function f_enable_all_sdcch() runs on test_CT {
4417 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4418 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4419 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4420 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4421}
4422
Philipp Maierac09bfc2019-01-08 13:41:39 +01004423/* Allow HR only */
4424private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4425 g_pars := f_gen_test_hdlr_pars();
4426 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4427 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4428 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4429 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4430 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4431 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4432 f_establish_fully(ass_cmd, exp_compl);
4433}
4434
4435/* Allow FR only */
4436private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4437 g_pars := f_gen_test_hdlr_pars();
4438 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4439 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4440 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4441 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4442 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4443 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4444 f_establish_fully(ass_cmd, exp_compl);
4445}
4446
4447/* Allow HR only (expect assignment failure) */
4448private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4449 g_pars := f_gen_test_hdlr_pars();
4450 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4451 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4452 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4453 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4454 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4455 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4456 f_establish_fully(ass_cmd, exp_fail);
4457}
4458
4459/* Allow FR only (expect assignment failure) */
4460private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4461 g_pars := f_gen_test_hdlr_pars();
4462 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4463 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4464 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4465 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4466 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4467 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4468 f_establish_fully(ass_cmd, exp_fail);
4469}
4470
4471/* Allow FR and HR, but prefer FR */
4472private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4473 g_pars := f_gen_test_hdlr_pars();
4474 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4475 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4476 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4477 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4478 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4479 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4480 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4481 f_establish_fully(ass_cmd, exp_compl);
4482}
4483
4484/* Allow FR and HR, but prefer HR */
4485private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4486 g_pars := f_gen_test_hdlr_pars();
4487 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4488 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4489 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4490 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4491 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4492 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4493 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4494 f_establish_fully(ass_cmd, exp_compl);
4495}
4496
4497/* Allow FR and HR, but prefer FR */
4498private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4499 g_pars := f_gen_test_hdlr_pars();
4500 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4501 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4502 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4503 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4504 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4505 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4506 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4507 f_establish_fully(ass_cmd, exp_compl);
4508}
4509
4510/* Allow FR and HR, but prefer HR */
4511private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4512 g_pars := f_gen_test_hdlr_pars();
4513 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4514 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4515 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4516 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4517 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4518 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4519 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4520 f_establish_fully(ass_cmd, exp_compl);
4521}
4522
4523/* Request a HR channel while all FR channels are exhausted, this is expected
4524 * to work without conflicts */
4525testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4526 var MSC_ConnHdlr vc_conn;
4527 f_init(1, true);
4528 f_sleep(1.0);
4529 f_enable_all_tch();
4530 f_disable_all_tch_f();
4531 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4532 vc_conn.done;
4533 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004534 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004535}
4536
4537/* Request a FR channel while all FR channels are exhausted, this is expected
4538 * to fail. */
4539testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4540 var MSC_ConnHdlr vc_conn;
4541 f_init(1, true);
4542 f_sleep(1.0);
4543 f_enable_all_tch();
4544 f_disable_all_tch_f();
4545 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4546 vc_conn.done;
4547 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004548 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004549}
4550
4551/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4552 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4553testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4554 var MSC_ConnHdlr vc_conn;
4555 f_init(1, true);
4556 f_sleep(1.0);
4557 f_enable_all_tch();
4558 f_disable_all_tch_f();
4559 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4560 vc_conn.done;
4561 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004562 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004563}
4564
4565/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4566 * are exhausted, this is expected to work without conflicts. */
4567testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4568 var MSC_ConnHdlr vc_conn;
4569 f_init(1, true);
4570 f_sleep(1.0);
4571 f_enable_all_tch();
4572 f_disable_all_tch_f();
4573 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4574 vc_conn.done;
4575 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004576 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004577}
4578
4579/* Request a FR channel while all HR channels are exhausted, this is expected
4580 * to work without conflicts */
4581testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4582 var MSC_ConnHdlr vc_conn;
4583 f_init(1, true);
4584 f_sleep(1.0);
4585 f_enable_all_tch();
4586 f_disable_all_tch_h();
4587 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4588 vc_conn.done;
4589 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004590 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004591}
4592
4593/* Request a HR channel while all HR channels are exhausted, this is expected
4594 * to fail. */
4595testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4596 var MSC_ConnHdlr vc_conn;
4597 f_init(1, true);
4598 f_sleep(1.0);
4599 f_enable_all_tch();
4600 f_disable_all_tch_h();
4601 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4602 vc_conn.done;
4603 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004604 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004605}
4606
4607/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4608 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4609testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4610 var MSC_ConnHdlr vc_conn;
4611 f_init(1, true);
4612 f_sleep(1.0);
4613 f_enable_all_tch();
4614 f_disable_all_tch_h();
4615 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4616 vc_conn.done;
4617 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004618 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004619}
4620
4621/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4622 * are exhausted, this is expected to work without conflicts. */
4623testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4624 var MSC_ConnHdlr vc_conn;
4625 f_init(1, true);
4626 f_sleep(1.0);
4627 f_enable_all_tch();
4628 f_disable_all_tch_h();
4629 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4630 vc_conn.done;
4631 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004632 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004633}
4634
4635/* Allow FR and HR, but prefer HR */
4636private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4637 g_pars := f_gen_test_hdlr_pars();
4638 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4639 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4640 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4641 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4642 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4643 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4644 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4645 f_establish_fully(ass_cmd, exp_compl);
4646}
4647
4648/* Allow FR and HR, but prefer FR */
4649private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4650 g_pars := f_gen_test_hdlr_pars();
4651 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4652 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4653 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4654 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4655 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4656 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4657 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4658 f_establish_fully(ass_cmd, exp_compl);
4659}
4660
4661/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4662 * HR, which is the prefered type, is selected. */
4663testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
4664 var MSC_ConnHdlr vc_conn;
4665 f_init(1, true);
4666 f_sleep(1.0);
4667 f_enable_all_tch();
4668 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
4669 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004670 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004671}
4672
4673/* Request a FR (prefered) or alternatively a HR channel, it is expected that
4674 * FR, which is the prefered type, is selected. */
4675testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
4676 var MSC_ConnHdlr vc_conn;
4677 f_init(1, true);
4678 f_sleep(1.0);
4679 f_enable_all_tch();
4680 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
4681 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004682 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004683}
4684
Pau Espin Pedrol14475352021-07-22 15:48:16 +02004685/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
4686private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
4687 g_pars := f_gen_test_hdlr_pars();
4688 g_pars.ra := '02'O; /* RA containing reason=LU */
4689
4690 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4691 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4692 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4693 var template uint3_t tsc := ?;
4694
4695 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4696 f_create_bssmap_exp(l3_enc);
4697 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4698 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4699
4700 /* we should now have a COMPL_L3 at the MSC */
4701 timer T := 10.0;
4702 T.start;
4703 alt {
4704 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4705 [] T.timeout {
4706 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4707 }
4708 }
4709}
4710testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
4711 var MSC_ConnHdlr vc_conn;
4712 f_init(1, true);
4713 f_sleep(1.0);
4714 f_disable_all_sdcch();
4715 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
4716 vc_conn.done;
4717 f_enable_all_sdcch();
4718 f_shutdown_helper();
4719}
4720
4721/* Request a signalling channel with all SDCCH exhausted, it is
4722 expected that no TCH will be selected for signalling and assigment will fail
4723 because it's dictated by VTY config */
4724testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
4725 var RSL_Message rsl_unused, rsl_msg;
4726 var GsmRrMessage rr;
4727 f_init(1, false);
4728 f_sleep(1.0);
4729 f_vty_allow_tch_for_signalling(false, 0);
4730 f_disable_all_sdcch();
4731
4732 /* RA containing reason=LU */
4733 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
4734 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
4735 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
4736 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
4737 setverdict(fail, "Expected reject");
4738 }
4739
4740 f_vty_allow_tch_for_signalling(true, 0);
4741 f_enable_all_sdcch();
4742 f_shutdown_helper();
4743}
4744
4745/* Request a voice channel with all SDCCH exhausted, it is
4746 * expected that TCH channel will be allocated since the VTY option is only
4747 * aimed at signalling requests */
4748private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
4749 g_pars := f_gen_test_hdlr_pars();
4750 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
4751
4752 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
4753 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
4754 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
4755 var template uint3_t tsc := ?;
4756
4757 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
4758 f_create_bssmap_exp(l3_enc);
4759 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
4760 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
4761
4762 /* we should now have a COMPL_L3 at the MSC */
4763 timer T := 10.0;
4764 T.start;
4765 alt {
4766 [] BSSAP.receive(tr_BSSMAP_ComplL3);
4767 [] T.timeout {
4768 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
4769 }
4770 }
4771}
4772testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
4773 var MSC_ConnHdlr vc_conn;
4774 f_init(1, true);
4775 f_sleep(1.0);
4776 f_vty_allow_tch_for_signalling(false, 0);
4777 f_disable_all_sdcch();
4778
4779 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
4780 vc_conn.done;
4781
4782 f_vty_allow_tch_for_signalling(true, 0);
4783 f_enable_all_sdcch();
4784 f_shutdown_helper();
4785}
4786
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004787testcase TC_assignment_osmux() runs on test_CT {
4788 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4789 var MSC_ConnHdlr vc_conn;
4790
4791 /* See note above */
4792 var RSL_IE_Body mr_conf := {
4793 other := {
4794 len := 2,
4795 payload := '2804'O
4796 }
4797 };
4798
4799 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4800 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4801 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4802 pars.expect_mr_conf_ie := mr_conf;
4803 pars.use_osmux := true;
4804
4805 f_init(1, true, true);
4806 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004807 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004808
4809 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4810 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004811
4812 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004813 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004814}
4815
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004816/* test the procedure of the MSC requesting a Classmark Update:
4817 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
4818 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01004819private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004820 g_pars := f_gen_test_hdlr_pars();
4821
Harald Weltea0630032018-03-20 21:09:55 +01004822 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004823 /* we should now have a COMPL_L3 at the MSC */
4824 BSSAP.receive(tr_BSSMAP_ComplL3);
4825
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02004826 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
4827 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
4828
Harald Welte898113b2018-01-31 18:32:21 +01004829 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
4830 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
4831 setverdict(pass);
4832}
4833testcase TC_classmark() runs on test_CT {
4834 var MSC_ConnHdlr vc_conn;
4835 f_init(1, true);
4836 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004837 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01004838 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004839 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004840}
4841
Harald Welteeddf0e92020-06-21 19:42:15 +02004842/* Send a CommonID from the simulated MSC and verify that the information is used to
4843 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
4844private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
4845 g_pars := f_gen_test_hdlr_pars();
4846 f_MscConnHdlr_init_vty();
4847
4848 f_create_chan_and_exp();
4849 /* we should now have a COMPL_L3 at the MSC */
4850 BSSAP.receive(tr_BSSMAP_ComplL3);
4851
4852 /* Send CommonID */
4853 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
4854
4855 /* Use VTY to verify that the IMSI of the subscr_conn is set */
4856 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
4857 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
4858
4859 setverdict(pass);
4860}
4861testcase TC_common_id() runs on test_CT {
4862 var MSC_ConnHdlr vc_conn;
4863 f_init(1, true);
4864 f_sleep(1.0);
4865 vc_conn := f_start_handler(refers(f_tc_common_id));
4866 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004867 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02004868}
4869
Harald Weltee3bd6582018-01-31 22:51:25 +01004870private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004871 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004872 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01004873 /* we should now have a COMPL_L3 at the MSC */
4874 BSSAP.receive(tr_BSSMAP_ComplL3);
4875
Harald Weltee3bd6582018-01-31 22:51:25 +01004876 /* send the single message we want to send */
4877 f_rsl_send_l3(l3);
4878}
4879
4880private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
4881 timer T := sec;
4882 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01004883 T.start;
4884 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01004885 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
4886 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02004887 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01004888 }
4889 [] T.timeout {
4890 setverdict(pass);
4891 }
4892 }
4893}
4894
Harald Weltee3bd6582018-01-31 22:51:25 +01004895/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4896private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
4897 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
4898 f_bssap_expect_nothing();
4899}
Harald Welte898113b2018-01-31 18:32:21 +01004900testcase TC_unsol_ass_fail() runs on test_CT {
4901 var MSC_ConnHdlr vc_conn;
4902 f_init(1, true);
4903 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004904 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01004905 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004906 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01004907}
Harald Welte552620d2017-12-16 23:21:36 +01004908
Harald Welteea99a002018-01-31 20:46:43 +01004909
4910/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
4911private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004912 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
4913 f_bssap_expect_nothing();
Harald Welteea99a002018-01-31 20:46:43 +01004914}
4915testcase TC_unsol_ass_compl() runs on test_CT {
4916 var MSC_ConnHdlr vc_conn;
4917 f_init(1, true);
4918 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004919 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01004920 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004921 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01004922}
4923
4924
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004925/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
4926private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01004927 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
4928 f_bssap_expect_nothing();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004929}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004930testcase TC_unsol_ho_fail() runs on test_CT {
4931 var MSC_ConnHdlr vc_conn;
4932 f_init(1, true);
4933 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004934 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004935 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004936 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01004937}
4938
4939
Harald Weltee3bd6582018-01-31 22:51:25 +01004940/* short message from MS should be ignored */
4941private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004942 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01004943 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01004944 /* we should now have a COMPL_L3 at the MSC */
4945 BSSAP.receive(tr_BSSMAP_ComplL3);
4946
4947 /* send short message */
4948 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
4949 f_bssap_expect_nothing();
4950}
4951testcase TC_err_82_short_msg() runs on test_CT {
4952 var MSC_ConnHdlr vc_conn;
4953 f_init(1, true);
4954 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004955 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01004956 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004957 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01004958}
4959
4960
Harald Weltee9e02e42018-01-31 23:36:25 +01004961/* 24.008 8.4 Unknown message must trigger RR STATUS */
4962private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
4963 f_est_single_l3(ts_RRM_UL_REL('00'O));
4964 timer T := 3.0
4965 alt {
4966 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
4967 setverdict(pass);
4968 }
4969 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01004970 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01004971 }
4972}
4973testcase TC_err_84_unknown_msg() runs on test_CT {
4974 var MSC_ConnHdlr vc_conn;
4975 f_init(1, true);
4976 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02004977 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01004978 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004979 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01004980}
4981
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01004982/***********************************************************************
4983 * Handover
4984 ***********************************************************************/
4985
Harald Welte94e0c342018-04-07 11:33:23 +02004986/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
4987private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
4988runs on test_CT {
4989 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
4990 " timeslot "&int2str(ts_nr)&" ";
4991 f_vty_transceive(BSCVTY, cmd & suffix);
4992}
4993
Harald Welte261af4b2018-02-12 21:20:39 +01004994/* execute a "bts <0-255> trx <0-255> timeslot <0-7> sub-slot <0-7>" command on given Dchan */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07004995private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
4996 uint8_t bts_nr, uint8_t trx_nr,
4997 in RslChannelNr chan_nr)
4998{
Harald Welte261af4b2018-02-12 21:20:39 +01004999 /* FIXME: resolve those from component-global state */
5000 var integer ts_nr := chan_nr.tn;
5001 var integer ss_nr;
5002 if (ischosen(chan_nr.u.ch0)) {
5003 ss_nr := 0;
5004 } else if (ischosen(chan_nr.u.lm)) {
5005 ss_nr := chan_nr.u.lm.sub_chan;
5006 } else if (ischosen(chan_nr.u.sdcch4)) {
5007 ss_nr := chan_nr.u.sdcch4.sub_chan;
5008 } else if (ischosen(chan_nr.u.sdcch8)) {
5009 ss_nr := chan_nr.u.sdcch8.sub_chan;
5010 } else {
5011 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005012 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005013 }
5014
5015 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5016 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005017 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005018}
5019
Neels Hofmeyr91401012019-07-11 00:42:35 +02005020/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5021 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5022 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5023 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5024 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005025private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5026 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5027{
5028 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005029}
5030
5031/* intra-BSC hand-over between BTS0 and BTS1 */
5032private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005033 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5034 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005035
5036 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5037 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5038
Harald Weltea0630032018-03-20 21:09:55 +01005039 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005040 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005041
5042 var HandoverState hs := {
5043 rr_ho_cmpl_seen := false,
5044 handover_done := false,
5045 old_chan_nr := -
5046 };
5047 /* issue hand-over command on VTY */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005048 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005049 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5050 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005051
5052 /* From the MGW perspective, a handover is is characterized by
5053 * performing one MDCX operation with the MGW. So we expect to see
5054 * one more MDCX during handover. */
5055 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5056
Harald Welte261af4b2018-02-12 21:20:39 +01005057 alt {
5058 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005059 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005060
Philipp Maier4dae0652018-11-12 12:03:26 +01005061 /* Since this is an internal handover we expect the BSC to inform the
5062 * MSC about the event */
5063 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5064
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005065 /* Check the amount of MGCP transactions is still consistant with the
5066 * test expectation */
5067 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005068
5069 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5070 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
5071 f_verify_encr_info(f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr));
5072
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005073 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005074}
5075
5076testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005077 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005078 var MSC_ConnHdlr vc_conn;
5079 f_init(2, true);
5080 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005081
5082 f_ctrs_bsc_and_bts_init();
5083
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005084 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005085 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005086
5087 /* from f_establish_fully() */
5088 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5089 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5090 /* from handover */
5091 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5092 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5093 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5094 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5095 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005096 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005097}
Harald Weltee9e02e42018-01-31 23:36:25 +01005098
Oliver Smith7eabd312021-07-12 14:18:56 +02005099function f_tc_ho_int_a5(OCT1 encr_alg, charstring enc_a5 := "0 1 3") runs on test_CT {
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005100 var MSC_ConnHdlr vc_conn;
5101 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5102 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5103
5104 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005105 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005106 f_sleep(1.0);
5107
5108 f_ctrs_bsc_and_bts_init();
5109
5110 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5111 vc_conn.done;
5112
5113 /* from f_establish_fully() */
5114 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5115 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5116 /* from handover */
5117 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5118 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5119 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5120 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
5121 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005122 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005123 f_shutdown_helper();
5124}
5125
5126testcase TC_ho_int_a5_0() runs on test_CT {
5127 f_tc_ho_int_a5('01'O);
5128}
5129
5130testcase TC_ho_int_a5_1() runs on test_CT {
5131 f_tc_ho_int_a5('02'O);
5132}
5133
5134testcase TC_ho_int_a5_3() runs on test_CT {
5135 f_tc_ho_int_a5('08'O);
5136}
5137
5138testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005139 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005140}
5141
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005142/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5143private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5144 g_pars := f_gen_test_hdlr_pars();
5145 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5146 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005147
5148 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5149 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5150
5151 f_establish_fully(ass_cmd, exp_compl);
5152 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5153
5154 var HandoverState hs := {
5155 rr_ho_cmpl_seen := false,
5156 handover_done := false,
5157 old_chan_nr := -
5158 };
5159 /* issue hand-over command on VTY */
5160 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5161 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5162 f_rslem_suspend(RSL1_PROC);
5163
5164 /* From the MGW perspective, a handover is is characterized by
5165 * performing one MDCX operation with the MGW. So we expect to see
5166 * one more MDCX during handover. */
5167 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5168
5169 var RSL_Message rsl;
5170 var PDU_ML3_NW_MS l3;
5171 var RslChannelNr new_chan_nr;
5172 var GsmArfcn arfcn;
5173 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5174 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5175 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5176 setverdict(fail, "Expected handoverCommand");
5177 mtc.stop;
5178 }
5179 }
5180 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5181 new_chan_nr, arfcn);
5182
5183 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5184
5185 /* resume processing of RSL DChan messages, which was temporarily suspended
5186 * before performing a hand-over */
5187 f_rslem_resume(RSL1_PROC);
5188 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5189
5190 f_sleep(1.0);
5191
5192 /* Handover fails because no HANDO DET appears on the new lchan,
5193 * and the old lchan reports a Radio Link Failure. */
5194 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5195
5196 var PDU_BSSAP rx_clear_request;
5197 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5198 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5199 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5200
5201 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5202
5203 var MgcpCommand mgcp;
5204 interleave {
5205 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5206 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005207 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005208 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005209 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005210 }
5211 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005212 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005213 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005214 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005215 }
5216 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {}
5217 }
5218
5219 f_sleep(0.5);
5220 setverdict(pass);
5221}
5222testcase TC_ho_int_radio_link_failure() runs on test_CT {
5223 var MSC_ConnHdlr vc_conn;
5224 f_init(2, true);
5225 f_sleep(1.0);
5226
5227 f_ctrs_bsc_and_bts_init();
5228
5229 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5230 vc_conn.done;
5231
5232 /* from f_establish_fully() */
5233 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5234 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5235 /* from handover */
5236 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5237 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5238 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5239 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
5240 f_ctrs_bsc_and_bts_verify();
5241 f_shutdown_helper();
5242}
5243
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005244/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005245private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005246 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005247 var template MgcpResponse mgcp_resp;
5248 var MGCP_RecvFrom mrf;
5249 var template MgcpMessage msg_resp;
5250 var template MgcpMessage msg_dlcx := {
5251 command := tr_DLCX()
5252 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005253
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005254 if (g_pars.aoip) {
5255 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005256 log("Got first DLCX: ", mgcp);
5257 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005258 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005259
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005260 MGCP.receive(tr_DLCX()) -> value mgcp {
5261 log("Got second DLCX: ", mgcp);
5262 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5263 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005264 } else {
5265 /* For SCCPLite, BSC doesn't handle the MSC-side */
5266 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5267 log("Got first DLCX: ", mrf.msg.command);
5268 msg_resp := {
5269 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5270 }
5271 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5272 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005273 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005274}
5275
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005276private function f_ho_out_of_this_bsc(template (omit) BSSMAP_oldToNewBSSIEs exp_oldToNewBSSIEs := omit) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005277
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005278 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005279 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5280
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005281 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005282
5283 f_sleep(0.5);
5284 /* The MSC negotiates Handover Request and Handover Request Ack with
5285 * the other BSS and comes back with a BSSMAP Handover Command
5286 * containing an RR Handover Command coming from the target BSS... */
5287
5288 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5289 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5290 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5291 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5292 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5293
5294 /* expect the Handover Command to go out on RR */
5295 var RSL_Message rsl_ho_cmd
5296 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5297 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5298 var RSL_IE_Body rsl_ho_cmd_l3;
5299 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5300 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5301 setverdict(fail);
5302 } else {
5303 log("Found L3 Info: ", rsl_ho_cmd_l3);
5304 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5305 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5306 setverdict(fail);
5307 } else {
5308 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5309 setverdict(pass);
5310 }
5311 }
5312
5313 /* When the other BSS has reported a completed handover, this side is
5314 * torn down. */
5315
5316 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5317 var BssmapCause cause := enum2int(cause_val);
5318 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5319
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005320 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005321
5322 interleave {
5323 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5324 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5325 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005326 [] BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005327 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005328 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005329}
5330
5331private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5332 g_pars := f_gen_test_hdlr_pars();
5333 var PDU_BSSAP ass_req := f_gen_ass_req();
5334 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5335 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5336 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5337 f_establish_fully(ass_req, exp_compl);
5338
5339 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005340}
5341testcase TC_ho_out_of_this_bsc() runs on test_CT {
5342 var MSC_ConnHdlr vc_conn;
5343
5344 f_init(1, true);
5345 f_sleep(1.0);
5346
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005347 f_ctrs_bsc_and_bts_init();
5348
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005349 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5350 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005351
5352 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5353 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5354 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5355 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5356 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5357 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5358 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005359 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005360}
5361
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005362private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5363 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005364 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005365 octetstring l3 := '0123456789'O)
5366runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005367 /* The old lchan and conn should still be active. See that arbitrary L3
5368 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005369 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005370 var template PDU_BSSAP exp_data := {
5371 discriminator := '1'B,
5372 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005373 dlci := dlci,
5374 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005375 pdu := {
5376 dtap := l3
5377 }
5378 };
5379 BSSAP.receive(exp_data);
5380 setverdict(pass);
5381}
5382
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005383private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5384 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005385 template (value) OCT1 dlci := '00'O,
5386 octetstring l3 := '0123456789'O)
5387runs on MSC_ConnHdlr {
5388 BSSAP.send(PDU_BSSAP:{
5389 discriminator := '1'B,
5390 spare := '0000000'B,
5391 dlci := dlci,
5392 lengthIndicator := lengthof(l3),
5393 pdu := {
5394 dtap := l3
5395 }
5396 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005397 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005398 setverdict(pass);
5399}
5400
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005401/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5402 * simply never sends a BSSMAP Handover Command. */
5403private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005404 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005405
5406 var PDU_BSSAP ass_req := f_gen_ass_req();
5407 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5408 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5409 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5410 f_establish_fully(ass_req, exp_compl);
5411
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005412 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005413 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5414
5415 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5416
5417 /* osmo-bsc should time out 10 seconds after the handover started.
5418 * Let's give it a bit extra. */
5419 f_sleep(15.0);
5420
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005421 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005422 f_sleep(1.0);
5423}
5424testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5425 var MSC_ConnHdlr vc_conn;
5426
5427 f_init(1, true);
5428 f_sleep(1.0);
5429
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005430 f_ctrs_bsc_and_bts_init();
5431
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005432 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5433 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005434
5435 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5436 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5437 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5438 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5439 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5440 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5441 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005442 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005443}
5444
5445/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5446 * RR Handover Failure. */
5447private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005448 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005449
5450 var PDU_BSSAP ass_req := f_gen_ass_req();
5451 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5452 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5453 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5454 f_establish_fully(ass_req, exp_compl);
5455
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005456 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005457 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5458
5459 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5460
5461 f_sleep(0.5);
5462 /* The MSC negotiates Handover Request and Handover Request Ack with
5463 * the other BSS and comes back with a BSSMAP Handover Command
5464 * containing an RR Handover Command coming from the target BSS... */
5465
5466 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5467 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5468 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5469 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5470 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5471
5472 /* expect the Handover Command to go out on RR */
5473 var RSL_Message rsl_ho_cmd
5474 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5475 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5476 var RSL_IE_Body rsl_ho_cmd_l3;
5477 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5478 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5479 setverdict(fail);
5480 } else {
5481 log("Found L3 Info: ", rsl_ho_cmd_l3);
5482 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5483 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5484 setverdict(fail);
5485 } else {
5486 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5487 setverdict(pass);
5488 }
5489 }
5490
5491 f_sleep(0.2);
5492 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5493
5494 /* Should tell the MSC about the failure */
5495 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5496
5497 f_sleep(1.0);
5498
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005499 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005500 f_sleep(1.0);
5501
5502 setverdict(pass);
5503 f_sleep(1.0);
5504}
5505testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5506 var MSC_ConnHdlr vc_conn;
5507
5508 f_init(1, true);
5509 f_sleep(1.0);
5510
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005511 f_ctrs_bsc_and_bts_init();
5512
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005513 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5514 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005515
5516 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5517 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5518 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5519 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5520 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5521 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5522 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005523 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005524}
5525
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005526/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5527 * (neither BSSMAP Clear Command for success nor RR Handover Failure). 48.008 3.1.5.3.3 "Abnormal Conditions" applies
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005528 * and the lchan is released. */
5529private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005530 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005531
5532 var PDU_BSSAP ass_req := f_gen_ass_req();
5533 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5534 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5535 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5536 f_establish_fully(ass_req, exp_compl);
5537
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005538 f_bts_0_cfg(BSCVTY, {"neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005539 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5540
5541 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5542
5543 f_sleep(0.5);
5544 /* The MSC negotiates Handover Request and Handover Request Ack with
5545 * the other BSS and comes back with a BSSMAP Handover Command
5546 * containing an RR Handover Command coming from the target BSS... */
5547
5548 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5549 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5550 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5551 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5552 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5553
5554 /* expect the Handover Command to go out on RR */
5555 var RSL_Message rsl_ho_cmd
5556 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5557 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5558 var RSL_IE_Body rsl_ho_cmd_l3;
5559 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5560 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5561 setverdict(fail);
5562 } else {
5563 log("Found L3 Info: ", rsl_ho_cmd_l3);
5564 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5565 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5566 setverdict(fail);
5567 } else {
5568 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5569 setverdict(pass);
5570 }
5571 }
5572
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005573 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5574 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5575 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005576
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005577 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005578 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5579 log("Got BSSMAP Clear Request");
5580 /* Instruct BSC to clear channel */
5581 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5582 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5583
5584 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005585 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005586 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5587 log("Got Deact SACCH");
5588 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005589 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005590 log("Got RR Release");
5591 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005592 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005593 log("Got RF Chan Rel");
5594 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005595 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005596 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005597 }
5598
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005599 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005600 BSSAP.receive(tr_BSSMAP_ClearComplete);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005601
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005602 setverdict(pass);
5603 f_sleep(1.0);
5604}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005605testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005606 var MSC_ConnHdlr vc_conn;
5607
5608 f_init(1, true);
5609 f_sleep(1.0);
5610
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005611 f_ctrs_bsc_and_bts_init();
5612
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005613 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005614 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005615
5616 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5617 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5618 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5619 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5620 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5621 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5622 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005623 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005624}
5625
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005626private function f_ho_into_this_bsc(charstring id, template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit) runs on MSC_ConnHdlr {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005627 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5628 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5629 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5630 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5631 * before we get started. */
5632 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5633 f_rslem_register(0, new_chan_nr);
5634 g_chan_nr := new_chan_nr;
5635 f_sleep(1.0);
5636
5637 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5638 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5639 activate(as_Media());
5640
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005641 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005642 f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005643 oldToNewBSSIEs := oldToNewBSSIEs,
5644 enc := g_pars.encr)));
Harald Welte6811d102019-04-14 22:23:14 +02005645 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005646
5647 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5648
5649 var PDU_BSSAP rx_bssap;
5650 var octetstring ho_command_str;
5651
5652 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
Pau Espin Pedrol76ba5412019-06-10 11:00:33 +02005653
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005654 /* we're sure that the channel activation is done now, verify the encryption parameters in it */
5655 f_verify_encr_info(f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr));
5656
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005657 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5658 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5659 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5660 log("L3 Info in HO Request Ack is ", ho_command);
5661
5662 var GsmArfcn arfcn;
5663 var RslChannelNr actual_new_chan_nr;
5664 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5665 actual_new_chan_nr, arfcn);
5666
5667 if (actual_new_chan_nr != new_chan_nr) {
5668 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5669 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5670 setverdict(fail);
5671 return;
5672 }
5673 log("Handover Command chan_nr is", actual_new_chan_nr);
5674
5675 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5676 * tells the MS to handover to the new lchan. Here comes the new MS on
5677 * the new lchan with a Handover RACH: */
5678
5679 /* send handover detect */
5680
5681 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5682
5683 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5684
5685 /* send handover complete over the new channel */
5686
5687 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
5688 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
5689 enc_PDU_ML3_MS_NW(l3_tx)));
5690
5691 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005692 setverdict(pass);
5693}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005694
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005695private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005696 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005697 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
5698 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
5699 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005700 }
5701 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005702 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005703 } else {
5704 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005705 }
5706 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02005707 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005708 setverdict(pass);
5709}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005710function f_tc_ho_into_this_bsc_main(TestHdlrParams pars) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005711 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005712
5713 f_init(1, true);
5714 f_sleep(1.0);
5715
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005716 f_ctrs_bsc_and_bts_init();
5717
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005718 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5719 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005720
5721 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
5722 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005723
5724 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5725 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5726 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5727 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
5728 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005729}
5730
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005731testcase TC_ho_into_this_bsc() runs on test_CT {
5732 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5733 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005734 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005735}
5736
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02005737function f_tc_ho_into_this_bsc_a5(OCT1 encr_alg) runs on test_CT {
5738 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5739 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5740 f_tc_ho_into_this_bsc_main(pars);
5741 f_shutdown_helper();
5742}
5743
5744testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
5745 f_tc_ho_into_this_bsc_a5('01'O);
5746}
5747
5748testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
5749 f_tc_ho_into_this_bsc_a5('02'O);
5750}
5751
5752testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
5753 f_tc_ho_into_this_bsc_a5('08'O);
5754}
5755
5756testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
5757 f_tc_ho_into_this_bsc_a5('10'O);
5758}
5759
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005760testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
5761 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5762 pars.host_aoip_tla := "::6";
5763 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005764 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02005765}
5766
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005767/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005768 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005769 channel is later released (RR CHannel Release), should trigger inclusion of
5770 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
5771 neighbors. */
5772testcase TC_srvcc_eutran_to_geran() runs on test_CT {
5773 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5774 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005775 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005776 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005777
5778 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
5779 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
5780 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02005781 f_shutdown_helper();
5782}
5783
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005784/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
5785 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
5786 list when the channel is released. */
5787testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
5788 f_init_vty();
5789 f_vty_allow_srvcc_fast_return(true, 0)
5790
5791 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5792 pars.last_used_eutran_plmn := '323454'O;
5793 pars.exp_fast_return := false;
5794 f_tc_ho_into_this_bsc_main(pars);
5795 f_vty_allow_srvcc_fast_return(false, 0);
5796 f_shutdown_helper();
5797}
5798
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005799private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
5800 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
5801 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
5802 f_ho_into_this_bsc(id, oldToNewBSSIEs);
5803 f_ho_out_of_this_bsc(oldToNewBSSIEs);
5804 setverdict(pass);
5805}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005806
5807private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
5808 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005809 var MSC_ConnHdlr vc_conn;
5810 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5811
5812 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005813 if (disable_fast_return) {
5814 f_vty_allow_srvcc_fast_return(true, 0);
5815 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005816 f_sleep(1.0);
5817
5818 f_ctrs_bsc_and_bts_init();
5819
5820 pars.last_used_eutran_plmn := '323454'O;
5821 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5822 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
5823
5824 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
5825 vc_conn.done;
5826
5827 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
5828 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
5829 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
5830 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
5831 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
5832 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02005833
5834 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
5835 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005836 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005837
5838 if (disable_fast_return) {
5839 f_vty_allow_srvcc_fast_return(false, 0);
5840 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005841 f_shutdown_helper();
5842}
5843
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02005844/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
5845 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
5846 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
5847 IE with "Last Used E-UTRAN PLMN Id" from first step. */
5848testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
5849 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
5850}
5851/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
5852 * independently of fast-reture allowed/forbidden in local BTS */
5853testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
5854 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
5855}
5856
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005857private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
5858 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5859 f_rslem_register(0, new_chan_nr);
5860 g_chan_nr := new_chan_nr;
5861 f_sleep(1.0);
5862
5863 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5864 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5865 activate(as_Media());
5866
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005867 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005868 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005869 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005870
5871 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5872
5873 var PDU_BSSAP rx_bssap;
5874 var octetstring ho_command_str;
5875
5876 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5877
5878 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5879 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5880 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5881 log("L3 Info in HO Request Ack is ", ho_command);
5882
5883 var GsmArfcn arfcn;
5884 var RslChannelNr actual_new_chan_nr;
5885 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5886 actual_new_chan_nr, arfcn);
5887
5888 if (actual_new_chan_nr != new_chan_nr) {
5889 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5890 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5891 setverdict(fail);
5892 return;
5893 }
5894 log("Handover Command chan_nr is", actual_new_chan_nr);
5895
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02005896 /* For deterministic test results, give some time for the MGW endpoint to be configured */
5897 f_sleep(1.0);
5898
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005899 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5900 * tells the MS to handover to the new lchan. In this case, the MS
5901 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
5902 * Handover Failure to the MSC. The procedure according to 3GPP TS
5903 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
5904 * BSSMAP Clear Command: */
5905
5906 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
5907 var BssmapCause cause := enum2int(cause_val);
5908 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5909
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005910 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005911 BSSAP.receive(tr_BSSMAP_ClearComplete);
5912
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005913 setverdict(pass);
5914 f_sleep(1.0);
5915
5916 setverdict(pass);
5917}
5918testcase TC_ho_in_fail_msc_clears() runs on test_CT {
5919 var MSC_ConnHdlr vc_conn;
5920 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5921
5922 f_init(1, true);
5923 f_sleep(1.0);
5924
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005925 f_ctrs_bsc_and_bts_init();
5926
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005927 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
5928 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005929
5930 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
5931 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005932
5933 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5934 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5935 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
5936 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
5937 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005938 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005939}
5940
5941private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
5942 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
5943 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
5944 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
5945 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
5946 * before we get started. */
5947 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
5948 f_rslem_register(0, new_chan_nr);
5949 g_chan_nr := new_chan_nr;
5950 f_sleep(1.0);
5951
5952 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
5953 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
5954 activate(as_Media());
5955
Neels Hofmeyr90f80962020-06-12 16:16:55 +02005956 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005957 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02005958 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01005959
5960 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
5961
5962 var PDU_BSSAP rx_bssap;
5963 var octetstring ho_command_str;
5964
5965 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
5966
5967 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
5968 log("Received L3 Info in HO Request Ack: ", ho_command_str);
5969 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
5970 log("L3 Info in HO Request Ack is ", ho_command);
5971
5972 var GsmArfcn arfcn;
5973 var RslChannelNr actual_new_chan_nr;
5974 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
5975 actual_new_chan_nr, arfcn);
5976
5977 if (actual_new_chan_nr != new_chan_nr) {
5978 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
5979 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
5980 setverdict(fail);
5981 return;
5982 }
5983 log("Handover Command chan_nr is", actual_new_chan_nr);
5984
5985 /* Now the MSC forwards the RR Handover Command to the other BSC, which
5986 * tells the MS to handover to the new lchan. Here comes the new MS on
5987 * the new lchan with a Handover RACH: */
5988
5989 /* send handover detect */
5990
5991 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
5992
5993 BSSAP.receive(tr_BSSMAP_HandoverDetect);
5994
5995 /* The MSC chooses to clear the connection now, maybe we got the
5996 * Handover RACH on the new cell but the MS still signaled Handover
5997 * Failure to the old BSS? */
5998
5999 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6000 var BssmapCause cause := enum2int(cause_val);
6001 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6002
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006003 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006004 BSSAP.receive(tr_BSSMAP_ClearComplete);
6005
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006006 f_sleep(1.0);
6007}
6008testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6009 var MSC_ConnHdlr vc_conn;
6010 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6011
6012 f_init(1, true);
6013 f_sleep(1.0);
6014
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006015 f_ctrs_bsc_and_bts_init();
6016
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006017 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6018 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006019
6020 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6021 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006022
6023 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6024 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6025 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6026 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6027 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006028 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006029}
6030
6031/* The new BSS's lchan times out before the MSC decides that handover failed. */
6032private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6033 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6034 f_rslem_register(0, new_chan_nr);
6035 g_chan_nr := new_chan_nr;
6036 f_sleep(1.0);
6037
6038 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6039 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6040 activate(as_Media());
6041
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006042 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006043 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006044 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006045
6046 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6047
6048 var PDU_BSSAP rx_bssap;
6049 var octetstring ho_command_str;
6050
6051 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6052
6053 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6054 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6055 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6056 log("L3 Info in HO Request Ack is ", ho_command);
6057
6058 var GsmArfcn arfcn;
6059 var RslChannelNr actual_new_chan_nr;
6060 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6061 actual_new_chan_nr, arfcn);
6062
6063 if (actual_new_chan_nr != new_chan_nr) {
6064 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6065 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6066 setverdict(fail);
6067 return;
6068 }
6069 log("Handover Command chan_nr is", actual_new_chan_nr);
6070
6071 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6072 * tells the MS to handover to the new lchan. But the MS never shows up
6073 * on the new lchan. */
6074
6075 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6076
6077 /* Did osmo-bsc also send a Clear Request? */
6078 timer T := 0.5;
6079 T.start;
6080 alt {
6081 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6082 [] T.timeout { }
6083 }
6084
6085 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6086 * asked for it, this is a Handover Failure after all). */
6087
6088 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6089 var BssmapCause cause := enum2int(cause_val);
6090 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6091
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006092 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006093 BSSAP.receive(tr_BSSMAP_ClearComplete);
6094
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006095 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006096}
6097testcase TC_ho_in_fail_no_detect() runs on test_CT {
6098 var MSC_ConnHdlr vc_conn;
6099 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6100
6101 f_init(1, true);
6102 f_sleep(1.0);
6103
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006104 f_ctrs_bsc_and_bts_init();
6105
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006106 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6107 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006108
6109 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6110 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006111
6112 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6113 f_ctrs_bsc_and_bts_add(0, "handover:error");
6114 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6115 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6116 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006117 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006118}
6119
6120/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6121private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6122 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6123 f_rslem_register(0, new_chan_nr);
6124 g_chan_nr := new_chan_nr;
6125 f_sleep(1.0);
6126
6127 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6128 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6129 activate(as_Media());
6130
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006131 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006132 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006133 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006134
6135 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6136
6137 var PDU_BSSAP rx_bssap;
6138 var octetstring ho_command_str;
6139
6140 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6141
6142 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6143 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6144 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6145 log("L3 Info in HO Request Ack is ", ho_command);
6146
6147 var GsmArfcn arfcn;
6148 var RslChannelNr actual_new_chan_nr;
6149 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6150 actual_new_chan_nr, arfcn);
6151
6152 if (actual_new_chan_nr != new_chan_nr) {
6153 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6154 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6155 setverdict(fail);
6156 return;
6157 }
6158 log("Handover Command chan_nr is", actual_new_chan_nr);
6159
6160 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6161 * tells the MS to handover to the new lchan. But the MS never shows up
6162 * on the new lchan. */
6163
6164 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6165
6166 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006167 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006168
6169 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006170 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6171 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6172 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006173 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006174 BSSAP.receive(tr_BSSMAP_ClearComplete);
6175
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006176 f_sleep(1.0);
6177}
6178testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6179 var MSC_ConnHdlr vc_conn;
6180 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6181
6182 f_init(1, true);
6183 f_sleep(1.0);
6184
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006185 f_ctrs_bsc_and_bts_init();
6186
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006187 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6188 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006189
6190 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6191 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006192
6193 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6194 f_ctrs_bsc_and_bts_add(0, "handover:error");
6195 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6196 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6197 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006198 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006199}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006200
Neels Hofmeyr91401012019-07-11 00:42:35 +02006201type record of charstring Commands;
6202
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006203private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006204{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006205 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006206 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006207 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006208 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006209 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006210}
6211
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006212private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6213{
6214 f_vty_enter_cfg_cs7_inst(pt, 0);
6215 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6216 f_vty_transceive(pt, cmds[i]);
6217 }
6218 f_vty_transceive(pt, "end");
6219}
6220
Neels Hofmeyr91401012019-07-11 00:42:35 +02006221private function f_probe_for_handover(charstring log_label,
6222 charstring log_descr,
6223 charstring handover_vty_cmd,
6224 boolean expect_handover,
6225 boolean is_inter_bsc_handover := false)
6226runs on MSC_ConnHdlr
6227{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006228 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6229 * lchans to be established on bts 1 or bts 2. */
6230 f_rslem_suspend(RSL1_PROC);
6231 f_rslem_suspend(RSL2_PROC);
6232
Neels Hofmeyr91401012019-07-11 00:42:35 +02006233 var RSL_Message rsl;
6234
6235 var charstring log_msg := " (expecting handover)"
6236 if (not expect_handover) {
6237 log_msg := " (expecting NO handover)";
6238 }
6239 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6240 f_vty_transceive(BSCVTY, handover_vty_cmd);
6241
Neels Hofmeyr91401012019-07-11 00:42:35 +02006242 timer T := 2.0;
6243 T.start;
6244
6245 alt {
6246 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6247 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6248 log("Rx L3 from net: ", l3);
6249 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6250 var RslChannelNr new_chan_nr;
6251 var GsmArfcn arfcn;
6252 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6253 new_chan_nr, arfcn);
6254 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6255 log(l3.msgs.rrm.handoverCommand);
6256
6257 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6258 * matter on which BTS it really is, we're not going to follow through an entire handover
6259 * anyway. */
6260 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6261 f_rslem_resume(RSL1_PROC);
6262 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6263 f_rslem_resume(RSL2_PROC);
6264
6265 if (expect_handover and not is_inter_bsc_handover) {
6266 setverdict(pass);
6267 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6268 } else {
6269 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6270 & log_label & ": " & log_descr);
6271 }
6272
6273 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6274 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6275 * Handover Failure. */
6276 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6277
6278 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6279 f_sleep(0.5);
6280 RSL1.clear;
6281 RSL2.clear;
6282 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6283 break;
6284 } else {
6285 repeat;
6286 }
6287 }
6288 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6289 if (expect_handover and is_inter_bsc_handover) {
6290 setverdict(pass);
6291 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6292 } else {
6293 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6294 & log_label & ": " & log_descr);
6295 }
6296
6297 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6298
6299 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6300 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6301 * setting a short timeout and waiting is the only way. */
6302 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6303 f_sleep(1.5);
6304 log("f_probe_for_handover(" & log_label & "): ...done");
6305
6306 break;
6307 }
6308 [] T.timeout {
6309 if (expect_handover) {
6310 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6311 & log_label & ": " & log_descr);
6312 } else {
6313 setverdict(pass);
6314 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6315 }
6316 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6317 break;
6318 }
6319 }
6320
6321 f_rslem_resume(RSL1_PROC);
6322 f_rslem_resume(RSL2_PROC);
6323 f_sleep(3.0);
6324 RSL.clear;
6325
6326 log("f_probe_for_handover(" & log_label & "): done clearing");
6327}
6328
6329/* Test the effect of various neighbor configuration scenarios:
6330 *
6331 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6332 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6333 */
6334private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6335 g_pars := f_gen_test_hdlr_pars();
6336 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6337 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006338
6339 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6340 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6341
6342 /* Establish lchan at bts 0 */
6343 f_establish_fully(ass_cmd, exp_compl);
6344
6345 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6346 f_vty_enter_cfg_network(BSCVTY);
6347 f_vty_transceive(BSCVTY, "timer T7 1");
6348 f_vty_transceive(BSCVTY, "end");
6349}
6350
6351private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6352 f_tc_ho_neighbor_config_start();
6353
6354 /*
6355 * bts 0 ARFCN 871 BSIC 10
6356 * bts 1 ARFCN 871 BSIC 11
6357 * bts 2 ARFCN 871 BSIC 12
6358 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6359 */
6360
6361 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006362 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006363 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6364 "handover any to arfcn 871 bsic 11",
6365 true);
6366
6367 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6368 "handover any to arfcn 13 bsic 39",
6369 false);
6370
6371 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6372 "handover any to arfcn 871 bsic 12",
6373 false);
6374
6375 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6376 "handover any to arfcn 871 bsic 11",
6377 true);
6378}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006379testcase TC_ho_neighbor_config_1() runs on test_CT {
6380 var MSC_ConnHdlr vc_conn;
6381 f_init(3, true, guard_timeout := 60.0);
6382 f_sleep(1.0);
6383 f_ctrs_bsc_and_bts_init();
6384 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6385 vc_conn.done;
6386
6387 /* f_tc_ho_neighbor_config_start() */
6388 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6389 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6390
6391 /* 1.a */
6392 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6393 * handover quickly by sending a Handover Failure message. */
6394 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6395 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6396 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6397 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6398
6399 /* 1.b */
6400 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6401 f_ctrs_bsc_and_bts_add(0, "handover:error");
6402
6403 /* 1.c */
6404 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6405 f_ctrs_bsc_and_bts_add(0, "handover:error");
6406
6407 /* 1.d */
6408 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6409 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6410 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6411 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6412
6413 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006414 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006415}
6416
Neels Hofmeyr91401012019-07-11 00:42:35 +02006417private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6418 f_tc_ho_neighbor_config_start();
6419
6420 /*
6421 * bts 0 ARFCN 871 BSIC 10
6422 * bts 1 ARFCN 871 BSIC 11
6423 * bts 2 ARFCN 871 BSIC 12
6424 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6425 */
6426
6427 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006428 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006429 f_sleep(0.5);
6430
6431 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
6432 "handover any to arfcn 871 bsic 11",
6433 true);
6434
6435 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
6436 "handover any to arfcn 871 bsic 12",
6437 false);
6438}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006439testcase TC_ho_neighbor_config_2() runs on test_CT {
6440 var MSC_ConnHdlr vc_conn;
6441 f_init(3, true, guard_timeout := 50.0);
6442 f_sleep(1.0);
6443 f_ctrs_bsc_and_bts_init();
6444 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
6445 vc_conn.done;
6446
6447 /* f_tc_ho_neighbor_config_start() */
6448 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6449 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6450
6451 /* 2.a */
6452 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6453 * handover quickly by sending a Handover Failure message. */
6454 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6455 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6456 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6457 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6458
6459 /* 2.b */
6460 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6461 f_ctrs_bsc_and_bts_add(0, "handover:error");
6462
6463 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006464 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006465}
6466
Neels Hofmeyr91401012019-07-11 00:42:35 +02006467private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
6468 f_tc_ho_neighbor_config_start();
6469
6470 /*
6471 * bts 0 ARFCN 871 BSIC 10
6472 * bts 1 ARFCN 871 BSIC 11
6473 * bts 2 ARFCN 871 BSIC 12
6474 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6475 */
6476
6477 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006478 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006479 f_sleep(0.5);
6480
6481 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
6482 "handover any to arfcn 871 bsic 11",
6483 false);
6484 f_probe_for_handover("3.b", "HO to bts 2 works, explicitly listed as neighbor; no ambiguity because bts 3 is not listed as neighbor",
6485 "handover any to arfcn 871 bsic 12",
6486 true);
6487}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006488testcase TC_ho_neighbor_config_3() runs on test_CT {
6489 var MSC_ConnHdlr vc_conn;
6490 f_init(3, true, guard_timeout := 50.0);
6491 f_sleep(1.0);
6492 f_ctrs_bsc_and_bts_init();
6493 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
6494 vc_conn.done;
6495
6496 /* f_tc_ho_neighbor_config_start() */
6497 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6498 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6499
6500 /* 3.a */
6501 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6502 f_ctrs_bsc_and_bts_add(0, "handover:error");
6503
6504 /* 3.b */
6505 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6506 * handover quickly by sending a Handover Failure message. */
6507 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6508 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6509 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6510 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6511
6512 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006513 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006514}
6515
Neels Hofmeyr91401012019-07-11 00:42:35 +02006516private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
6517 f_tc_ho_neighbor_config_start();
6518
6519 /*
6520 * bts 0 ARFCN 871 BSIC 10
6521 * bts 1 ARFCN 871 BSIC 11
6522 * bts 2 ARFCN 871 BSIC 12
6523 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6524 */
6525
6526 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006527 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006528 f_sleep(0.5);
6529
6530 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
6531 "handover any to arfcn 871 bsic 11",
6532 false);
6533 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
6534 "handover any to arfcn 871 bsic 12",
6535 false);
6536 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
6537 "handover any to arfcn 123 bsic 45",
6538 true, true);
6539}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006540testcase TC_ho_neighbor_config_4() runs on test_CT {
6541 var MSC_ConnHdlr vc_conn;
6542 f_init(3, true, guard_timeout := 50.0);
6543 f_sleep(1.0);
6544 f_ctrs_bsc_and_bts_init();
6545 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
6546 vc_conn.done;
6547
6548 /* f_tc_ho_neighbor_config_start() */
6549 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6550 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6551
6552 /* 4.a */
6553 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6554 f_ctrs_bsc_and_bts_add(0, "handover:error");
6555
6556 /* 4.b */
6557 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6558 f_ctrs_bsc_and_bts_add(0, "handover:error");
6559
6560 /* 4.c */
6561 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6562 * handover quickly by timing out after the Handover Required message */
6563 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6564 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6565 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6566 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6567
6568 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006569 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006570}
6571
Neels Hofmeyr91401012019-07-11 00:42:35 +02006572private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
6573 f_tc_ho_neighbor_config_start();
6574
6575 /*
6576 * bts 0 ARFCN 871 BSIC 10
6577 * bts 1 ARFCN 871 BSIC 11
6578 * bts 2 ARFCN 871 BSIC 12
6579 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6580 */
6581
6582 log("f_tc_ho_neighbor_config: 5. explicit remote neighbor re-using ARFCN+BSIC: 'neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006583 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006584 f_sleep(0.5);
6585
6586 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
6587 "handover any to arfcn 871 bsic 12",
6588 true, true);
6589}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006590testcase TC_ho_neighbor_config_5() runs on test_CT {
6591 var MSC_ConnHdlr vc_conn;
6592 f_init(3, true);
6593 f_sleep(1.0);
6594 f_ctrs_bsc_and_bts_init();
6595 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
6596 vc_conn.done;
6597
6598 /* f_tc_ho_neighbor_config_start() */
6599 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6600 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6601
6602 /* 5 */
6603 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6604 * handover quickly by timing out after the Handover Required message */
6605 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6606 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6607 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6608 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6609
6610 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006611 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006612}
6613
Neels Hofmeyr91401012019-07-11 00:42:35 +02006614private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
6615 f_tc_ho_neighbor_config_start();
6616
6617 /*
6618 * bts 0 ARFCN 871 BSIC 10
6619 * bts 1 ARFCN 871 BSIC 11
6620 * bts 2 ARFCN 871 BSIC 12
6621 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6622 */
6623
6624 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
6625 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006626 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006627 f_sleep(0.5);
6628
6629 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
6630 "handover any to arfcn 871 bsic 12",
6631 false);
6632}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006633testcase TC_ho_neighbor_config_6() runs on test_CT {
6634 var MSC_ConnHdlr vc_conn;
6635 f_init(3, true);
6636 f_sleep(1.0);
6637 f_ctrs_bsc_and_bts_init();
6638 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
6639 vc_conn.done;
6640
6641 /* f_tc_ho_neighbor_config_start() */
6642 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6643 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6644
6645 /* 6.a */
6646 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6647 * handover quickly by timing out after the Handover Required message */
6648 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6649 f_ctrs_bsc_and_bts_add(0, "handover:error");
6650
6651 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006652 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006653}
6654
Neels Hofmeyr91401012019-07-11 00:42:35 +02006655private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
6656 f_tc_ho_neighbor_config_start();
6657
6658 /*
6659 * bts 0 ARFCN 871 BSIC 10
6660 * bts 1 ARFCN 871 BSIC 11
6661 * bts 2 ARFCN 871 BSIC 12
6662 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6663 */
6664
6665 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
6666 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006667 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006668 f_sleep(0.5);
6669
6670 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
6671 "handover any to arfcn 871 bsic 12",
6672 true);
6673 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
6674 "handover any to arfcn 123 bsic 45",
6675 true, true);
6676}
Neels Hofmeyr91401012019-07-11 00:42:35 +02006677testcase TC_ho_neighbor_config_7() runs on test_CT {
6678 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02006679 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006680 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006681 f_ctrs_bsc_and_bts_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006682 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
6683 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006684
6685 /* f_tc_ho_neighbor_config_start() */
6686 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6687 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6688
6689 /* 7.a */
6690 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6691 * handover quickly by sending a Handover Failure message. */
6692 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6693 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6694 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6695 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
6696
6697 /* 7.b */
6698 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
6699 * handover quickly by timing out after the Handover Required message */
6700 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6701 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6702 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6703 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6704
6705 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006706 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006707}
6708
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006709/* OS#3041: Open and close N connections in a normal fashion, and expect no
6710 * BSSMAP Reset just because of that. */
6711testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
6712 var default d;
6713 var integer i;
6714 var DchanTuple dt;
6715
6716 f_init();
6717
6718 /* Wait for initial BSSMAP Reset to pass */
6719 f_sleep(4.0);
6720
6721 d := activate(no_bssmap_reset());
6722
6723 /* Setup up a number of connections and RLSD them again from the MSC
6724 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6725 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02006726 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006727 /* Since we're doing a lot of runs, give each one a fresh
6728 * T_guard from the top. */
6729 T_guard.start;
6730
6731 /* Setup a BSSAP connection and clear it right away. This is
6732 * the MSC telling the BSC about a planned release, it's not an
6733 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006734 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01006735
6736 /* MSC disconnects (RLSD). */
6737 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
6738 }
6739
6740 /* In the buggy behavior, a timeout of 2 seconds happens between above
6741 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6742 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6743 f_sleep(4.0);
6744
6745 deactivate(d);
6746 f_shutdown_helper();
6747}
Harald Welte552620d2017-12-16 23:21:36 +01006748
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006749/* OS#3041: Open and close N connections in a normal fashion, and expect no
6750 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
6751 * the MSC. */
6752testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
6753 var default d;
6754 var integer i;
6755 var DchanTuple dt;
6756 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006757 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
6758 var BssmapCause cause := enum2int(cause_val);
6759
6760 f_init();
6761
6762 /* Wait for initial BSSMAP Reset to pass */
6763 f_sleep(4.0);
6764
6765 d := activate(no_bssmap_reset());
6766
6767 /* Setup up a number of connections and RLSD them again from the MSC
6768 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6769 * Let's do it some more times for good measure. */
6770 for (i := 0; i < 8; i := i+1) {
6771 /* Since we're doing a lot of runs, give each one a fresh
6772 * T_guard from the top. */
6773 T_guard.start;
6774
6775 /* Setup a BSSAP connection and clear it right away. This is
6776 * the MSC telling the BSC about a planned release, it's not an
6777 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02006778 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006779
6780 /* Instruct BSC to clear channel */
6781 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6782
6783 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006784 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01006785 }
6786
6787 /* In the buggy behavior, a timeout of 2 seconds happens between above
6788 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6789 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6790 f_sleep(4.0);
6791
6792 deactivate(d);
6793 f_shutdown_helper();
6794}
6795
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006796/* OS#3041: Open and close N connections in a normal fashion, and expect no
6797 * BSSMAP Reset just because of that. Close connections from the MS side with a
6798 * Release Ind on RSL. */
6799testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
6800 var default d;
6801 var integer i;
6802 var DchanTuple dt;
6803 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006804 var integer j;
6805
6806 f_init();
6807
6808 /* Wait for initial BSSMAP Reset to pass */
6809 f_sleep(4.0);
6810
6811 d := activate(no_bssmap_reset());
6812
6813 /* Setup up a number of connections and RLSD them again from the MSC
6814 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
6815 * Let's do it some more times for good measure. */
6816 for (i := 0; i < 8; i := i+1) {
6817 /* Since we're doing a lot of runs, give each one a fresh
6818 * T_guard from the top. */
6819 T_guard.start;
6820
6821 /* Setup a BSSAP connection and clear it right away. This is
6822 * the MSC telling the BSC about a planned release, it's not an
6823 * erratic loss of a connection. */
6824 dt := f_est_dchan('23'O, 23, '00010203040506'O);
6825
6826 /* simulate RLL REL IND */
6827 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
6828
6829 /* expect Clear Request on MSC side */
6830 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
6831
6832 /* Instruct BSC to clear channel */
6833 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
6834 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
6835
6836 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02006837 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01006838 }
6839
6840 /* In the buggy behavior, a timeout of 2 seconds happens between above
6841 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
6842 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
6843 f_sleep(4.0);
6844
6845 deactivate(d);
6846 f_shutdown_helper();
6847}
6848
Harald Welte94e0c342018-04-07 11:33:23 +02006849/***********************************************************************
6850 * IPA style dynamic PDCH
6851 ***********************************************************************/
6852
6853private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
6854 template (omit) RSL_Cause nack := omit)
6855runs on test_CT {
6856 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6857 var RSL_Message rsl_unused;
6858 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6859 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
6860 /* expect the BSC to issue the related RSL command */
6861 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6862 if (istemplatekind(nack, "omit")) {
6863 /* respond with a related acknowledgement */
6864 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6865 } else {
6866 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
6867 }
6868}
6869
6870private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
6871 template (omit) RSL_Cause nack := omit)
6872runs on test_CT {
6873 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
6874 var RSL_Message rsl_unused;
6875 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
6876 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
6877 /* expect the BSC to issue the related RSL command */
6878 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
6879 if (istemplatekind(nack, "omit")) {
6880 /* respond with a related acknowledgement */
6881 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
6882 } else {
6883 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
6884 }
6885}
6886
6887private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
6888runs on test_CT return charstring {
6889 var charstring cmd, resp;
6890 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01006891 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02006892}
6893
6894private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
6895 template charstring exp)
6896runs on test_CT {
6897 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
6898 if (not match(mode, exp)) {
6899 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02006900 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02006901 }
6902}
6903
6904private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
6905runs on test_CT {
6906 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
6907 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
6908 f_vty_transceive(BSCVTY, "end");
6909}
6910
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02006911
6912private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
6913 var integer i;
6914 for (i := 0; i < 8; i := i + 1) {
6915 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
6916 }
6917}
6918
Harald Welte94e0c342018-04-07 11:33:23 +02006919private const charstring TCHF_MODE := "TCH/F mode";
6920private const charstring TCHH_MODE := "TCH/H mode";
6921private const charstring PDCH_MODE := "PDCH mode";
6922private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02006923private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02006924
6925/* Test IPA PDCH activation / deactivation triggered by VTY */
6926testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
6927 var RSL_Message rsl_unused;
6928
6929 /* change Timeslot 6 before f_init() starts RSL */
6930 f_init_vty();
6931 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6932 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6933
6934 f_init(1, false);
6935 f_sleep(1.0);
6936
6937 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6938
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006939 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006940 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6941 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6942 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6943 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6944 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006945 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006946 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6947
6948 /* De-activate it via VTY */
6949 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6950 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006951 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006952 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6953
6954 /* re-activate it via VTY */
6955 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
6956 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006957 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006958 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6959
6960 /* and finally de-activate it again */
6961 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6962 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02006963 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02006964 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6965
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02006966 /* clean up config */
6967 f_ts_set_chcomb(0, 0, 6, "PDCH");
6968
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006969 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02006970}
6971
6972/* Test IPA PDCH activation NACK */
6973testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
6974 var RSL_Message rsl_unused;
6975
6976 /* change Timeslot 6 before f_init() starts RSL */
6977 f_init_vty();
6978 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
6979 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6980
6981 f_init(1, false);
6982 f_sleep(1.0);
6983
6984 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
6985
6986 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6987 /* The BSC will activate the dynamic PDCH by default, so confirm that */
6988 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
6989 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
6990 f_sleep(1.0);
6991 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
6992
6993 /* De-activate it via VTY */
6994 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
6995 f_sleep(1.0);
6996 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
6997
6998 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
6999 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7000 f_sleep(1.0);
7001 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7002
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007003 /* clean up config */
7004 f_ts_set_chcomb(0, 0, 6, "PDCH");
7005
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007006 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007007}
7008
7009
7010/***********************************************************************
7011 * Osmocom style dynamic PDCH
7012 ***********************************************************************/
7013
7014private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7015 template (omit) RSL_Cause nack := omit)
7016runs on test_CT {
7017 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7018 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007019 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007020 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7021 /* expect the BSC to issue the related RSL command */
7022 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7023 if (istemplatekind(nack, "omit")) {
7024 /* respond with a related acknowledgement */
7025 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7026 } else {
7027 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7028 }
7029}
7030
7031private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7032 template (omit) RSL_Cause nack := omit)
7033runs on test_CT {
7034 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7035 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007036 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007037 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7038 /* expect the BSC to issue the related RSL command */
7039 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7040 if (istemplatekind(nack, "omit")) {
7041 /* respond with a related acknowledgement */
7042 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7043 } else {
7044 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7045 }
7046}
7047
7048/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7049testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7050 var RSL_Message rsl_unused;
7051
7052 /* change Timeslot 6 before f_init() starts RSL */
7053 f_init_vty();
7054 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7055 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7056
7057 f_init(1, false);
7058 f_sleep(1.0);
7059
7060 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7061
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007062 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007063 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7064 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7065 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7066
7067 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7068 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007069 log("TCH/F_TCH/H_PDCH requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
Harald Welte94e0c342018-04-07 11:33:23 +02007070 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7071
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007072 /* clean up config */
7073 f_ts_set_chcomb(0, 0, 6, "PDCH");
7074
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007075 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007076}
7077
7078/* Test Osmocom dyn PDCH activation NACK behavior */
7079testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7080 var RSL_Message rsl_unused;
7081
7082 /* change Timeslot 6 before f_init() starts RSL */
7083 f_init_vty();
7084 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7085 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7086
7087 f_init(1, false);
7088 f_sleep(1.0);
7089
7090 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7091
7092 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7093 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7094 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
7095
7096 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7097 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7098 f_sleep(1.0);
7099 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7100
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007101 /* clean up config */
7102 f_ts_set_chcomb(0, 0, 6, "PDCH");
7103
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007104 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007105}
7106
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007107/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7108testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7109 var RSL_Message rsl_unused, rsl_msg;
7110 var DchanTuple dt;
7111 var BSSAP_N_CONNECT_ind rx_c_ind;
7112
7113 /* change Timeslot 6 before f_init() starts RSL */
7114 f_init_vty();
7115 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7116 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7117
7118 f_init(1, false);
7119 f_sleep(1.0);
7120
7121 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7122
7123 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7124 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7125 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7126 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7127
7128 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7129 f_sleep(1.0);
7130 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7131 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7132
7133 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7134 * on CCCH+SDCCH4+CBCH) */
7135 var integer i;
7136 for (i := 0; i < 3; i := i + 1) {
7137 dt := f_est_dchan('23'O, i, '00010203040506'O);
7138 }
7139
7140 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7141 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7142 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7143 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7144
7145 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7146 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7147
7148 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7149 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7150 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7151 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7152
7153 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7154 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7155 dt.sccp_conn_id := rx_c_ind.connectionId;
7156 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7157
7158 /* Instruct BSC to clear channel */
7159 var BssmapCause cause := 0;
7160 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7161 f_exp_chan_rel_and_clear(dt, 0);
7162
7163 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7164 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7165 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7166 f_sleep(1.0);
7167 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7168
7169 /* clean up config */
7170 f_ts_set_chcomb(0, 0, 6, "PDCH");
7171
7172 f_shutdown_helper();
7173}
7174
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007175/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7176 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7177 it as TCH directly instead. SYS#5309. */
7178testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7179 var RSL_Message rsl_unused, rsl_msg;
7180 var DchanTuple dt;
7181 var BSSAP_N_CONNECT_ind rx_c_ind;
7182 var integer i;
7183
7184 /* change Timeslot 6 before f_init() starts RSL */
7185 f_init_vty();
7186 for (i := 1; i < 8; i := i + 1) {
7187 if (i == 6) {
7188 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7189 } else {
7190 f_ts_set_chcomb(0, 0, i, "PDCH");
7191 }
7192 }
7193 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7194
7195 f_init(1, false);
7196 f_sleep(1.0);
7197
7198 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7199
7200 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7201 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7202 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7203 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7204
7205 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7206 f_sleep(1.0);
7207 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7208 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7209
7210 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7211 * on CCCH+SDCCH4+CBCH) */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007212 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007213 for (i := 0; i < 3; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007214 dt := f_est_dchan(ra, i, '00010203040506'O);
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007215 }
7216
7217 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007218 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007219 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7220 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7221
7222 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7223 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7224
7225 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7226 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7227 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7228 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7229
7230 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7231 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7232 dt.sccp_conn_id := rx_c_ind.connectionId;
7233 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7234
7235 /* Instruct BSC to clear channel */
7236 var BssmapCause cause := 0;
7237 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7238 f_exp_chan_rel_and_clear(dt, 0);
7239
7240 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7241 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7242 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7243 f_sleep(1.0);
7244 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7245
7246 /* clean up config */
7247 f_ts_reset_chcomb(0);
7248 /* TODO: clean up other channels? */
7249
7250 f_shutdown_helper();
7251}
7252
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007253/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7254testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7255 var RSL_Message rsl_unused, rsl_msg;
7256 var DchanTuple dt;
7257 var BSSAP_N_CONNECT_ind rx_c_ind;
7258 var GsmRrMessage rr;
7259
7260 /* change Timeslot 6 before f_init() starts RSL */
7261 f_init_vty();
7262 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7263 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7264
7265 f_init(1, false);
7266 f_sleep(1.0);
7267
7268 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7269
7270 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7271 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7272 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7273 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7274
7275 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7276 f_sleep(1.0);
7277 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7278 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7279
7280 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7281 * on CCCH+SDCCH4+CBCH) */
7282 var integer i;
7283 for (i := 0; i < 3; i := i + 1) {
7284 dt := f_est_dchan('23'O, i, '00010203040506'O);
7285 }
7286
7287 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7288 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7289 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7290 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7291
7292 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7293 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7294
7295 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7296 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7297 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7298 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7299 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7300 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7301 }
7302
7303 /* FIXME? Currently the TS stays in state BORKEN: */
7304
7305 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
7306 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr, ?));
7307 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7308 * f_sleep(1.0);
7309 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7310 */
7311
7312 /* clean up config */
7313 f_ts_set_chcomb(0, 0, 6, "PDCH");
7314
7315 f_shutdown_helper();
7316}
7317
Stefan Sperling0796a822018-10-05 13:01:39 +02007318testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007319 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007320 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7321 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7322 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007323 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007324}
7325
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007326testcase TC_chopped_ipa_payload() runs on test_CT {
7327 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7328 /* TODO: mp_bsc_ctrl_port does not work yet */};
7329 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7330 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7331 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007332 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007333}
7334
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007335/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7336 the BTS does autonomous MS power control loop */
7337testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7338 var MSC_ConnHdlr vc_conn;
7339 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7340 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7341 pars.exp_ms_power_params := true;
7342
7343 f_init(1, true);
7344 f_sleep(1.0);
7345 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
7346 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007347 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007348}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007349
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02007350/* Verify activation and deactivation of the BCCH carrier power reduction mode */
7351testcase TC_c0_power_red_mode() runs on test_CT {
7352 f_init(1);
7353
7354 for (var integer red := 6; red >= 0; red := red - 2) {
7355 /* Configure BCCH carrier power reduction mode via the VTY */
7356 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
7357
7358 /* Expect Osmocom specific BS Power Control message on the RSL */
7359 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
7360 chan_nr := t_RslChanNr_BCCH(0),
7361 bs_power := tr_RSL_IE_BS_Power(red / 2));
7362 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
7363 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
7364
7365 /* Additionally verify the applied value over the CTRL interface */
7366 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
7367 if (cred != int2str(red)) {
7368 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
7369 cred, " (expected ", red, ")");
7370 }
7371 }
7372
7373 f_shutdown_helper();
7374}
7375
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007376/***********************************************************************
7377 * MSC Pooling
7378 ***********************************************************************/
7379
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007380template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01007381 ts_MI_TMSI_LV(tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v, nri_bitlen := nri_bitlen));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007382
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007383private function f_expect_lchan_rel(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt, template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007384runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007385 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007386 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007387 f_logp(BSCVTY, "Got RSL RR Release");
7388 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007389 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007390 f_logp(BSCVTY, "Got RSL Deact SACCH");
7391 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007392 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007393 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007394 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7395 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02007396 break;
7397 }
7398 }
7399}
7400
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007401friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
7402 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02007403runs on MSC_ConnHdlr {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007404 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007405 BSSAP.send(ts_BSSMAP_ClearCommand(0));
7406 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007407 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007408 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007409 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007410 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007411 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007412 }
7413 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007414 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007415 /* Also drop the SCCP connection */
7416 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
7417 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02007418 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007419 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007420 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
7421 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007422 }
7423 }
7424}
7425
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007426private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
7427 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007428runs on MSC_ConnHdlr {
7429 timer T := 10.0;
7430 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
7431
Neels Hofmeyr767548a2020-08-09 20:26:07 +00007432 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007433 f_create_bssmap_exp(l3_enc);
7434
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007435 /* RSL_Emulation.f_chan_est() on rsl_pt:
7436 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007437 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
7438 */
7439 var RSL_Message rx_rsl;
7440 var GsmRrMessage rr;
7441
7442 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007443 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007444 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007445 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007446 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
7447 */
7448 timer Tt := 10.0;
7449
7450 /* request a channel to be established */
7451 Tt.start;
7452 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007453 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007454 Tt.stop;
7455 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007456 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007457 setverdict(fail, "Unexpected RSL message on DCHAN");
7458 mtc.stop;
7459 }
7460 [] Tt.timeout {
7461 setverdict(fail, "Timeout waiting for RSL on DCHAN");
7462 mtc.stop;
7463 }
7464 }
7465 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
7466 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007467 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007468
7469
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007470 if (expect_bssmap_l3) {
7471 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
7472 var template PDU_BSSAP exp_l3_compl;
7473 exp_l3_compl := tr_BSSMAP_ComplL3()
7474 if (g_pars.aoip == false) {
7475 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
7476 } else {
7477 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
7478 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007479
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007480 var PDU_BSSAP bssap;
7481 T.start;
7482 alt {
7483 [] BSSAP.receive(exp_l3_compl) -> value bssap {
7484 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
7485 log("rx exp_l3_compl = ", bssap);
7486 }
7487 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
7488 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
7489 }
7490 [] T.timeout {
7491 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
7492 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007493 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007494
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007495 /* start ciphering, if requested */
7496 if (ispresent(g_pars.encr)) {
7497 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007498 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00007499 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007500 }
7501
7502 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007503 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007504 }
7505 setverdict(pass);
7506 f_sleep(1.0);
7507}
7508
7509private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
7510 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7511 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007512 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007513 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007514 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007515 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007516 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007517 }
7518}
7519
7520/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
7521private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
7522 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007523 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
7524 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
7525 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
7526 f_perform_compl_l3(RSL, RSL_PROC, ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_IMSI_LV('001010000000004'H))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007527}
7528testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
7529
7530 f_init(1, true);
7531 f_sleep(1.0);
7532 var MSC_ConnHdlr vc_conn;
7533 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007534
7535 f_ctrs_msc_init();
7536
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007537 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
7538 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007539
7540 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007541 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007542}
7543
7544/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
7545/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7546 * just as well using only RSL. */
7547testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
7548
7549 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7550 f_sleep(1.0);
7551
7552 /* Control which MSC gets chosen next by the round-robin, otherwise
7553 * would be randomly affected by which other tests ran before this. */
7554 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7555
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007556 f_ctrs_msc_init();
7557
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007558 var MSC_ConnHdlr vc_conn1;
7559 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7560 pars1.mscpool.rsl_idx := 0;
7561 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
7562 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7563 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007564 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007565
7566 var MSC_ConnHdlr vc_conn2;
7567 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7568 pars2.mscpool.rsl_idx := 1;
7569 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
7570 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7571 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007572 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007573
7574 /* Test round-robin wrap to the first MSC */
7575 var MSC_ConnHdlr vc_conn3;
7576 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7577 pars3.mscpool.rsl_idx := 2;
7578 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
7579 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7580 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007581 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007582 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007583}
7584
7585/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
7586 * (configured in osmo-bsc.cfg). */
7587/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7588 * just as well using only RSL. */
7589testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
7590
7591 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7592 f_sleep(1.0);
7593
7594 /* Control which MSC gets chosen next by the round-robin, otherwise
7595 * would be randomly affected by which other tests ran before this. */
7596 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7597
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007598 f_ctrs_msc_init();
7599
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007600 var MSC_ConnHdlr vc_conn1;
7601 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7602 pars1.mscpool.rsl_idx := 0;
7603 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7604 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7605 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007606 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007607
7608 var MSC_ConnHdlr vc_conn2;
7609 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7610 pars2.mscpool.rsl_idx := 1;
7611 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7612 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7613 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007614 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007615
7616 /* Test round-robin wrap to the first MSC */
7617 var MSC_ConnHdlr vc_conn3;
7618 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7619 pars3.mscpool.rsl_idx := 2;
7620 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
7621 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7622 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007623 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007624 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007625}
7626
7627/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
7628 * (configured in osmo-bsc.cfg). In this case, one of the MSC also has the NULL-NRI as part of its owned NRIs, but the
7629 * NULL-NRI setting is stronger than that. */
7630/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7631 * just as well using only RSL. */
7632testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
7633
7634 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7635 f_sleep(1.0);
7636
7637 /* Control which MSC gets chosen next by the round-robin, otherwise
7638 * would be randomly affected by which other tests ran before this. */
7639 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7640
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007641 f_ctrs_msc_init();
7642
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007643 var MSC_ConnHdlr vc_conn1;
7644 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7645 pars1.mscpool.rsl_idx := 0;
7646 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7647 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7648 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007649 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007650
7651 var MSC_ConnHdlr vc_conn2;
7652 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7653 pars2.mscpool.rsl_idx := 1;
7654 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7655 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7656 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007657 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007658
7659 /* Test round-robin wrap to the first MSC */
7660 var MSC_ConnHdlr vc_conn3;
7661 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7662 pars3.mscpool.rsl_idx := 2;
7663 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
7664 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7665 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007666 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007667 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007668}
7669
7670/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
7671 * assigned to any MSC (configured in osmo-bsc.cfg). */
7672/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7673 * just as well using only RSL. */
7674testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
7675
7676 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7677 f_sleep(1.0);
7678
7679 /* Control which MSC gets chosen next by the round-robin, otherwise
7680 * would be randomly affected by which other tests ran before this. */
7681 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7682
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007683 f_ctrs_msc_init();
7684
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007685 var MSC_ConnHdlr vc_conn1;
7686 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7687 pars1.mscpool.rsl_idx := 0;
7688 /* An NRI that is not assigned to any MSC */
7689 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
7690 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7691 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007692 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007693
7694 var MSC_ConnHdlr vc_conn2;
7695 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7696 pars2.mscpool.rsl_idx := 1;
7697 /* An NRI that is not assigned to any MSC */
7698 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
7699 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7700 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007701 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007702
7703 /* Test round-robin wrap to the first MSC */
7704 var MSC_ConnHdlr vc_conn3;
7705 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7706 pars3.mscpool.rsl_idx := 2;
7707 /* An NRI that is not assigned to any MSC */
7708 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
7709 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7710 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007711 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007712 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007713}
7714
7715/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
7716 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
7717/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7718 * just as well using only RSL. */
7719testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
7720
7721 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7722 f_sleep(1.0);
7723
7724 /* Control which MSC gets chosen next by the round-robin, otherwise
7725 * would be randomly affected by which other tests ran before this. */
7726 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7727
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007728 f_ctrs_msc_init();
7729
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007730 var MSC_ConnHdlr vc_conn1;
7731 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7732 pars1.mscpool.rsl_idx := 0;
7733 /* An NRI that is assigned to an unconnected MSC */
7734 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
7735 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7736 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007737 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7738 f_ctrs_msc_add(0, "mscpool:subscr:new");
7739 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007740
7741 var MSC_ConnHdlr vc_conn2;
7742 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7743 pars2.mscpool.rsl_idx := 1;
7744 /* An NRI that is assigned to an unconnected MSC */
7745 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
7746 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7747 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007748 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7749 f_ctrs_msc_add(1, "mscpool:subscr:new");
7750 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007751
7752 /* Test round-robin wrap to the first MSC */
7753 var MSC_ConnHdlr vc_conn3;
7754 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
7755 pars3.mscpool.rsl_idx := 2;
7756 /* An NRI that is assigned to an unconnected MSC */
7757 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
7758 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7759 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007760 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
7761 f_ctrs_msc_add(0, "mscpool:subscr:new");
7762 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007763 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007764}
7765
7766/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
7767 * osmo-bsc.cfg). */
7768/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7769 * just as well using only RSL. */
7770testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
7771
7772 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
7773 f_sleep(1.0);
7774
7775 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
7776 * this is not using round-robin. */
7777 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7778
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007779 f_ctrs_msc_init();
7780
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007781 var MSC_ConnHdlr vc_conn1;
7782 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
7783 pars1.mscpool.rsl_idx := 0;
7784 /* An NRI of the second MSC's range (256-511) */
7785 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
7786 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7787 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007788 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007789
7790 var MSC_ConnHdlr vc_conn2;
7791 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
7792 pars2.mscpool.rsl_idx := 1;
7793 /* An NRI of the second MSC's range (256-511) */
7794 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
7795 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7796 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007797 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007798
7799 var MSC_ConnHdlr vc_conn3;
7800 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7801 pars3.mscpool.rsl_idx := 2;
7802 /* An NRI of the second MSC's range (256-511) */
7803 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
7804 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7805 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007806 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007807 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007808}
7809
7810/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
7811 * while a round-robin remains unaffected by that. */
7812/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7813 * just as well using only RSL. */
7814testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
7815
7816 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7817 f_sleep(1.0);
7818
7819 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
7820 * this is not using round-robin. */
7821 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7822
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007823 f_ctrs_msc_init();
7824
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007825 var MSC_ConnHdlr vc_conn1;
7826 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
7827 pars1.mscpool.rsl_idx := 0;
7828 /* An NRI of the third MSC's range (512-767) */
7829 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
7830 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7831 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007832 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007833
7834 var MSC_ConnHdlr vc_conn2;
7835 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7836 pars2.mscpool.rsl_idx := 1;
7837 /* An NRI of the third MSC's range (512-767) */
7838 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
7839 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7840 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007841 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007842
7843 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
7844 var MSC_ConnHdlr vc_conn3;
7845 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
7846 pars3.mscpool.rsl_idx := 2;
7847 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
7848 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
7849 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007850 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007851 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007852}
7853
7854/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
7855/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7856 * just as well using only RSL. */
7857testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
7858
7859 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7860 f_sleep(1.0);
7861
7862 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
7863 * instead, and hits msc 0. */
7864 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
7865
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007866 f_ctrs_msc_init();
7867
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007868 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
7869 var MSC_ConnHdlr vc_conn1;
7870 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7871 pars1.mscpool.rsl_idx := 0;
7872 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
7873 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
7874 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007875 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007876
7877 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
7878 var MSC_ConnHdlr vc_conn2;
7879 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
7880 pars2.mscpool.rsl_idx := 1;
7881 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
7882 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
7883 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007884 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007885 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007886}
7887
7888/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
7889 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7890private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
7891 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7892 //cid_list := { cIl_allInBSS := ''O };
7893 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7894 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7895 var BSSAP_N_UNITDATA_req paging;
7896 var hexstring imsi := '001010000000123'H;
7897
7898 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7899
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007900 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007901 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
7902 BSSAP.send(paging);
7903
7904 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7905 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7906 * channel number is picked here. */
7907 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7908 f_rslem_register(0, new_chan_nr);
7909 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
7910 f_rslem_unregister(0, new_chan_nr);
7911
7912 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
7913 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007914 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007915 f_sleep(1.0);
7916}
7917testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
7918 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7919 f_sleep(1.0);
7920
7921 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7922 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7923 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
7924
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007925 f_ctrs_msc_init();
7926
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007927 var MSC_ConnHdlr vc_conn1;
7928 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7929 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007930 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7931 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007932 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
7933 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007934 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007935 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007936}
7937
7938/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
7939 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
7940private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
7941 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
7942 //cid_list := { cIl_allInBSS := ''O };
7943 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
7944 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
7945 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01007946 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007947 var BSSAP_N_UNITDATA_req paging;
7948
7949 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
7950
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007951 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007952 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
7953 BSSAP.send(paging);
7954
7955 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
7956 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
7957 * channel number is picked here. */
7958 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
7959 f_rslem_register(0, new_chan_nr);
7960 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
7961 f_rslem_unregister(0, new_chan_nr);
7962
7963 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
7964 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
7965 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02007966 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(nri_v))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007967 f_sleep(1.0);
7968}
7969testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
7970 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
7971 f_sleep(1.0);
7972
7973 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
7974 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
7975 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
7976
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007977 f_ctrs_msc_init();
7978
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007979 var MSC_ConnHdlr vc_conn1;
7980 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
7981 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02007982 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
7983 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007984 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
7985 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02007986 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007987 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007988}
7989
7990/* For round-robin, skip an MSC that has 'no allow-attach' set. */
7991/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
7992 * just as well using only RSL. */
7993testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
7994
7995 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
7996 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00007997 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
7998 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02007999
8000 /* Control which MSC gets chosen next by the round-robin, otherwise
8001 * would be randomly affected by which other tests ran before this. */
8002 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8003
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008004 f_ctrs_msc_init();
8005
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008006 var MSC_ConnHdlr vc_conn1;
8007 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8008 pars1.mscpool.rsl_idx := 0;
8009 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8010 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8011 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008012 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008013
8014 var MSC_ConnHdlr vc_conn2;
8015 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8016 pars2.mscpool.rsl_idx := 1;
8017 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8018 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8019 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008020 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008021
8022 var MSC_ConnHdlr vc_conn3;
8023 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8024 pars3.mscpool.rsl_idx := 2;
8025 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8026 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8027 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008028 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008029 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008030}
8031
8032/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8033 * TMSI NRI. */
8034testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8035
8036 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8037 f_sleep(1.0);
8038
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008039 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8040 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8041
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008042 /* Control which MSC gets chosen next by the round-robin, otherwise
8043 * would be randomly affected by which other tests ran before this. */
8044 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8045
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008046 f_ctrs_msc_init();
8047
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008048 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8049 var MSC_ConnHdlr vc_conn1;
8050 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8051 pars1.mscpool.rsl_idx := 0;
8052 /* An NRI of the second MSC's range (256-511) */
8053 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8054 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8055 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008056 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008057
8058 var MSC_ConnHdlr vc_conn2;
8059 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8060 pars2.mscpool.rsl_idx := 1;
8061 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8062 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8063 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008064 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008065
8066 var MSC_ConnHdlr vc_conn3;
8067 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8068 pars3.mscpool.rsl_idx := 2;
8069 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8070 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8071 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008072 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008073 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008074}
8075
Philipp Maier783681c2020-07-16 16:47:06 +02008076/* Allow/Deny emergency calls globally via VTY */
8077private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8078 f_vty_enter_cfg_msc(BSCVTY, 0);
8079 if (allow) {
8080 f_vty_transceive(BSCVTY, "allow-emergency allow");
8081 } else {
8082 f_vty_transceive(BSCVTY, "allow-emergency deny");
8083 }
8084 f_vty_transceive(BSCVTY, "exit");
8085 f_vty_transceive(BSCVTY, "exit");
8086}
8087
8088/* Allow/Deny emergency calls per BTS via VTY */
8089private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8090 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8091 if (allow) {
8092 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8093 } else {
8094 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8095 }
8096 f_vty_transceive(BSCVTY, "exit");
8097 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008098 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008099}
8100
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008101/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8102private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8103 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8104 if (allow) {
8105 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8106 } else {
8107 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8108 }
8109 f_vty_transceive(BSCVTY, "exit");
8110 f_vty_transceive(BSCVTY, "exit");
8111 f_vty_transceive(BSCVTY, "exit");
8112}
8113
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008114/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8115private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8116 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8117 if (allow) {
8118 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8119 } else {
8120 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8121 }
8122 f_vty_transceive(BSCVTY, "exit");
8123 f_vty_transceive(BSCVTY, "exit");
8124 f_vty_transceive(BSCVTY, "exit");
8125}
8126
Philipp Maier783681c2020-07-16 16:47:06 +02008127/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8128private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8129 var PDU_ML3_MS_NW emerg_setup;
8130 var octetstring emerg_setup_enc;
8131 var RSL_Message emerg_setup_data_ind;
8132
8133 f_establish_fully(omit, omit);
8134
8135 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8136 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8137 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8138
8139 RSL.send(emerg_setup_data_ind);
8140}
8141
8142/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8143 * CALLS are permitted by the BSC config. */
8144private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8145 var PDU_BSSAP emerg_setup_data_ind_bssap;
8146 var PDU_ML3_MS_NW emerg_setup;
8147 timer T := 3.0;
8148
8149 f_assignment_emerg_setup()
8150
8151 T.start;
8152 alt {
8153 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8154 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8155 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8156 setverdict(fail, "no emergency setup");
8157 }
8158 }
8159 [] BSSAP.receive {
8160 setverdict(fail, "unexpected BSSAP message!");
8161 }
8162 [] T.timeout {
8163 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8164 }
8165 }
8166
8167 setverdict(pass);
8168}
8169
8170/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8171 * forbidden by the BSC config. */
8172private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8173 var PDU_BSSAP emerg_setup_data_ind_bssap;
8174 timer T := 3.0;
8175
8176 f_assignment_emerg_setup()
8177
8178 T.start;
8179 alt {
8180 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8181 setverdict(pass);
8182 }
8183 [] RSL.receive {
8184 setverdict(fail, "unexpected RSL message!");
8185 }
8186 [] T.timeout {
8187 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8188 }
8189 }
8190}
8191
8192/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8193testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8194 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8195 var MSC_ConnHdlr vc_conn;
8196
8197 f_init(1, true);
8198 f_sleep(1.0);
8199
8200 f_vty_allow_emerg_msc(true);
8201 f_vty_allow_emerg_bts(true, 0);
8202 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8203 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008204 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008205}
8206
8207/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8208testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8209 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8210 var MSC_ConnHdlr vc_conn;
8211
8212 f_init(1, true);
8213 f_sleep(1.0);
8214
8215 f_vty_allow_emerg_msc(false);
8216 f_vty_allow_emerg_bts(true, 0);
8217 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8218 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008219 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008220}
8221
8222/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8223testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8224 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8225 var MSC_ConnHdlr vc_conn;
8226
8227 /* Note: This simulates a spec violation by the MS, correct MS
8228 * implementations would not try to establish an emergency call because
8229 * the system information tells in advance that emergency calls are
8230 * not forbidden */
8231
8232 f_init(1, true);
8233 f_sleep(1.0);
8234
8235 f_vty_allow_emerg_msc(true);
8236 f_vty_allow_emerg_bts(false, 0);
8237 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8238 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008239 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008240}
8241
Philipp Maier82812002020-08-13 18:48:27 +02008242/* Test what happens when an emergency call arrives while all TCH channels are
8243 * busy, the BSC is expected to terminate one call in favor of the incoming
8244 * emergency call */
8245testcase TC_emerg_premption() runs on test_CT {
8246 var ASP_RSL_Unitdata rsl_ud;
8247 var integer i;
8248 var integer chreq_total, chreq_nochan;
8249 var RSL_Message rx_rsl;
8250 var RslChannelNr chan_nr;
8251
8252 f_init(1);
8253 f_sleep(1.0);
8254
8255 f_vty_allow_emerg_msc(true);
8256 f_vty_allow_emerg_bts(true, 0);
8257
8258 /* Fill up all channels on the BTS */
8259 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8260 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8261 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8262 chan_nr := f_chreq_act_ack('33'O, i);
8263 }
8264 IPA_RSL[0].clear;
8265 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8266 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8267
8268 /* Send Channel request for emegergency call */
8269 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8270
8271 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8272 chan_nr := valueof(t_RslChanNr_Bm(1));
8273 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8274
8275 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8276 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8277 chan_nr := rx_rsl.ies[0].body.chan_nr;
8278 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
8279 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02008280
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008281 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008282}
8283
8284/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07008285private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008286private type record FHParamsTs {
8287 boolean enabled,
8288 uint6_t hsn,
8289 uint6_t maio,
8290 ArfcnList ma
8291};
8292
8293/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008294private type record FHParamsTrx {
8295 GsmArfcn arfcn,
8296 FHParamsTs ts[8]
8297};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008298
8299/* Randomly generate the hopping parameters for the given timeslot numbers */
8300private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
8301runs on test_CT return FHParamsTrx {
8302 var FHParamsTrx fhp;
8303
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008304 /* Generate a random ARFCN, including ARFCN 0 */
8305 fhp.arfcn := f_rnd_int(3);
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008306
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008307 for (var integer tn := 0; tn < 8; tn := tn + 1) {
8308 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008309 fhp.ts[tn].enabled := false;
8310 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008311 continue;
8312 }
8313
8314 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008315 fhp.ts[tn].hsn := f_rnd_int(64);
8316 fhp.ts[tn].maio := f_rnd_int(64);
8317 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008318
8319 /* Random Mobile Allocation (hopping channels) */
8320 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
8321 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
8322 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008323 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008324 }
8325
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008326 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008327 }
8328
8329 log("f_TC_fh_params_gen(): ", fhp);
8330 return fhp;
8331}
8332
8333/* Make sure that the given Channel Description IE matches the hopping configuration */
8334private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
8335{
8336 var template (present) ChannelDescription tr_cd;
8337 var template (present) MaioHsn tr_maio_hsn;
8338 var uint3_t tn := cd.chan_nr.tn;
8339
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008340 if (fhp.ts[tn].enabled) {
8341 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008342 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
8343 } else {
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008344 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008345 }
8346
8347 if (not match(cd, tr_cd)) {
8348 setverdict(fail, "Channel Description IE does not match: ",
8349 cd, " vs expected ", tr_cd);
8350 }
8351}
8352
8353/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
8354private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
8355 in MobileAllocationLV ma)
8356{
8357 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
8358
8359 if (not match(ma, tr_ma)) {
8360 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
8361 tn, "): ", ma, " vs expected: ", tr_ma);
8362 } else {
8363 setverdict(pass);
8364 }
8365}
8366
8367private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
8368 in MobileAllocationLV ma)
8369return template MobileAllocationLV {
8370 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008371 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008372 return { len := 0, ma := ''B };
8373 }
8374
8375 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
8376 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
8377 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008378
8379 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008380 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
8381 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
8382 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008383 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008384 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008385 }
8386 }
8387
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008388 /* Take ARFCN of the TRX itself into account */
8389 full_mask[fhp.arfcn] := '1'B;
8390
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008391 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008392 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8393 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008394 }
8395
8396 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008397 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008398 if (full_mask[i] != '1'B)
8399 { continue; }
8400
8401 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
8402 if (slot_mask[i] == '1'B) {
8403 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008404 } else {
8405 ma_mask := ma_mask & '0'B;
8406 }
8407 }
8408
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07008409 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
8410 if (full_mask[0] == '1'B) {
8411 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
8412 if (slot_mask[0] == '1'B) {
8413 ma_mask := ma_mask & '1'B;
8414 } else {
8415 ma_mask := ma_mask & '0'B;
8416 }
8417 }
8418
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008419 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07008420 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008421 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
8422
8423 return { len := ma_mask_len, ma := ma_mask };
8424}
8425
8426/* Configure the hopping parameters in accordance with the given record */
8427private function f_TC_fh_params_set(in FHParamsTrx fhp,
8428 uint8_t bts_nr := 0,
8429 uint8_t trx_nr := 0)
8430runs on test_CT {
8431 /* Enter the configuration node for the given BTS/TRX numbers */
8432 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8433
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008434 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn));
8435
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008436 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008437 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8438
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008439 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008440 f_vty_transceive(BSCVTY, "hopping enabled 0");
8441 f_vty_transceive(BSCVTY, "exit"); /* go back */
8442 continue;
8443 }
8444
8445 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008446 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
8447 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008448
8449 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008450 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8451 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008452 }
8453
8454 f_vty_transceive(BSCVTY, "hopping enabled 1");
8455 f_vty_transceive(BSCVTY, "exit"); /* go back */
8456 }
8457
8458 f_vty_transceive(BSCVTY, "end");
8459}
8460
8461/* Disable frequency hopping on all timeslots */
8462private function f_TC_fh_params_unset(in FHParamsTrx fhp,
8463 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008464 uint8_t trx_nr := 0,
8465 GsmArfcn arfcn := 871)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008466runs on test_CT {
8467 /* Enter the configuration node for the given BTS/TRX numbers */
8468 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
8469
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07008470 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn));
8471
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008472 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008473 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
8474
8475 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07008476 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
8477 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008478 }
8479
8480 f_vty_transceive(BSCVTY, "hopping enabled 0");
8481 f_vty_transceive(BSCVTY, "exit"); /* go back */
8482 }
8483
8484 f_vty_transceive(BSCVTY, "end");
8485 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8486}
8487
8488/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
8489 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
8490testcase TC_fh_params_chan_activ() runs on test_CT {
8491 var FHParamsTrx fhp := f_TC_fh_params_gen();
8492 var RSL_Message rsl_msg;
8493 var RSL_IE_Body ie;
8494
8495 f_init_vty();
8496
8497 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8498 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8499
8500 f_init(1);
8501
8502 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8503 for (var integer i := 0; i < 9; i := i + 1) {
8504 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8505 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8506
8507 /* Make sure that Channel Identification IE is present */
8508 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
8509 setverdict(fail, "RSL Channel Identification IE is absent");
8510 continue;
8511 }
8512
8513 /* Make sure that hopping parameters (HSN/MAIO) match */
8514 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
8515
8516 /* "Mobile Allocation shall be included but empty" - let's check this */
8517 if (ie.chan_ident.ma.v.len != 0) {
8518 setverdict(fail, "Mobile Allocation IE is not empty: ",
8519 ie.chan_ident.ma, ", despite it shall be");
8520 continue;
8521 }
8522 }
8523
8524 /* Disable frequency hopping */
8525 f_TC_fh_params_unset(fhp);
8526
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008527 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07008528}
8529
8530/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
8531testcase TC_fh_params_imm_ass() runs on test_CT {
8532 var FHParamsTrx fhp := f_TC_fh_params_gen();
8533 var RSL_Message rsl_msg;
8534 var RSL_IE_Body ie;
8535
8536 f_init_vty();
8537
8538 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8539 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8540
8541 f_init(1);
8542
8543 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
8544 for (var integer i := 0; i < 9; i := i + 1) {
8545 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
8546 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8547
8548 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8549 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
8550
8551 /* Make sure that Full Immediate Assign Info IE is present */
8552 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
8553 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
8554 continue;
8555 }
8556
8557 /* Decode the actual Immediate Assignment message */
8558 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
8559 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
8560 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
8561 continue;
8562 }
8563
8564 /* Make sure that hopping parameters (HSN/MAIO) match */
8565 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
8566
8567 /* Make sure that the Mobile Allocation IE matches */
8568 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
8569 rr_msg.payload.imm_ass.mobile_allocation);
8570 }
8571
8572 /* Disable frequency hopping */
8573 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02008574
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008575 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02008576}
8577
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008578/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
8579testcase TC_fh_params_assignment_cmd() runs on test_CT {
8580 var FHParamsTrx fhp := f_TC_fh_params_gen();
8581 var RSL_Message rsl_msg;
8582 var RSL_IE_Body ie;
8583
8584 f_init_vty();
8585
8586 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8587 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8588
8589 f_init(1);
8590
8591 /* HACK: work around "Couldn't find Expect for CRCX" */
8592 vc_MGCP.stop;
8593
8594 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
8595 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
8596
8597 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
8598 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
8599 for (var integer i := 0; i < 3; i := i + 1) {
8600 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
8601 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8602
8603 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
8604 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
8605 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8606
8607 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
8608 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8609 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8610
8611 /* Make sure that L3 Information IE is present */
8612 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8613 setverdict(fail, "RSL L3 Information IE is absent");
8614 continue;
8615 }
8616
8617 /* Decode the L3 message and make sure it is (RR) Assignment Command */
8618 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8619 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
8620 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
8621 continue;
8622 }
8623
8624 /* Make sure that hopping parameters (HSN/MAIO) match */
8625 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
8626 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8627
8628 /* Make sure that Cell Channel Description IE is present if FH is enabled */
8629 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07008630 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008631 continue;
8632 }
8633
8634 /* Make sure that the Mobile Allocation IE matches (if present) */
8635 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
8636 if (chan_desc.h and ma_present) {
8637 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8638 l3_msg.payload.ass_cmd.mobile_allocation.v);
8639 } else if (chan_desc.h and not ma_present) {
8640 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8641 continue;
8642 } else if (not chan_desc.h and ma_present) {
8643 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
8644 continue;
8645 }
8646 }
8647
8648 /* Give the IUT some time to release all channels */
8649 f_sleep(3.0);
8650
8651 /* Disable frequency hopping */
8652 f_TC_fh_params_unset(fhp);
8653
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008654 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07008655}
8656
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07008657/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
8658private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
8659runs on test_CT {
8660 var RSL_Message rsl_msg;
8661 var RSL_IE_Body ie;
8662 var DchanTuple dt;
8663
8664 /* Establish a dedicated channel, so we can trigger handover */
8665 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
8666
8667 /* Trigger handover from BTS0 to BTS1 */
8668 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
8669 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
8670
8671 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
8672 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8673
8674 /* ACKnowledge channel activation and expect (RR) Handover Command */
8675 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
8676 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
8677
8678 /* Make sure that L3 Information IE is present */
8679 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
8680 setverdict(fail, "RSL L3 Information IE is absent");
8681 return;
8682 }
8683
8684 /* Decode the L3 message and make sure it is (RR) Handover Command */
8685 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
8686 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
8687 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
8688 return;
8689 }
8690
8691 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
8692 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
8693 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
8694 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
8695 return;
8696 }
8697
8698 /* Make sure that hopping parameters (HSN/MAIO) match */
8699 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8700
8701 /* Make sure that Cell Channel Description IE is present */
8702 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
8703 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
8704 return;
8705 }
8706
8707 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
8708 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
8709 if (ma_present) {
8710 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8711 l3_msg.payload.ho_cmd.mobile_allocation.v);
8712 } else {
8713 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8714 return;
8715 }
8716}
8717testcase TC_fh_params_handover_cmd() runs on test_CT {
8718 var FHParamsTrx fhp := f_TC_fh_params_gen();
8719
8720 f_init_vty();
8721
8722 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
8723 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8724
8725 f_vty_transceive(BSCVTY, "timeslot 0");
8726 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8727 f_vty_transceive(BSCVTY, "exit"); /* go back */
8728
8729 f_vty_transceive(BSCVTY, "timeslot 1");
8730 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
8731 f_vty_transceive(BSCVTY, "end"); /* we're done */
8732
8733 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
8734 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
8735
8736 f_init(2);
8737
8738 f_TC_fh_params_handover_cmd(fhp);
8739
8740 /* Disable frequency hopping on BTS1 */
8741 f_TC_fh_params_unset(fhp, 1);
8742
8743 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
8744 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
8745
8746 f_vty_transceive(BSCVTY, "timeslot 0");
8747 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
8748 f_vty_transceive(BSCVTY, "exit"); /* go back */
8749
8750 f_vty_transceive(BSCVTY, "timeslot 1");
8751 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8752 f_vty_transceive(BSCVTY, "end"); /* we're done */
8753
8754 f_shutdown_helper();
8755}
8756
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008757/* Verify the hopping parameters in System Information Type 4 */
8758testcase TC_fh_params_si4_cbch() runs on test_CT {
8759 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
8760 var ASP_RSL_Unitdata rx_rsl_ud;
8761 timer T := 5.0;
8762
8763 f_init_vty();
8764
8765 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
8766 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8767
8768 f_vty_transceive(BSCVTY, "timeslot 0");
8769 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
8770 f_vty_transceive(BSCVTY, "exit"); /* go back */
8771
8772 f_vty_transceive(BSCVTY, "timeslot 1");
8773 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
8774 f_vty_transceive(BSCVTY, "end"); /* we're done */
8775
8776 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
8777 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
8778
8779 f_init(1);
8780
8781 T.start;
8782 alt {
8783 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
8784 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
8785 var SystemInformation si := dec_SystemInformation(ie.other.payload);
8786
8787 /* Make sure that what we decoded is System Information Type 4 */
8788 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
8789 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
8790 repeat;
8791 }
8792
8793 /* Make sure that CBCH Channel Description IE is present */
8794 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
8795 setverdict(fail, "CBCH Channel Description IE is absent");
8796 break;
8797 }
8798
8799 /* Finally, check the hopping parameters (HSN, MAIO) */
8800 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
8801 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
8802
8803 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
8804 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
8805 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
8806 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
8807 break;
8808 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
8809 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
8810 si.payload.si4.cbch_mobile_alloc.v);
8811 }
8812 }
8813 [] IPA_RSL[0].receive { repeat; }
8814 [] T.timeout {
8815 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
8816 }
8817 }
8818
8819 /* Disable frequency hopping */
8820 f_TC_fh_params_unset(fhp);
8821
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008822 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008823 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
8824
8825 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07008826 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008827 f_vty_transceive(BSCVTY, "exit"); /* go back */
8828
8829 f_vty_transceive(BSCVTY, "timeslot 1");
8830 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
8831 f_vty_transceive(BSCVTY, "end"); /* we're done */
8832
Vadim Yanitskiy21726312020-09-04 01:45:36 +07008833 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07008834}
8835
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008836template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
8837 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
8838
8839private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
8840 template (present) BSSLAP_PDU expect_bsslap)
8841{
8842 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
8843 if (not match(bsslap, expect_bsslap)) {
8844 log("EXPECTING BSSLAP: ", expect_bsslap);
8845 log("GOT BSSLAP: ", bsslap);
8846 setverdict(fail, "BSSLAP is not as expected");
8847 mtc.stop;
8848 }
8849 setverdict(pass);
8850}
8851
8852/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
8853const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
8854
8855private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
8856 var PDU_BSSAP_LE rx_bsslap;
8857 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
8858 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
8859}
8860
8861/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8862 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
8863private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
8864 f_sleep(1.0);
8865
8866 f_establish_fully(omit, omit);
8867 f_bssap_le_register_imsi(g_pars.imsi, omit);
8868
8869 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8870 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8871
8872 var PDU_BSSAP_LE plr;
8873 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
8874
8875 if (not do_ta_request) {
8876 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
8877 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
8878 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
8879 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
8880 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
8881 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
8882 mtc.stop;
8883 }
8884 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
8885 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
8886 if (not match(bsslap, expect_ta_layer3)) {
8887 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
8888 log("GOT BSSLAP: ", bsslap);
8889 setverdict(fail, "BSSLAP is not as expected");
8890 mtc.stop;
8891 }
8892 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
8893 * has no need to request the TA from the BSC and directly responds. */
8894 } else {
8895 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
8896 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
8897 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
8898 }
8899
8900 /* SMLC got the TA from the BSC, now responds with geo information data. */
8901 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
8902 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8903 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
8904
8905 /* The LCS was using an active A-interface conn. It should still remain active after this. */
8906 f_mo_l3_transceive();
8907
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008908 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008909
8910 f_sleep(2.0);
8911 setverdict(pass);
8912}
8913
8914/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8915 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
8916private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
8917 f_lcs_loc_req_for_active_ms(false);
8918}
8919testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
8920 var MSC_ConnHdlr vc_conn;
8921 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8922
8923 f_init(1, true);
8924 f_sleep(1.0);
8925 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
8926 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008927 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008928}
8929
8930/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8931 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
8932private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
8933 f_lcs_loc_req_for_active_ms(true);
8934}
8935testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
8936 var MSC_ConnHdlr vc_conn;
8937 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8938
8939 f_init(1, true);
8940 f_sleep(1.0);
8941 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
8942 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01008943 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008944}
8945
8946/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
8947 * conn without an active lchan. */
8948private function f_clear_A_conn() runs on MSC_ConnHdlr
8949{
8950 var BssmapCause cause := 0;
8951 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
8952 BSSAP.receive(tr_BSSMAP_ClearComplete);
8953 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8954
8955 timer no_more_bssap := 5.0;
8956 no_more_bssap.start;
8957 alt {
8958 [] no_more_bssap.timeout { break; }
8959 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
8960 setverdict(fail, "Expected no more BSSAP after Clear Complete");
8961 mtc.stop;
8962 }
8963 }
8964 setverdict(pass);
8965}
8966
8967/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
8968 * for LCS, for cases where there is only an A conn without an active lchan. */
8969private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
8970{
8971 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
8972
8973 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
8974 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
8975 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
8976 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
8977 ts_CellId_CGI('262'H, '42'H, 23, 42))));
8978 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
8979
8980 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
8981 f_clear_A_conn();
8982 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
8983 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
8984}
8985
8986/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
8987 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
8988 */
8989private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
8990 f_sleep(1.0);
8991
8992 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8993 f_bssap_le_register_imsi(g_pars.imsi, omit);
8994
8995 /* Register to receive the Paging Command */
8996 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
8997 g_chan_nr := new_chan_nr;
8998 f_rslem_register(0, g_chan_nr);
8999
9000 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9001 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9002 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9003 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9004
9005 var PDU_BSSAP_LE plr;
9006 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9007
9008 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9009 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9010
9011 /* OsmoBSC needs to Page */
9012 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9013 f_logp(BSCVTY, "got Paging Command");
9014
9015 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9016 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009017 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(g_pars.imsi))), do_clear := false, expect_bssmap_l3 := false);
9018 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009019
9020 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9021
9022 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9023
9024 /* SMLC got the TA from the BSC, now responds with geo information data. */
9025 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9026 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9027
9028 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9029
9030 /* The lchan is gone, the A-interface conn was created for the LCS only.
9031 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9032 f_verify_active_A_conn_and_clear();
9033
9034 f_sleep(2.0);
9035 setverdict(pass);
9036}
9037testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9038 var MSC_ConnHdlr vc_conn;
9039 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9040
9041 f_init(1, true);
9042 f_sleep(1.0);
9043
9044 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9045 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9046
9047 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9048 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009049 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009050}
9051
9052/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9053 */
9054private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9055 f_sleep(1.0);
9056
9057 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9058 f_bssap_le_register_imsi(g_pars.imsi, omit);
9059
9060 /* provoke an abort by omitting both IMSI and IMEI */
9061 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9062 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9063 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9064 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9065
9066 /* BSC tells MSC about failure */
9067 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9068 locationEstimate := omit, positioningData := omit,
9069 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9070
9071 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9072 f_verify_active_A_conn_and_clear();
9073
9074 f_sleep(2.0);
9075 setverdict(pass);
9076}
9077testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9078 var MSC_ConnHdlr vc_conn;
9079 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9080
9081 f_init(1, true);
9082 f_sleep(1.0);
9083
9084 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9085 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9086
9087 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9088 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009089 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009090}
9091
9092/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9093 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9094private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9095 f_sleep(1.0);
9096
9097 f_establish_fully(omit, omit);
9098 f_bssap_le_register_imsi(g_pars.imsi, omit);
9099
9100 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9101 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9102
9103 var PDU_BSSAP_LE plr;
9104 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9105
9106 if (do_ta) {
9107 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9108 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9109 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9110 }
9111
9112 /* SMLC fails to respond, BSC runs into timeout */
9113 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9114 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9115
9116 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9117 locationEstimate := omit, positioningData := omit,
9118 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9119
9120 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9121 f_verify_active_A_conn_and_clear();
9122
9123 f_sleep(2.0);
9124 setverdict(pass);
9125}
9126
9127/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9128 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9129private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9130 f_lcs_loc_req_for_active_ms_le_timeout(false);
9131}
9132
9133testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9134 var MSC_ConnHdlr vc_conn;
9135 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9136
9137 f_init(1, true);
9138 f_sleep(1.0);
9139 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9140 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009141 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009142}
9143
9144/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9145 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9146private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9147 f_lcs_loc_req_for_active_ms_le_timeout(true);
9148}
9149
9150testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9151 var MSC_ConnHdlr vc_conn;
9152 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9153
9154 f_init(1, true);
9155 f_sleep(1.0);
9156 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9157 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009158 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009159}
9160
9161/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9162private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9163 f_sleep(1.0);
9164
9165 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9166 f_bssap_le_register_imsi(g_pars.imsi, omit);
9167
9168 /* Register to receive the Paging Command */
9169 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9170 g_chan_nr := new_chan_nr;
9171 f_rslem_register(0, g_chan_nr);
9172
9173 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9174 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9175 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9176 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9177
9178 var PDU_BSSAP_LE plr;
9179 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9180
9181 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9182 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9183
9184 /* OsmoBSC needs to Page */
9185 var PDU_BSSAP_LE rx_bsslap;
9186 alt {
9187 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9188 f_logp(BSCVTY, "got Paging Command");
9189 repeat;
9190 }
9191 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9192 /* MS does not respond to Paging, TA Req runs into timeout. */
9193 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9194 }
9195 }
9196
9197 /* SMLC responds with failure */
9198 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9199 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9200
9201 /* BSC tells MSC about failure */
9202 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9203 locationEstimate := omit, positioningData := omit,
9204 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9205
9206 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9207 f_verify_active_A_conn_and_clear();
9208
9209 f_sleep(2.0);
9210 setverdict(pass);
9211}
9212testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9213 var MSC_ConnHdlr vc_conn;
9214 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9215
9216 f_init(1, true);
9217 f_sleep(1.0);
9218
9219 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9220 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9221
9222 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9223 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009224 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009225}
9226
9227/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9228 * over. */
9229private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9230 f_sleep(1.0);
9231
9232 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9233 f_bssap_le_register_imsi(g_pars.imsi, omit);
9234
9235 /* Register to receive the Paging Command */
9236 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9237 g_chan_nr := new_chan_nr;
9238 f_rslem_register(0, g_chan_nr);
9239
9240 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9241 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9242 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9243 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9244
9245 var PDU_BSSAP_LE plr;
9246 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9247
9248 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
9249 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009250 f_perform_compl_l3(RSL, RSL_PROC, valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV(g_pars.imsi)))),
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009251 do_clear := false, expect_bssmap_l3 := true);
9252
9253 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9254 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9255
9256 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
9257 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9258
9259 /* SMLC got the TA from the BSC, now responds with geo information data. */
9260 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9261 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9262 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9263
9264 /* The lchan should still exist, it was from a CM Service Request. */
9265 f_mo_l3_transceive();
9266
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009267 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009268
9269 f_sleep(2.0);
9270 setverdict(pass);
9271}
9272testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
9273 var MSC_ConnHdlr vc_conn;
9274 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9275
9276 f_init(1, true);
9277 f_sleep(1.0);
9278
9279 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9280 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9281
9282 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
9283 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009284 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009285}
9286
9287/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
9288 * the new lchan after handover. */
9289private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9290 f_sleep(1.0);
9291
9292 f_establish_fully(omit, omit);
9293 f_bssap_le_register_imsi(g_pars.imsi, omit);
9294
9295 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9296 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9297
9298 var PDU_BSSAP_LE plr;
9299 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9300
9301 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
9302 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
9303
9304 var HandoverState hs := {
9305 rr_ho_cmpl_seen := false,
9306 handover_done := false,
9307 old_chan_nr := -
9308 };
9309 /* issue hand-over command on VTY */
9310 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
9311 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
9312 f_rslem_suspend(RSL1_PROC);
9313
9314 /* From the MGW perspective, a handover is is characterized by
9315 * performing one MDCX operation with the MGW. So we expect to see
9316 * one more MDCX during handover. */
9317 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
9318
9319 alt {
9320 [] as_handover(hs);
9321 }
9322
9323 var PDU_BSSAP_LE rx_bsslap;
9324
9325 interleave {
9326 /* Expect the BSC to inform the MSC about the handover */
9327 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
9328
9329 /* Expect the BSC to inform the SMLC about the handover */
9330 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9331 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
9332 }
9333 }
9334
9335 /* SMLC now responds with geo information data. */
9336 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9337 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9338 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9339
9340 /* lchan still active */
9341 f_mo_l3_transceive(RSL1);
9342
9343 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009344 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009345
9346 f_sleep(2.0);
9347 setverdict(pass);
9348}
9349testcase TC_ho_during_lcs_loc_req() runs on test_CT {
9350 var MSC_ConnHdlr vc_conn;
9351 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9352
9353 f_init(2, true);
9354 f_sleep(1.0);
9355 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
9356 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009357 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009358}
9359
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009360/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
9361private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
9362 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9363
9364 /* Also disable attach for the single connected MSC */
9365 f_vty_msc_allow_attach(BSCVTY, { false });
9366
9367 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000100001'H)), '00F110'O) ));
9368 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
9369
9370 /* No MSC is found, expecting a proper release on RSL */
9371 interleave {
9372 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
9373 f_logp(BSCVTY, "Got RSL RR Release");
9374 }
9375 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9376 f_logp(BSCVTY, "Got RSL Deact SACCH");
9377 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009378 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009379 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
9380 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009381 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009382 }
9383 }
9384 setverdict(pass);
9385}
9386testcase TC_no_msc() runs on test_CT {
9387
9388 f_init(1, true);
9389 f_sleep(1.0);
9390 var MSC_ConnHdlr vc_conn;
9391 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9392
9393 f_ctrs_bsc_init(counternames_bsc_mscpool);
9394
9395 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
9396 vc_conn.done;
9397
9398 f_ctrs_bsc_add("mscpool:subscr:no_msc");
9399 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009400 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +00009401}
9402
Harald Welte0ea2d5e2018-04-07 21:40:29 +02009403/* Dyn PDCH todo:
9404 * activate OSMO as TCH/F
9405 * activate OSMO as TCH/H
9406 * does the BSC-located PCU socket get the updated INFO?
9407 * what if no PCU is connected at the time?
9408 * is the info correct on delayed PCU (re)connect?
9409 */
Harald Welte94e0c342018-04-07 11:33:23 +02009410
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009411private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
9412 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
9413 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
9414
9415 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
9416 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
9417 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
9418 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
9419 g_pars.ass_codec_list.codecElements[0];
9420 if (isvalue(g_pars.expect_mr_s0_s7)) {
9421 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
9422 g_pars.expect_mr_s0_s7;
9423 }
9424 }
9425 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
9426 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
9427 log("expecting ASS COMPL like this: ", exp_compl);
9428
9429 f_establish_fully(ass_cmd, exp_compl);
9430
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +02009431 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 modify vamos tsc 2 3");
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009432
9433 var RSL_Message rsl;
9434
9435 timer T := 5.0;
9436 T.start;
9437 alt {
9438 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
9439 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
9440 log("Rx L3 from net: ", l3);
9441 if (ischosen(l3.msgs.rrm.channelModeModify)) {
9442 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9443 mtc.stop;
9444 }
9445 }
9446 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
9447 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
9448 mtc.stop;
9449 }
9450 [] T.timeout {
9451 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
9452 setverdict(pass);
9453 }
9454 }
9455 T.stop;
9456}
9457
9458/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
9459 * osmo-bsc. */
9460testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
9461 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9462 var MSC_ConnHdlr vc_conn;
9463
9464 f_init(1, true);
9465 f_sleep(1.0);
9466
9467 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9468 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
9469 vc_conn.done;
9470 f_shutdown_helper();
9471}
9472
9473/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
9474 */
9475testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
9476 f_init_vty();
9477
9478 f_init(1, false);
9479 f_sleep(1.0);
9480
9481 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
9482
9483 var ASP_RSL_Unitdata rx_rsl_ud;
9484 timer T := 5.0;
9485
9486 T.start;
9487 alt {
9488 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
9489 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
9490 T.stop;
9491 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
9492 mtc.stop;
9493 }
9494 repeat;
9495 }
9496 [] T.timeout {
9497 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
9498 setverdict(pass);
9499 }
9500 }
9501}
9502
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009503private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
9504 /* First fully set up a speech lchan */
9505 f_TC_assignment_codec(id);
9506
9507 /* Trigger re-assignment to another lchan */
9508 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
9509
9510 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
9511 * one MDCX on MGCP. */
9512 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
9513
9514 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
9515 * as the old lchan used. */
9516 g_media.bts.ipa_crcx_seen := false;
9517 g_media.bts.ipa_mdcx_seen := false;
9518
9519 /* Send different BTS side RTP port number for the new lchan */
9520 g_media.bts.bts.port_nr := 4223;
9521
9522 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
9523
9524 /* Trigger re-assignment. */
9525 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
9526
9527 timer T := 5.0;
9528 T.start;
9529 alt {
9530 [] as_assignment(assignment_st);
9531 [] as_Media();
9532 [] T.timeout {
9533 break;
9534 }
9535 }
9536
9537 if (not assignment_st.assignment_done) {
9538 setverdict(fail, "Assignment did not complete");
9539 mtc.stop;
9540 }
9541
9542 f_check_mgcp_expectations()
9543 setverdict(pass);
9544
9545 f_sleep(2.0);
9546 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
9547
9548 /* Instruct BSC to clear channel */
9549 var BssmapCause cause := 0;
9550 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9551 interleave {
9552 [] MGCP.receive(tr_DLCX) {}
9553 [] MGCP.receive(tr_DLCX) {}
9554 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
9555 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02009556 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009557 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02009558 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +00009559 }
9560 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
9561 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9562 }
9563 }
9564
9565 f_sleep(0.5);
9566}
9567
9568testcase TC_reassignment_fr() runs on test_CT {
9569 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9570 var MSC_ConnHdlr vc_conn;
9571
9572 f_init(1, true);
9573 f_sleep(1.0);
9574
9575 f_ctrs_bsc_and_bts_init();
9576
9577 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9578 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
9579 vc_conn.done;
9580
9581 /* from f_establish_fully() */
9582 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9583 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9584 /* from re-assignment */
9585 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
9586 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
9587 f_ctrs_bsc_and_bts_verify();
9588 f_shutdown_helper();
9589}
9590
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009591const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
9592const charstring REEST_CLEAR := "REEST_CLEAR";
9593const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
9594
9595/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
9596 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
9597 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
9598 * the MSC as the CM Re-Establishment is handled.
9599 *
9600 * MS bts0 bts1 bsc msc test-component
9601 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
9602 * | | _1 wait a bit, to settle down
9603 * |<-x x--| | _1 "lose connection"
9604 * | | REEST_LOST_CONNECTION
9605 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
9606 * | | REEST_CLEAR
9607 * | |<-0---| _1 Clear Command on first A-conn
9608 * | |--0-->| _1 Clear Complete
9609 * | |<----------------->| | _1 Release first channel
9610 * | | REEST_CLEAR_DONE
9611 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
9612 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
9613 *
9614 */
9615private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
9616 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
9617 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9618
9619 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9620 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9621
9622 f_establish_fully(ass_cmd, exp_compl);
9623
9624 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
9625 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
9626 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
9627 f_sleep(2.0);
9628 COORD.send(REEST_LOST_CONNECTION);
9629
9630 alt {
9631 [] COORD.receive(REEST_CLEAR);
9632 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
9633 setverdict(fail, "Unexpected channel release");
9634 mtc.stop;
9635 }
9636 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
9637 setverdict(fail, "Unexpected channel release");
9638 mtc.stop;
9639 }
9640 }
9641 f_perform_clear()
9642 f_expect_dlcx_conns();
9643 COORD.send(REEST_CLEAR_DONE);
9644}
9645
9646private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
9647 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
9648
9649 /* The MS lost the connection on the first channel, now establishes another one */
9650 COORD.receive(REEST_LOST_CONNECTION);
9651
9652 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
9653 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
9654 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
9655
9656 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009657 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009658 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
9659
9660 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
9661 COORD.send(REEST_CLEAR);
9662 COORD.receive(REEST_CLEAR_DONE);
9663
9664 f_sleep(2.0);
9665
9666 /* Answer the CM Re-Establishment with an Assignment Command. */
9667 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
9668 var PDU_BSSAP ass_cmd := f_gen_ass_req();
9669 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
9670 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
9671
9672 var AssignmentState st := valueof(ts_AssignmentStateInit);
9673 st.voice_call := true;
9674 st.is_assignment := true;
9675
9676 var ExpectCriteria mgcpcrit := {
9677 connid := omit,
9678 endpoint := omit,
9679 transid := omit
9680 };
9681 f_create_mgcp_expect(mgcpcrit);
9682
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009683 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009684
9685 BSSAP.send(ass_cmd);
9686
9687 var PDU_BSSAP bssap;
9688
9689 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009690 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
9691 [] as_Media_ipacc(RSL1, RSL2);
9692 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009693 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
9694 break;
9695 }
9696 }
9697
9698 f_sleep(3.0);
9699
9700 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009701 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009702 f_expect_dlcx_conns();
9703}
9704
9705testcase TC_cm_reestablishment() runs on test_CT {
9706 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
9707 var MSC_ConnHdlr vc_conn1;
9708
9709 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
9710 var MSC_ConnHdlr vc_conn2;
9711 pars2.imsi := pars1.imsi;
9712 pars2.media_nr := 2;
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +02009713 /* f_tc_cm_reestablishment_2 uses 'bts 1'.
9714 * BTS 1 has BSIC 11 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 3 */
9715 pars2.expect_tsc := 3;
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +02009716
9717 f_init(2, true, guard_timeout := 40.0);
9718 f_sleep(1.0);
9719
9720 vc_conn1 := f_start_handler_create(pars1);
9721 vc_conn2 := f_start_handler_create(pars2);
9722 connect(vc_conn1:COORD, vc_conn2:COORD);
9723 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
9724 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
9725 vc_conn1.done;
9726 vc_conn2.done;
9727
9728 f_shutdown_helper();
9729}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +00009730
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009731function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
9732 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
9733runs on test_CT return template (omit) RSL_Message {
9734 var ASP_RSL_Unitdata rx_rsl_ud;
9735 timer T := t_secs;
9736
9737 T.start;
9738 alt {
9739 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
9740 T.stop;
9741 }
9742 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
9743 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
9744 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
9745 T.stop;
9746 return omit;
9747 }
9748 [] T.timeout {
9749 return omit;
9750 }
9751 }
9752 return rx_rsl_ud.rsl;
9753}
9754
9755private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
9756 f_vty_enter_cfg_bts(pt, bts_nr);
9757 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
9758 f_vty_transceive(pt, "exit");
9759 f_vty_transceive(pt, "exit");
9760 f_vty_transceive(pt, "exit");
9761}
9762
9763private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009764 template RslChannelNr chan_nr := ?,
9765 template (present) uint12_t arfcn := ?,
9766 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009767{
9768 var RSL_IE_Body full_imm_ass_info;
9769 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
9770 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9771 mtc.stop;
9772 }
9773
9774 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
9775 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
9776 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009777 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009778 page_mode := ?);
9779 if (not match(rr_imm_ass, expect_imm_ass)) {
9780 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
9781 setverdict(fail, "Failed to match Immediate Assignment");
9782 mtc.stop;
9783 }
9784}
9785
9786testcase TC_imm_ass_post_chan_ack() runs on test_CT {
9787 var RSL_Message chan_act;
9788 var RSL_Message imm_ass;
9789
9790 f_init(1, false);
9791 f_sleep(1.0);
9792
9793 /* (should be the default anyway, just to make things clear) */
9794 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
9795
9796 /* RA containing reason=LU */
9797 var GsmFrameNumber fn := 2342;
9798 var uint8_t ra := 2;
9799 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9800
9801 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9802
9803 /* First send the Chan Act ACK */
9804 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009805 var RSL_IE_Body chan_ident_ie;
9806 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9807 setverdict(fail, "RSL Channel Identification IE is absent");
9808 mtc.stop;
9809 }
9810
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009811 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
9812
9813 /* Then expect the Immediate Assignment, after we ACKed the chan act */
9814 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9815
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009816 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9817 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009818
9819 /* Check that the lchan is working */
9820 var octetstring l3 := '00010203040506'O;
9821 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9822
9823 var BSSAP_N_CONNECT_ind rx_c_ind;
9824 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9825 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9826
9827 f_sleep(1.0);
9828 f_shutdown_helper();
9829}
9830
9831testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
9832 var RSL_Message chan_act;
9833 var RSL_Message imm_ass;
9834
9835 f_init(1, false);
9836 f_sleep(1.0);
9837
9838 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9839
9840 /* RA containing reason=LU */
9841 var GsmFrameNumber fn := 2342;
9842 var uint8_t ra := 2;
9843 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9844
9845 /* (set bts 0 cfg back to default) */
9846 f_vty_set_imm_ass(BSCVTY);
9847
9848 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9849 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009850 var RSL_IE_Body chan_ident_ie;
9851 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9852 setverdict(fail, "RSL Channel Identification IE is absent");
9853 mtc.stop;
9854 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009855
9856 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9857 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009858 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9859 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +02009860
9861 /* Only now send the Chan Act ACK */
9862 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9863
9864 /* Check that the lchan is working */
9865 var octetstring l3 := '00010203040506'O;
9866 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9867
9868 var BSSAP_N_CONNECT_ind rx_c_ind;
9869 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9870 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9871
9872 f_sleep(1.0);
9873 f_shutdown_helper();
9874}
9875
Neels Hofmeyr23158742021-09-07 19:08:07 +02009876testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
9877 var RSL_Message chan_act;
9878 var RSL_Message imm_ass;
9879
9880 f_init(1, false);
9881 f_sleep(1.0);
9882
9883 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
9884
9885 /* RA containing reason=LU */
9886 var GsmFrameNumber fn := 2342;
9887 var uint8_t ra := 2;
9888 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9889
9890 /* (set bts 0 cfg back to default) */
9891 f_vty_set_imm_ass(BSCVTY);
9892
9893 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9894 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
9895 var RSL_IE_Body chan_ident_ie;
9896 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9897 setverdict(fail, "RSL Channel Identification IE is absent");
9898 mtc.stop;
9899 }
9900
9901 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9902 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
9903 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9904 chan_ident_ie.chan_ident.ch_desc.v.tsc);
9905
9906 /* Only now send the Chan Act ACK */
9907 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9908
9909 /* Check that the lchan is working */
9910 var octetstring l3 := '00010203040506'O;
9911 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9912
9913 var BSSAP_N_CONNECT_ind rx_c_ind;
9914 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9915 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9916
9917 f_sleep(1.0);
9918 f_shutdown_helper();
9919}
9920
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009921testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
9922 /* change Timeslot 6 before f_init() starts RSL */
9923 f_init_vty();
9924 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9925 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9926
9927 f_init(1, false);
9928 f_sleep(1.0);
9929
9930 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
9931 /* The BSC will activate the dynamic PDCH by default, so confirm that */
9932 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
9933 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
9934
9935 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
9936 f_ts_set_chcomb(0, 0, 6, "PDCH");
9937
9938 /* block all static timeslots so that the dyn TS will be used */
9939 f_disable_all_tch_f();
9940 f_disable_all_tch_h();
9941 f_disable_all_sdcch();
9942
9943 var RSL_Message chan_act;
9944 var RSL_Message imm_ass;
9945
9946 f_init(1, false);
9947 f_sleep(1.0);
9948
9949 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
9950
9951 /* RA containing reason=LU */
9952 var GsmFrameNumber fn := 2342;
9953 var uint8_t ra := 2;
9954 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
9955
9956 /* (set bts 0 cfg back to default) */
9957 f_vty_set_imm_ass(BSCVTY);
9958
9959 /* Expect the dyn TS to deactivate PDCH first */
9960 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
9961 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
9962
9963 /* Now activation as SDCCH8 */
9964 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
9965
9966 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009967 var RSL_IE_Body chan_ident_ie;
9968 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
9969 setverdict(fail, "RSL Channel Identification IE is absent");
9970 mtc.stop;
9971 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009972
9973 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
9974 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +02009975 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
9976 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +02009977
9978 /* Only now send the Chan Act ACK */
9979 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
9980
9981 /* Check that the lchan is working */
9982 var octetstring l3 := '00010203040506'O;
9983 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
9984
9985 var BSSAP_N_CONNECT_ind rx_c_ind;
9986 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9987 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9988
9989 f_sleep(1.0);
9990 f_shutdown_helper();
9991}
9992
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +02009993testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
9994 /* change Timeslot 6 before f_init() starts RSL */
9995 f_init_vty();
9996 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
9997 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9998
9999 f_init(1, false);
10000 f_sleep(1.0);
10001
10002 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10003 /* The BSC will activate the dynamic PDCH by default, so confirm that */
10004 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr, ?));
10005 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10006
10007 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10008 f_ts_set_chcomb(0, 0, 6, "PDCH");
10009
10010 /* block all static timeslots so that the dyn TS will be used */
10011 f_disable_all_tch_f();
10012 f_disable_all_tch_h();
10013 f_disable_all_sdcch();
10014
10015 var RSL_Message chan_act;
10016 var RSL_Message imm_ass;
10017
10018 f_init(1, false);
10019 f_sleep(1.0);
10020
10021 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10022
10023 /* RA containing reason=LU */
10024 var GsmFrameNumber fn := 2342;
10025 var uint8_t ra := 2;
10026 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10027
10028 /* (set bts 0 cfg back to default) */
10029 f_vty_set_imm_ass(BSCVTY);
10030
10031 /* Expect the dyn TS to deactivate PDCH first */
10032 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10033
10034 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10035 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10036
10037 /* continue the Osmo style PDCH Deact (usual chan rel) */
10038 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10039
10040 /* Now activation as SDCCH8 */
10041 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
10042
10043 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010044 var RSL_IE_Body chan_ident_ie;
10045 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10046 setverdict(fail, "RSL Channel Identification IE is absent");
10047 mtc.stop;
10048 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010049 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10050
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010051 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10052 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010053
10054 /* Check that the lchan is working */
10055 var octetstring l3 := '00010203040506'O;
10056 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10057
10058 var BSSAP_N_CONNECT_ind rx_c_ind;
10059 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
10060 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10061
10062 f_sleep(1.0);
10063 f_shutdown_helper();
10064}
10065
Harald Welte28d943e2017-11-25 15:00:50 +010010066control {
Harald Welte898113b2018-01-31 18:32:21 +010010067 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010010068 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010010069 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +020010070 execute( TC_stat_num_msc_connected_1() );
10071 execute( TC_stat_num_msc_connected_2() );
10072 execute( TC_stat_num_msc_connected_3() );
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020010073 execute( TC_stat_num_bts_connected_1() );
10074 execute( TC_stat_num_bts_connected_2() );
10075 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010010076 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010077 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020010078 execute( TC_ctrl_location() );
10079 }
Harald Welte898113b2018-01-31 18:32:21 +010010080
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010081 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020010082 execute( TC_si2quater_2_earfcns() );
10083 execute( TC_si2quater_3_earfcns() );
10084 execute( TC_si2quater_4_earfcns() );
10085 execute( TC_si2quater_5_earfcns() );
10086 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020010087 execute( TC_si2quater_12_earfcns() );
10088 execute( TC_si2quater_23_earfcns() );
10089 execute( TC_si2quater_32_earfcns() );
10090 execute( TC_si2quater_33_earfcns() );
10091 execute( TC_si2quater_42_earfcns() );
10092 execute( TC_si2quater_48_earfcns() );
10093 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020010094 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020010095 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020010096
Harald Welte898113b2018-01-31 18:32:21 +010010097 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010010098 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010010099 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010010100 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020010101 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020010102 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010010103 execute( TC_chan_act_ack_est_ind_noreply() );
10104 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010010105 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010010106 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070010107 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010010108 execute( TC_chan_rel_rll_rel_ind() );
10109 execute( TC_chan_rel_conn_fail() );
10110 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020010111 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
10112 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010010113 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010010114 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020010115 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010010116 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010010117 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020010118 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010010119
Harald Weltecfe2c962017-12-15 12:09:32 +010010120 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010010121
10122 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010010123 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010010124 execute( TC_assignment_csd() );
10125 execute( TC_assignment_ctm() );
10126 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010127 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10128 execute( TC_assignment_aoip_tla_v6() );
10129 }
Harald Welte235ebf12017-12-15 14:18:16 +010010130 execute( TC_assignment_fr_a5_0() );
10131 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010132 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020010133 execute( TC_assignment_fr_a5_1_codec_missing() );
10134 }
Harald Welte235ebf12017-12-15 14:18:16 +010010135 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020010136 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020010137 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020010138 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010139 execute( TC_ciph_mode_a5_0() );
10140 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020010141 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020010142 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020010143 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020010144 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010010145
Harald Welte60aa5762018-03-21 19:33:13 +010010146 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020010147 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010010148 execute( TC_assignment_codec_hr() );
10149 execute( TC_assignment_codec_efr() );
10150 execute( TC_assignment_codec_amr_f() );
10151 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010152
Neels Hofmeyrf246a922020-05-13 02:27:10 +020010153 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010010154 execute( TC_assignment_codec_amr_f_S1() );
10155 execute( TC_assignment_codec_amr_h_S1() );
10156 execute( TC_assignment_codec_amr_f_S124() );
10157 execute( TC_assignment_codec_amr_h_S124() );
10158 execute( TC_assignment_codec_amr_f_S0() );
10159 execute( TC_assignment_codec_amr_f_S02() );
10160 execute( TC_assignment_codec_amr_f_S024() );
10161 execute( TC_assignment_codec_amr_f_S0247() );
10162 execute( TC_assignment_codec_amr_h_S0() );
10163 execute( TC_assignment_codec_amr_h_S02() );
10164 execute( TC_assignment_codec_amr_h_S024() );
10165 execute( TC_assignment_codec_amr_h_S0247() );
10166 execute( TC_assignment_codec_amr_f_S01234567() );
10167 execute( TC_assignment_codec_amr_f_S0234567() );
10168 execute( TC_assignment_codec_amr_f_zero() );
10169 execute( TC_assignment_codec_amr_f_unsupp() );
10170 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000010171 execute( TC_assignment_codec_amr_f_start_mode_auto() );
10172 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000010173 execute( TC_assignment_codec_amr_f_start_mode_4() );
10174 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000010175 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010010176 }
Harald Welte60aa5762018-03-21 19:33:13 +010010177
Philipp Maierac09bfc2019-01-08 13:41:39 +010010178 execute( TC_assignment_codec_fr_exhausted_req_hr() );
10179 execute( TC_assignment_codec_fr_exhausted_req_fr() );
10180 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
10181 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
10182 execute( TC_assignment_codec_hr_exhausted_req_fr() );
10183 execute( TC_assignment_codec_hr_exhausted_req_hr() );
10184 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
10185 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
10186 execute( TC_assignment_codec_req_hr_fr() );
10187 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020010188 execute( TC_assignment_sdcch_exhausted_req_signalling() );
10189 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
10190 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010010191
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020010192 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020010193
Harald Welte898113b2018-01-31 18:32:21 +010010194 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010010195 execute( TC_rll_est_ind_inact_lchan() );
10196 execute( TC_rll_est_ind_inval_sapi1() );
10197 execute( TC_rll_est_ind_inval_sapi3() );
10198 execute( TC_rll_est_ind_inval_sacch() );
10199
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070010200 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
10201 execute( TC_tch_dlci_link_id_sapi() );
10202
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070010203 /* SAPI N Reject triggered by RLL establishment failures */
10204 execute( TC_rll_rel_ind_sapi_n_reject() );
10205 execute( TC_rll_err_ind_sapi_n_reject() );
10206 execute( TC_rll_timeout_sapi_n_reject() );
10207
Harald Welte898113b2018-01-31 18:32:21 +010010208 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010010209 execute( TC_paging_imsi_nochan() );
10210 execute( TC_paging_tmsi_nochan() );
10211 execute( TC_paging_tmsi_any() );
10212 execute( TC_paging_tmsi_sdcch() );
10213 execute( TC_paging_tmsi_tch_f() );
10214 execute( TC_paging_tmsi_tch_hf() );
10215 execute( TC_paging_imsi_nochan_cgi() );
10216 execute( TC_paging_imsi_nochan_lac_ci() );
10217 execute( TC_paging_imsi_nochan_ci() );
10218 execute( TC_paging_imsi_nochan_lai() );
10219 execute( TC_paging_imsi_nochan_lac() );
10220 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010010221 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
10222 execute( TC_paging_imsi_nochan_rnc() );
10223 execute( TC_paging_imsi_nochan_lac_rnc() );
10224 execute( TC_paging_imsi_nochan_lacs() );
10225 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010010226 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010010227 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010010228 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010010229 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010010230 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010010231
10232 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010010233 execute( TC_rsl_unknown_unit_id() );
10234
10235 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010236
10237 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020010238 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010010239 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010010240 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010010241 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010010242 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010010243 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010244
Harald Welte261af4b2018-02-12 21:20:39 +010010245 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020010246 execute( TC_ho_int_a5_0() );
10247 execute( TC_ho_int_a5_1() );
10248 execute( TC_ho_int_a5_3() );
10249 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000010250 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010251
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010252 execute( TC_ho_out_of_this_bsc() );
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020010253 execute( TC_ho_out_fail_no_msc_response() );
10254 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020010255 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010256
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010010257 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020010258 execute( TC_ho_into_this_bsc_a5_0() );
10259 execute( TC_ho_into_this_bsc_a5_1() );
10260 execute( TC_ho_into_this_bsc_a5_3() );
10261 execute( TC_ho_into_this_bsc_a5_4() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020010262 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10263 execute( TC_ho_into_this_bsc_tla_v6() );
10264 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020010265 execute( TC_srvcc_eutran_to_geran() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020010266 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020010267 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
10268 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010010269 execute( TC_ho_in_fail_msc_clears() );
10270 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
10271 execute( TC_ho_in_fail_no_detect() );
10272 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010273
Neels Hofmeyr91401012019-07-11 00:42:35 +020010274 execute( TC_ho_neighbor_config_1() );
10275 execute( TC_ho_neighbor_config_2() );
10276 execute( TC_ho_neighbor_config_3() );
10277 execute( TC_ho_neighbor_config_4() );
10278 execute( TC_ho_neighbor_config_5() );
10279 execute( TC_ho_neighbor_config_6() );
10280 execute( TC_ho_neighbor_config_7() );
10281
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010010282 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010010283 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010010284 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020010285
10286 execute( TC_dyn_pdch_ipa_act_deact() );
10287 execute( TC_dyn_pdch_ipa_act_nack() );
10288 execute( TC_dyn_pdch_osmo_act_deact() );
10289 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrole076b3f2021-07-20 16:45:57 +020010290 if (mp_enable_dyn_sdcch8_test) {
10291 execute( TC_dyn_ts_sdcch8_act_deact() );
10292 execute (TC_dyn_ts_sdcch8_tch_call_act_deact() );
10293 execute( TC_dyn_ts_sdcch8_act_nack() );
10294 }
Harald Welte99f3ca02018-06-14 13:40:29 +020010295
Stefan Sperling0796a822018-10-05 13:01:39 +020010296 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020010297 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020010298
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010010299 /* Power control related */
10300 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020010301 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020010302
10303 /* MSC pooling */
10304 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
10305 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
10306 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
10307 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
10308 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10309 execute( TC_mscpool_L3Compl_on_1_msc() );
10310 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
10311 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
10312 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
10313 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
10314 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
10315 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
10316 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
10317 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
10318 execute( TC_mscpool_paging_and_response_imsi() );
10319 execute( TC_mscpool_paging_and_response_tmsi() );
10320 execute( TC_mscpool_no_allow_attach_round_robin() );
10321 execute( TC_mscpool_no_allow_attach_valid_nri() );
10322 }
10323
Harald Welte99f3ca02018-06-14 13:40:29 +020010324 execute( TC_early_conn_fail() );
10325 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020010326 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020010327
Philipp Maier783681c2020-07-16 16:47:06 +020010328 /* Emergency call handling (deny / allow) */
10329 execute( TC_assignment_emerg_setup_allow() );
10330 execute( TC_assignment_emerg_setup_deny_msc() );
10331 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020010332 execute( TC_emerg_premption() );
10333
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070010334 /* Frequency hopping parameters handling */
10335 execute( TC_fh_params_chan_activ() );
10336 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070010337 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070010338 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070010339 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010340
10341 if (mp_enable_lcs_tests) {
10342 execute( TC_lcs_loc_req_for_active_ms() );
10343 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
10344 execute( TC_lcs_loc_req_for_idle_ms() );
10345 execute( TC_lcs_loc_req_no_subscriber() );
10346 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
10347 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
10348 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
10349 execute( TC_cm_service_during_lcs_loc_req() );
10350 execute( TC_ho_during_lcs_loc_req() );
10351 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010352
10353 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010354
10355 execute( TC_refuse_chan_act_to_vamos() );
10356 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010357
10358 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010359
10360 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010361
10362 execute( TC_imm_ass_post_chan_ack() );
10363 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020010364 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010365 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010366 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Harald Welte28d943e2017-11-25 15:00:50 +010010367}
10368
10369}