blob: b35d316c0ce97c89891296029229f199f7ece2d6 [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
Neels Hofmeyrbf720202021-10-02 12:58:24 +020078type record of integer integer_list;
79
Harald Welte5d1a2202017-12-13 19:51:29 +010080const integer NUM_BTS := 3;
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020081const 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 +020082const integer NUM_MSC := 3;
Harald Welteae026692017-12-09 01:03:01 +010083const float T3101_MAX := 12.0;
Harald Welte28d943e2017-11-25 15:00:50 +010084
Harald Welte799c97b2017-12-14 17:50:30 +010085/* make sure to sync this with the osmo-bts.cfg you're using */
Philipp Maiercb6cc482018-03-26 13:08:00 +020086const integer NUM_TCHH_PER_BTS := 2;
87const integer NUM_TCHF_PER_BTS := 4;
Neels Hofmeyr74083c22020-07-29 00:43:01 +020088const integer NUM_SDCCH_PER_BTS := 3;
Harald Welte799c97b2017-12-14 17:50:30 +010089
Neels Hofmeyrbf720202021-10-02 12:58:24 +020090/* Default Training Sequence Code expected for bts[i]:
91 * BTS 0 has BSIC 10 (and no explicit timeslot training_sequence_code config), so expecting TSC = (BSIC & 7) = 2.
92 * BTS 1 has BSIC 11, TSC = (BSIC & 7) = 3.
93 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
94 * BTS 2 has BSIC 12, TSC = (BSIC & 7) = 4.
95 */
96const integer_list BTS_TSC := {
97 2,
98 3,
99 4,
100 4
101}
Harald Welte4003d112017-12-09 22:35:39 +0100102
Harald Welte21b46bd2017-12-17 19:46:32 +0100103/* per-BTS state which we keep */
Harald Welte96c94412017-12-09 03:12:45 +0100104type record BTS_State {
Harald Welte21b46bd2017-12-17 19:46:32 +0100105 /* component reference to the IPA_Client component used for RSL */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100106 IPA_Client rsl
Harald Welte96c94412017-12-09 03:12:45 +0100107}
108
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200109/* Default list of counters for an 'msc' entity. */
110const CounterNameVals counternames_msc_mscpool := {
111 { "mscpool:subscr:new", 0 },
112 { "mscpool:subscr:known", 0 },
113 { "mscpool:subscr:reattach", 0 },
114 { "mscpool:subscr:attach_lost", 0 },
115 { "mscpool:subscr:paged", 0 }
116};
117
Neels Hofmeyrbf037052020-10-28 22:52:02 +0000118/* List of global mscpool counters, not related to a specific 'msc' entity. */
119const CounterNameVals counternames_bsc_mscpool := {
120 { "mscpool:subscr:no_msc", 0 }
121};
122
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000123/* Default list of counters for 'bsc' and 'bts' entities. */
124const CounterNameVals counternames_bsc_bts_handover := {
125 { "assignment:attempted", 0 },
126 { "assignment:completed", 0 },
127 { "assignment:stopped", 0 },
128 { "assignment:no_channel", 0 },
129 { "assignment:timeout", 0 },
130 { "assignment:failed", 0 },
131 { "assignment:error", 0 },
132
133 { "handover:attempted", 0 },
134 { "handover:completed", 0 },
135 { "handover:stopped", 0 },
136 { "handover:no_channel", 0 },
137 { "handover:timeout", 0 },
138 { "handover:failed", 0 },
139 { "handover:error", 0 },
140
141 { "intra_cell_ho:attempted", 0 },
142 { "intra_cell_ho:completed", 0 },
143 { "intra_cell_ho:stopped", 0 },
144 { "intra_cell_ho:no_channel", 0 },
145 { "intra_cell_ho:timeout", 0 },
146 { "intra_cell_ho:failed", 0 },
147 { "intra_cell_ho:error", 0 },
148
149 { "intra_bsc_ho:attempted", 0 },
150 { "intra_bsc_ho:completed", 0 },
151 { "intra_bsc_ho:stopped", 0 },
152 { "intra_bsc_ho:no_channel", 0 },
153 { "intra_bsc_ho:timeout", 0 },
154 { "intra_bsc_ho:failed", 0 },
155 { "intra_bsc_ho:error", 0 },
156
157 { "interbsc_ho_out:attempted", 0 },
158 { "interbsc_ho_out:completed", 0 },
159 { "interbsc_ho_out:stopped", 0 },
160 { "interbsc_ho_out:timeout", 0 },
161 { "interbsc_ho_out:failed", 0 },
162 { "interbsc_ho_out:error", 0 },
163
164 { "interbsc_ho_in:attempted", 0 },
165 { "interbsc_ho_in:completed", 0 },
166 { "interbsc_ho_in:stopped", 0 },
167 { "interbsc_ho_in:no_channel", 0 },
168 { "interbsc_ho_in:timeout", 0 },
169 { "interbsc_ho_in:failed", 0 },
170 { "interbsc_ho_in:error", 0 }
171};
172
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100173const CounterNameVals counternames_bts_handover := {
174 { "incoming_intra_bsc_ho:attempted", 0 },
175 { "incoming_intra_bsc_ho:completed", 0 },
176 { "incoming_intra_bsc_ho:stopped", 0 },
177 { "incoming_intra_bsc_ho:no_channel", 0 },
178 { "incoming_intra_bsc_ho:timeout", 0 },
179 { "incoming_intra_bsc_ho:failed", 0 },
180 { "incoming_intra_bsc_ho:error", 0 }
181};
182
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200183/* Set of all System Information received during one RSL port's startup.
184 * Note that some System Information may be sent on RSL, but lacking actual SI data, to indicate that the BTS should not
185 * broadcast that SI type. That will be reflected as 'omit' here.
186 */
187type record SystemInformationConfig {
188 SystemInformationType1 si1 optional,
189 SystemInformationType2 si2 optional,
190 SystemInformationType2bis si2bis optional,
191 SystemInformationType2ter si2ter optional,
Neels Hofmeyrad132f22020-07-08 02:20:16 +0200192 SI2quaterRestOctetsList si2quater optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200193 SystemInformationType3 si3 optional,
194 SystemInformationType4 si4 optional,
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100195 SystemInformationType13 si13 optional,
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200196 SystemInformationType5 si5 optional,
197 SystemInformationType5bis si5bis optional,
198 SystemInformationType5ter si5ter optional,
199 SystemInformationType6 si6 optional
200};
201
202const SystemInformationConfig SystemInformationConfig_omit := {
203 si1 := omit,
204 si2 := omit,
205 si2bis := omit,
206 si2ter := omit,
207 si2quater := omit,
208 si3 := omit,
209 si4 := omit,
210 si13 := omit,
211 si5 := omit,
212 si5bis := omit,
213 si5ter := omit,
214 si6 := omit
215};
216
217/* tr_EUTRAN_CellDesc with defaults used in BSC_Tests.ttcn */
218template EUTRAN_CellDesc tr_EUTRAN_CellDesc_default(template (present) uint16_t e_arfcn := ?,
219 template uint3_t meas_bw := 3)
220:= tr_EUTRAN_CellDesc(e_arfcn := e_arfcn,
221 meas_bw_presence := '1'B,
222 meas_bw := meas_bw);
223
224/* tr_EUTRAN_NeighbourCells with defaults used in BSC_Tests.ttcn */
Harald Welte65e419a2020-08-21 12:38:33 +0200225template EUTRAN_NeighbourCells tr_EUTRAN_NeighbourCells_default(template (present) EUTRAN_CellDescs cell_desc_list := { tr_EUTRAN_CellDesc_default },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200226 template uint3_t prio := 3,
227 template (present) uint5_t thresh_high := 20,
228 template uint5_t thresh_low := 10,
229 template uint5_t qrxlevmin := 22)
230:= tr_EUTRAN_NeighbourCells(
231 cell_desc_list := cell_desc_list,
232 prio_presence := '1'B,
233 prio := prio,
234 thresh_high := thresh_high,
235 thresh_low_presence := '1'B,
236 thresh_low := thresh_low,
237 qrxlevmin_presence := '1'B,
238 qrxlevmin := qrxlevmin);
239
240template SystemInformationConfig SystemInformationConfig_default := {
241 si1 := {
242 cell_chan_desc := '8FB38000000000000000000000000000'O,
243 rach_control := {
244 max_retrans := RACH_MAX_RETRANS_7,
245 tx_integer := '1001'B,
246 cell_barr_access := false,
247 re_not_allowed := true,
248 acc := '0000010000000000'B
249 },
250 rest_octets := ?
251 },
252 si2 := {
253 bcch_freq_list := '00000000000000000000000000000000'O,
254 ncc_permitted := '11111111'B,
255 rach_control := {
256 max_retrans := RACH_MAX_RETRANS_7,
257 tx_integer := '1001'B,
258 cell_barr_access := false,
259 re_not_allowed := true,
260 acc := '0000010000000000'B
261 }
262 },
263 si2bis := omit,
264 si2ter := {
265 extd_bcch_freq_list := '8E320000000000000000000000000800'O,
266 rest_octets := ?
267 },
268 si2quater := {
269 tr_SI2quaterRestOctets_EUTRAN( repeated_neigh_cells := { tr_EUTRAN_NeighbourCells_default } )
270 },
271 si3 := {
272 cell_id := 0,
273 lai := {
274 mcc_mnc := '001F01'H,
275 lac := 1
276 },
277 ctrl_chan_desc := {
278 msc_r99 := true,
279 att := true,
280 bs_ag_blks_res := 1,
281 ccch_conf := CCHAN_DESC_1CCCH_COMBINED,
282 si22ind := false,
283 cbq3 := CBQ3_IU_MODE_NOT_SUPPORTED,
284 spare := '00'B,
285 bs_pa_mfrms := 3,
286 t3212 := 30
287 },
288 cell_options := {
289 dn_ind := false,
290 pwrc := false,
291 dtx := MS_SHALL_USE_UL_DTX,
292 radio_link_tout_div4 := 7
293 },
294 cell_sel_par := {
295 cell_resel_hyst_2dB := 2,
296 ms_txpwr_max_cch := 7,
297 acs := '0'B,
298 neci := true,
299 rxlev_access_min := 0
300 },
301 rach_control := {
302 max_retrans := RACH_MAX_RETRANS_7,
303 tx_integer := '1001'B,
304 cell_barr_access := false,
305 re_not_allowed := true,
306 acc := '0000010000000000'B
307 },
308 rest_octets := {
309 sel_params := {
310 presence := '0'B,
311 params := omit
312 },
313 pwr_offset := {
314 presence := '0'B,
315 offset := omit
316 },
317 si_2ter_ind := '1'B,
318 early_cm_ind := '0'B,
319 sched_where := {
320 presence := '0'B,
321 where := omit
322 },
323 gprs_ind := {
324 presence := '1'B,
325 ind := {
326 ra_colour := 0,
327 si13_pos := '0'B
328 }
329 },
330 umts_early_cm_ind := '1'B,
331 si2_quater_ind := {
332 presence := '1'B,
333 ind := '0'B
334 },
335 iu_mode_ind := omit,
336 si21_ind := {
337 presence := '0'B,
338 pos := omit
339 }
340 }
341 },
342 si4 := {
343 lai := {
344 mcc_mnc := '001F01'H,
345 lac := 1
346 },
347 cell_sel_par := {
348 cell_resel_hyst_2dB := 2,
349 ms_txpwr_max_cch := 7,
350 acs := '0'B,
351 neci := true,
352 rxlev_access_min := 0
353 },
354 rach_control := {
355 max_retrans := RACH_MAX_RETRANS_7,
356 tx_integer := '1001'B,
357 cell_barr_access := false,
358 re_not_allowed := true,
359 acc := '0000010000000000'B
360 },
Neels Hofmeyr74083c22020-07-29 00:43:01 +0200361 cbch_chan_desc := {
362 iei := '64'O,
363 v := {
364 chan_nr := {
365 u := {
366 sdcch4 := {
367 tag := '001'B,
368 sub_chan := 2
369 }
370 },
371 tn := 0
372 },
373 tsc := 2,
374 h := false,
375 arfcn := 871,
376 maio_hsn := omit
377 }
378 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200379 cbch_mobile_alloc := omit,
380 rest_octets := {
381 sel_params := {
382 presence := '0'B,
383 params := omit
384 },
385 pwr_offset := {
386 presence := '0'B,
387 offset := omit
388 },
389 gprs_ind := {
390 presence := '1'B,
391 ind := {
392 ra_colour := 0,
393 si13_pos := '0'B
394 }
395 },
396 s_presence := '0'B,
397 s := omit
398 }
399 },
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100400 si13 := {
401 rest_octets := {
402 presence := '1'B,
403 bcch_change_mark := ?,
404 si_change_field := '0000'B,
405 presence2 := '0'B,
406 si13_change_mark := omit,
407 gprs_ma := omit,
408 zero := '0'B, /* PBCCH not present in cell */
409 rac := 0,
410 spgc_ccch_sup := '0'B,
411 priority_access_thr := '110'B,
412 network_control_order := '00'B,
413 gprs_cell_opts := {
414 nmo := '01'B,
415 t3168 := '011'B,
416 t3192 := '010'B,
417 drx_timer_max := '011'B,
418 access_burst_type := '0'B,
419 control_ack_type := '1'B,
420 bs_cv_max := 15,
421 pan_presence := '1'B,
422 pan_dec := 1,
423 pan_inc := 1,
424 pan_max := '111'B,
425 ext_info_presence := ?,
426 ext_info_length := *,
427 ext_info := *
428 },
429 gprs_pwr_ctrl_params := {
430 alpha := 0,
431 t_avg_w := '10000'B,
432 t_avg_t := '10000'B,
433 pc_meas_chan := '0'B,
434 n_avg_i := '1000'B
435 }
436 }
437 },
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200438 si5 := {
439 bcch_freq_list := '10000000000000000000000000000000'O
440 },
441 si5bis := omit,
442 si5ter := {
443 extd_bcch_freq_list := '9E050020000000000000000000000000'O
444 },
445 si6 := {
446 cell_id := 0,
447 lai := {
448 mcc_mnc := '001F01'H,
449 lac := 1
450 },
451 cell_options := {
452 dtx_ext := '1'B,
453 pwrc := false,
454 dtx := '01'B,
455 radio_link_timeout := '0111'B
456 },
457 ncc_permitted := '11111111'B,
Vadim Yanitskiy348b07c2022-03-10 17:11:22 +0300458 rest_octets := {
459 pch_nch_info := ?,
460 vbs_vgcs_options := ?,
461 dtm_support := '0'B,
462 rac := omit,
463 max_lapdm := omit,
464 band_ind := '0'B /* C0 ARFCN indicates 1800 band */
465 }
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200466 }
467 };
468
469
470/* List of all the System Information received on all RSL ports */
471type record of SystemInformationConfig SystemInformationConfig_list;
472
473function f_sysinfo_dec_raw(inout SystemInformationConfig si, RSL_Message rsl)
474{
475 var RSL_IE_Body sysinfo_type_ie;
476 var RSL_IE_SysinfoType si_type;
477 var octetstring data;
478
479 if (f_rsl_find_ie(rsl, RSL_IE_SYSINFO_TYPE, sysinfo_type_ie) == false) {
480 setverdict(fail, "Cannot find RSL_IE_SYSINFO_TYPE");
481 mtc.stop;
482 }
483 si_type := sysinfo_type_ie.sysinfo_type;
484
485 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
486 var RSL_IE_Body bcch_ie;
487 if (f_rsl_find_ie(rsl, RSL_IE_FULL_BCCH_INFO, bcch_ie)) {
488 data := bcch_ie.other.payload;
489 }
490 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
491 var RSL_IE_Body l3_ie;
492 if (f_rsl_find_ie(rsl, RSL_IE_L3_INFO, l3_ie)) {
493 data := l3_ie.l3_info.payload;
494 }
495 } else {
496 setverdict(fail, "Don't understand this System Information message");
497 mtc.stop;
498 }
499
500 var boolean handled := false;
501
502 if (rsl.msg_type == RSL_MT_BCCH_INFO) {
503 handled := true;
504
505 if (si_type == RSL_SYSTEM_INFO_1) {
506 if (not isbound(data)) {
507 si.si1 := omit;
508 } else {
509 si.si1 := dec_SystemInformation(data).payload.si1;
510 }
511 } else if (si_type == RSL_SYSTEM_INFO_2) {
512 if (not isbound(data)) {
513 si.si2 := omit;
514 } else {
515 si.si2 := dec_SystemInformation(data).payload.si2;
516 }
517 } else if (si_type == RSL_SYSTEM_INFO_2bis) {
518 if (not isbound(data)) {
519 si.si2bis := omit;
520 } else {
521 si.si2bis := dec_SystemInformation(data).payload.si2bis;
522 }
523 } else if (si_type == RSL_SYSTEM_INFO_2ter) {
524 if (not isbound(data)) {
525 si.si2ter := omit;
526 } else {
527 si.si2ter := dec_SystemInformation(data).payload.si2ter;
528 }
529 } else if (si_type == RSL_SYSTEM_INFO_2quater) {
530 if (not isbound(data)) {
531 si.si2quater := {};
532 } else {
533 var SystemInformationType2quater decoded := dec_SystemInformation(data).payload.si2quater;
534 /* this is a *record* of SI2quaterRestOctets! (multiplexed) */
535 si.si2quater[decoded.rest_octets.si2quater_index] := decoded.rest_octets;
536 }
537 } else if (si_type == RSL_SYSTEM_INFO_3) {
538 if (not isbound(data)) {
539 si.si3 := omit;
540 } else {
541 si.si3 := dec_SystemInformation(data).payload.si3;
542 }
543 } else if (si_type == RSL_SYSTEM_INFO_4) {
544 if (not isbound(data)) {
545 si.si4 := omit;
546 } else {
547 si.si4 := dec_SystemInformation(data).payload.si4;
548 }
549 } else if (si_type == RSL_SYSTEM_INFO_13) {
550 if (not isbound(data)) {
551 si.si13 := omit;
552 } else {
Pau Espin Pedrol28652d82021-02-09 20:20:17 +0100553 si.si13 := dec_SystemInformation(data).payload.si13;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200554 }
555 } else {
556 handled := false;
557 }
558 } else if (rsl.msg_type == RSL_MT_SACCH_FILL) {
559 handled := true;
560
561 if (si_type == RSL_SYSTEM_INFO_5) {
562 if (not isbound(data)) {
563 si.si5 := omit;
564 } else {
565 si.si5 := dec_SystemInformation(data).payload.si5;
566 }
567 } else if (si_type == RSL_SYSTEM_INFO_5bis) {
568 if (not isbound(data)) {
569 si.si5bis := omit;
570 } else {
571 si.si5bis := dec_SystemInformation(data).payload.si5bis;
572 }
573 } else if (si_type == RSL_SYSTEM_INFO_5ter) {
574 if (not isbound(data)) {
575 si.si5ter := omit;
576 } else {
577 si.si5ter := dec_SystemInformation(data).payload.si5ter;
578 }
579 } else if (si_type == RSL_SYSTEM_INFO_6) {
580 if (not isbound(data)) {
581 si.si6 := omit;
582 } else {
583 si.si6 := dec_SystemInformation(data).payload.si6;
584 }
585 } else {
586 handled := false;
587 }
588 }
589
590 if (not handled) {
591 setverdict(fail, "Unexpected SI type in ", rsl.msg_type, " message: ", si_type);
592 }
593}
594
Harald Weltea4ca4462018-02-09 00:17:14 +0100595type component test_CT extends CTRL_Adapter_CT {
Harald Welte21b46bd2017-12-17 19:46:32 +0100596 /* Array of per-BTS state */
Harald Welte96c94412017-12-09 03:12:45 +0100597 var BTS_State bts[NUM_BTS];
Harald Welte89ab1912018-02-23 18:56:29 +0100598 /* RSL common Channel Port (for RSL_Emulation) */
599 port RSL_CCHAN_PT RSL_CCHAN[NUM_BTS];
Harald Welte21b46bd2017-12-17 19:46:32 +0100600 /* array of per-BTS RSL test ports */
Harald Welteae026692017-12-09 01:03:01 +0100601 port IPA_RSL_PT IPA_RSL[NUM_BTS];
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100602 port IPA_CODEC_PT IPA; /* Required for compilation of TC_rsl_unknown_unit_id() */
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +0200603 /* CTRL muxed over IPA in SCCPlite conn BSC<->MSC (or BSC-NAT) */
604 port IPA_CTRL_PT SCCPLITE_IPA_CTRL;
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100605 /* Configure/manage IPA_Emulation: */
606 port IPA_CFG_PT IPA_CFG_PORT;
Harald Weltea5d2ab22017-12-09 14:21:42 +0100607
Daniel Willmann191e0d92018-01-17 12:44:35 +0100608 var MGCP_Emulation_CT vc_MGCP;
Harald Weltebc03c762018-02-12 18:09:38 +0100609 port TELNETasp_PT BSCVTY;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100610
Daniel Willmannebdecc02020-08-12 15:30:17 +0200611 /* StatsD */
612 var StatsD_Checker_CT vc_STATSD;
613
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200614 var RAN_Adapter g_bssap[NUM_MSC];
Harald Welte47cd0e32020-08-21 12:39:11 +0200615 var BSSAP_LE_Adapter g_bssap_le;
Harald Weltea4ca4462018-02-09 00:17:14 +0100616 /* for old legacy-tests only */
617 port BSSAP_CODEC_PT BSSAP;
Harald Welte47cd0e32020-08-21 12:39:11 +0200618 port BSSAP_LE_CODEC_PT BSSAP_LE;
Harald Weltea4ca4462018-02-09 00:17:14 +0100619
Harald Welte21b46bd2017-12-17 19:46:32 +0100620 /* are we initialized yet */
Harald Welte28d943e2017-11-25 15:00:50 +0100621 var boolean g_initialized := false;
Harald Welte21b46bd2017-12-17 19:46:32 +0100622
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200623 /* Osmux is enabled through VTY */
624 var boolean g_osmux_enabled := false;
625
Pau Espin Pedrolc675b612020-01-09 19:55:40 +0100626 /*Configure T(tias) over VTY, seconds */
627 var integer g_bsc_sccp_timer_ias := 7 * 60;
628 /*Configure T(tiar) over VTY, seconds */
629 var integer g_bsc_sccp_timer_iar := 15 * 60;
630
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +0200631 /* global test case guard timer (actual timeout value is set in f_init()) */
Harald Welteae026692017-12-09 01:03:01 +0100632 timer T_guard := 30.0;
633
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200634 var CounterNameValsList g_ctr_msc;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000635 var CounterNameValsList g_ctr_bsc;
636 var CounterNameValsList g_ctr_bts;
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +0200637
638 /* System Information bytes as received during RSL startup, for each RSL[idx]. */
639 var SystemInformationConfig_list g_system_information := {};
Harald Welte28d943e2017-11-25 15:00:50 +0100640}
641
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200642type record of charstring phys_chan_configs;
Harald Welte28d943e2017-11-25 15:00:50 +0100643modulepar {
Harald Welte21b46bd2017-12-17 19:46:32 +0100644 /* IP address at which the BSC can be reached */
Harald Welte696ddb62017-12-08 14:01:43 +0100645 charstring mp_bsc_ip := "127.0.0.1";
Stefan Sperling830dc9d2018-02-12 21:08:28 +0100646 /* port number to which to establish the IPA OML connections */
647 integer mp_bsc_oml_port := 3002;
Harald Welte21b46bd2017-12-17 19:46:32 +0100648 /* port number to which to establish the IPA RSL connections */
Harald Welte696ddb62017-12-08 14:01:43 +0100649 integer mp_bsc_rsl_port := 3003;
Harald Welte21b46bd2017-12-17 19:46:32 +0100650 /* port number to which to establish the IPA CTRL connection */
Harald Welte96c94412017-12-09 03:12:45 +0100651 integer mp_bsc_ctrl_port := 4249;
Daniel Willmannebdecc02020-08-12 15:30:17 +0200652 /* port number to which to listen for STATSD metrics */
653 integer mp_bsc_statsd_port := 8125;
Daniel Willmann191e0d92018-01-17 12:44:35 +0100654 /* IP address at which the test binds */
655 charstring mp_test_ip := "127.0.0.1";
Harald Weltea4ca4462018-02-09 00:17:14 +0100656
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200657 RAN_Configurations mp_bssap_cfg := {
658 {
659 transport := BSSAP_TRANSPORT_AoIP,
660 sccp_service_type := "mtp3_itu",
661 sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" },
662 own_pc := 185, /* 0.23.1 first MSC emulation */
663 own_ssn := 254,
664 peer_pc := 187, /* 0.23.3 osmo-bsc */
665 peer_ssn := 254,
666 sio := '83'O,
Harald Weltecb0cc432020-06-21 19:42:31 +0200667 rctx := 1
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200668 },
669 {
670 transport := BSSAP_TRANSPORT_AoIP,
671 sccp_service_type := "mtp3_itu",
672 sctp_addr := { 23906, "127.0.0.1", 2905, "127.0.0.1" },
673 own_pc := 2, /* 0.0.2 second MSC emulation */
674 own_ssn := 254,
675 peer_pc := 187, /* 0.23.3 osmo-bsc */
676 peer_ssn := 254,
677 sio := '83'O,
678 rctx := 2
679 },
680 {
681 transport := BSSAP_TRANSPORT_AoIP,
682 sccp_service_type := "mtp3_itu",
683 sctp_addr := { 23907, "127.0.0.1", 2905, "127.0.0.1" },
684 own_pc := 3, /* 0.0.3 third MSC emulation */
685 own_ssn := 254,
686 peer_pc := 187, /* 0.23.3 osmo-bsc */
687 peer_ssn := 254,
688 sio := '83'O,
689 rctx := 3
690 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100691 };
Pau Espin Pedrol58cf6822019-05-28 18:11:33 +0200692
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200693 /* Must match per BTS config in osmo-bsc.cfg */
694 phys_chan_configs phys_chan_config := {
695 "CCCH+SDCCH4+CBCH",
696 "TCH/F",
697 "TCH/F",
698 "TCH/F",
699 "TCH/F",
Vadim Yanitskiy343c9eb2021-07-16 18:36:01 +0600700 "TCH/H",
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +0200701 "PDCH",
702 "PDCH"
703 };
704
Harald Welte47cd0e32020-08-21 12:39:11 +0200705 BSSAP_LE_Configuration mp_bssap_le_cfg := {
706 sccp_service_type := "mtp3_itu",
707 sctp_addr := { 23908, "127.0.0.1", 2905, "127.0.0.1" },
Neels Hofmeyrac086c12020-09-18 23:46:42 +0200708 own_pc := 190, /* 0.23.6 SMLC emulation */
Harald Welte47cd0e32020-08-21 12:39:11 +0200709 own_ssn := 252, /* SMLC side SSN */
710 peer_pc := 187, /* 0.23.3 osmo-bsc */
711 peer_ssn := 250, /* BSC side SSN */
712 sio := '83'O,
713 rctx := 6
714 };
Neels Hofmeyrcfe44062020-10-15 02:28:08 +0200715 boolean mp_enable_lcs_tests := true;
Harald Welte47cd0e32020-08-21 12:39:11 +0200716
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100717 /* Value set in osmo-bsc.cfg "ms max power" */
718 uint8_t mp_exp_ms_power_level := 7;
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600719
720 /* Whether to check for memory leaks */
721 boolean mp_verify_talloc_count := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100722}
723
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200724friend function f_gen_test_hdlr_pars(integer bssap_idx := 0) return TestHdlrParams {
Philipp Maier48604732018-10-09 15:00:37 +0200725
726 var TestHdlrParams pars := valueof(t_def_TestHdlrPars);
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200727 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier48604732018-10-09 15:00:37 +0200728 pars.aoip := true;
729 } else {
730 pars.aoip := false;
731 }
Pau Espin Pedrol8f30ccd2019-11-01 17:30:57 +0100732 pars.exp_ms_power_level := mp_exp_ms_power_level;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200733 pars.mscpool.bssap_idx := bssap_idx;
Neels Hofmeyrbf720202021-10-02 12:58:24 +0200734 pars.expect_tsc := BTS_TSC[0];
Vadim Yanitskiy96bb9cb2021-12-10 21:14:15 +0300735 pars.imsi := f_rnd_imsi('00101'H);
736
737 log(testcasename(), ": using IMSI ", pars.imsi);
Neels Hofmeyrb5b7a6e2021-06-04 19:03:45 +0200738
Philipp Maier48604732018-10-09 15:00:37 +0200739 return pars;
740}
741
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200742/* Convenience functions for rate counters using g_ctr_msc. */
743
744private function f_ctrs_msc_init(integer mscs_count := NUM_MSC, CounterNameVals counternames := counternames_msc_mscpool) runs on test_CT {
745 g_ctr_msc := f_counter_name_vals_get_n(IPA_CTRL, "msc", mscs_count, counternames);
746 log("initial msc rate counters: ", g_ctr_msc);
747}
748
749private function f_ctrs_msc_add(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr9656e922020-06-30 01:27:01 +0200750 f_counter_name_vals_list_add(g_ctr_msc, msc_nr, countername, val);
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200751}
752
753/* f_ctrs_msc_init();
754 * f_do_thing(on_msc := 0);
755 * f_do_thing(on_msc := 0);
756 * f_do_other(on_msc := 1);
757 * f_ctrs_msc_add(0, "thing", 2);
758 * f_ctrs_msc_add(1, "other");
759 * f_ctrs_msc_verify();
760 */
761private function f_ctrs_msc_verify() runs on test_CT {
762 log("verifying msc rate counters: ", g_ctr_msc);
763 f_counter_name_vals_expect_n(IPA_CTRL, "msc", g_ctr_msc);
764}
765
766/* convenience: f_ctrs_msc_add() and f_ctrs_msc_verify() in one call.
767 * f_ctrs_msc_init();
768 * f_do_thing(on_msc := 0);
769 * f_do_thing(on_msc := 0);
770 * f_do_thing(on_msc := 0);
771 * f_ctrs_msc_expect(0, "thing", 3);
772 */
773private function f_ctrs_msc_expect(integer msc_nr, charstring countername, integer val := 1) runs on test_CT {
774 f_ctrs_msc_add(msc_nr, countername, val);
775 f_ctrs_msc_verify();
776}
777
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000778/* Convenience functions for rate counters using g_ctr_bts, always also including g_ctr_bsc. */
779
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100780private function f_ctrs_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000781 g_ctr_bts := f_counter_name_vals_get_n(IPA_CTRL, "bts", bts_count, counternames);
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100782 log("initial bts rate counters: ", g_ctr_bts);
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100783}
784
785function f_ctrs_bsc_and_bts_init(integer bts_count := NUM_BTS, CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
786 f_ctrs_bts_init(bts_count, counternames);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000787 f_ctrs_bsc_init(counternames);
788}
789
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100790private function f_ctrs_bsc_and_bts_handover_init(integer bts_count := NUM_BTS) runs on test_CT {
791 var CounterNameVals bts_names := counternames_bsc_bts_handover & counternames_bts_handover;
Neels Hofmeyr4dec8cc2021-11-29 15:59:44 +0100792 f_ctrs_bts_init(bts_count, bts_names);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100793 f_ctrs_bsc_init(counternames_bsc_bts_handover);
794}
795
796private function f_ctrs_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000797 f_counter_name_vals_list_add(g_ctr_bts, bts_nr, countername, val);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +0100798}
799
800private function f_ctrs_bsc_and_bts_add(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
801 f_ctrs_bts_add(bts_nr, countername, val);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000802 f_ctrs_bsc_add(countername, val);
803}
804
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100805function f_ctrs_bts_verify() runs on test_CT {
806 f_counter_name_vals_expect_n(IPA_CTRL, "bts", g_ctr_bts);
807}
808
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000809/* f_ctrs_bsc_and_bts_init();
810 * f_do_thing(on_bts := 0);
811 * f_do_thing(on_bts := 0);
812 * f_do_other(on_bts := 1);
813 * f_ctrs_bsc_and_bts_add(0, "thing", 2);
814 * f_ctrs_bsc_and_bts_add(1, "other");
815 * f_ctrs_bsc_and_bts_verify();
816 */
817private function f_ctrs_bsc_and_bts_verify() runs on test_CT {
Neels Hofmeyrb7581872021-11-07 14:02:49 +0100818 f_ctrs_bts_verify();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +0000819 f_ctrs_bsc_verify();
820}
821
822/* convenience: f_ctrs_bsc_and_bts_add() and f_ctrs_bsc_and_bts_verify() in one call.
823 * f_ctrs_bsc_and_bts_init();
824 * f_do_thing(on_bts := 0);
825 * f_do_thing(on_bts := 0);
826 * f_do_thing(on_bts := 0);
827 * f_ctrs_bsc_and_bts_expect(0, "thing", 3);
828 */
829private function f_ctrs_bsc_and_bts_expect(integer bts_nr, charstring countername, integer val := 1) runs on test_CT {
830 f_ctrs_bsc_and_bts_add(bts_nr, countername, val);
831 f_ctrs_bsc_and_bts_verify();
832}
833
834
835/* Convenience functions for rate counters using g_ctr_bsc. */
836
837private function f_ctrs_bsc_init(CounterNameVals counternames := counternames_bsc_bts_handover) runs on test_CT {
838 g_ctr_bsc := f_counter_name_vals_get_n(IPA_CTRL, "bsc", 1, counternames);
839 log("initial bsc rate counters: ", g_ctr_bsc);
840}
841
842private function f_ctrs_bsc_add(charstring countername, integer val := 1) runs on test_CT {
843 f_counter_name_vals_list_add(g_ctr_bsc, 0, countername, val);
844}
845
846/* f_ctrs_bsc_init();
847 * f_do_thing();
848 * f_do_thing();
849 * f_do_other();
850 * f_ctrs_bsc_add("thing", 2);
851 * f_ctrs_bsc_add("other");
852 * f_ctrs_bsc_verify();
853 */
854private function f_ctrs_bsc_verify() runs on test_CT {
855 f_counter_name_vals_expect_n(IPA_CTRL, "bsc", g_ctr_bsc);
856}
857
858/* convenience: f_ctrs_bsc_add() and f_ctrs_bsc_verify() in one call.
859 * f_ctrs_bsc_init();
860 * f_do_thing();
861 * f_ctrs_bsc_expect("thing", 1);
862 */
863private function f_ctrs_bsc_expect(charstring countername, integer val := 1) runs on test_CT {
864 f_ctrs_bsc_add(countername, val);
865 f_ctrs_bsc_verify();
866}
867
Neels Hofmeyr22c3f792020-06-17 02:49:28 +0200868
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +0200869friend function f_shutdown_helper() runs on test_CT {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100870 /* Run the subscr and conn leak test only when the VTY is initialized */
Vadim Yanitskiy6e068012022-02-05 21:35:43 +0600871 if (BSCVTY.checkstate("Mapped") and mp_verify_talloc_count) {
Neels Hofmeyr18997492021-12-13 17:30:35 +0100872 f_verify_talloc_count(BSCVTY, {"struct bsc_subscr", "struct gsm_subscriber_connection"});
873 }
874
Daniel Willmann637ef6c2018-07-25 10:49:09 +0200875 all component.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100876 setverdict(pass);
Daniel Willmannafce8662018-07-06 23:11:32 +0200877 mtc.stop;
Philipp Maier282ca4b2018-02-27 17:17:00 +0100878}
879
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200880private function f_legacy_bssap_reset(integer bssap_idx := 0) runs on test_CT {
Harald Weltea4ca4462018-02-09 00:17:14 +0100881 var BSSAP_N_UNITDATA_ind ud_ind;
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200882 var boolean reset_received := false;
Harald Weltea4ca4462018-02-09 00:17:14 +0100883 timer T := 5.0;
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200884 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
885 ts_BSSMAP_Reset(0, g_osmux_enabled)));
Harald Weltea4ca4462018-02-09 00:17:14 +0100886 T.start;
887 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +0200888 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_bssap[bssap_idx].sccp_addr_own, g_bssap[bssap_idx].sccp_addr_peer,
889 tr_BSSMAP_ResetAck(g_osmux_enabled))) {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200890 log("BSSMAP: Received RESET-ACK in response to RESET, we're ready to go!");
Harald Weltea4ca4462018-02-09 00:17:14 +0100891 }
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200892 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200893 log("BSSMAP: Respoding to inbound RESET with RESET-ACK");
Harald Weltea4ca4462018-02-09 00:17:14 +0100894 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +0200895 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200896 reset_received := true;
Harald Weltea4ca4462018-02-09 00:17:14 +0100897 repeat;
898 }
899 [] BSSAP.receive { repeat; }
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200900 [] T.timeout {
Neels Hofmeyr4f5d7be2020-10-16 16:28:16 +0200901 log("BSSMAP: Timeout waiting for RESET-ACK after sending RESET");
Pau Espin Pedrol24c05992020-09-01 12:54:12 +0200902 /* If we received a RESET after ours was sent, it
903 may be a race condition where the other peer beacame
904 available after we sent it, but we are in a desired
905 state anyway, so go forward. */
906 if (not reset_received) {
907 setverdict(fail);
908 }
909 }
Harald Weltea4ca4462018-02-09 00:17:14 +0100910 }
Harald Welte28d943e2017-11-25 15:00:50 +0100911}
912
Harald Welteae026692017-12-09 01:03:01 +0100913type record IPA_Client {
Harald Welte21b46bd2017-12-17 19:46:32 +0100914 /* IPA Emulation component reference */
Harald Welteae026692017-12-09 01:03:01 +0100915 IPA_Emulation_CT vc_IPA,
Harald Welte21b46bd2017-12-17 19:46:32 +0100916 /* Unit-ID and other CCM parameters to use for IPA client emulation */
Harald Welteae026692017-12-09 01:03:01 +0100917 IPA_CCM_Parameters ccm_pars,
Harald Welte21b46bd2017-12-17 19:46:32 +0100918 /* String identifier for this IPA Client */
Harald Welte624f9632017-12-16 19:26:04 +0100919 charstring id,
Harald Welte21b46bd2017-12-17 19:46:32 +0100920 /* Associated RSL Emulation Component (if any). Only used in "Handler mode" */
Harald Welte624f9632017-12-16 19:26:04 +0100921 RSL_Emulation_CT vc_RSL optional
Harald Welte28d943e2017-11-25 15:00:50 +0100922}
923
Harald Welte21b46bd2017-12-17 19:46:32 +0100924/*! Start the IPA/RSL related bits for one IPA_Client.
925 * \param clnt IPA_Client for which to establish
926 * \param bsc_host IP address / hostname of the BSC
927 * \param bsc_port TCP port number of the BSC
928 * \param i number identifying this BTS
929 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false) */
Harald Welte624f9632017-12-16 19:26:04 +0100930function f_ipa_rsl_start(inout IPA_Client clnt, charstring bsc_host, PortNumber bsc_port, integer i,
931 boolean handler_mode := false)
Harald Welte28d943e2017-11-25 15:00:50 +0100932runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +0100933 timer T := 10.0;
934
Harald Welte96c94412017-12-09 03:12:45 +0100935 clnt.id := "IPA" & int2str(i) & "-RSL";
Harald Welte71389132021-12-09 21:58:18 +0100936 clnt.vc_IPA := IPA_Emulation_CT.create(clnt.id & "-IPA") alive;
Harald Welteae026692017-12-09 01:03:01 +0100937 clnt.ccm_pars := c_IPA_default_ccm_pars;
938 clnt.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
939 clnt.ccm_pars.unit_id := int2str(1234+i) & "/0/0";
Harald Welte624f9632017-12-16 19:26:04 +0100940 if (handler_mode) {
Harald Welte71389132021-12-09 21:58:18 +0100941 clnt.vc_RSL := RSL_Emulation_CT.create(clnt.id & "-RSL") alive;
Harald Welte89ab1912018-02-23 18:56:29 +0100942 connect(clnt.vc_RSL:CCHAN_PT, self:RSL_CCHAN[i]);
Harald Welte624f9632017-12-16 19:26:04 +0100943 }
Harald Welteae026692017-12-09 01:03:01 +0100944
945 map(clnt.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100946 connect(clnt.vc_IPA:CFG_PORT, self:IPA_CFG_PORT);
Harald Welte624f9632017-12-16 19:26:04 +0100947 if (handler_mode) {
948 connect(clnt.vc_IPA:IPA_RSL_PORT, clnt.vc_RSL:IPA_PT);
949 } else {
950 connect(clnt.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[i]);
951 }
Harald Welteae026692017-12-09 01:03:01 +0100952
Harald Welte5d1a2202017-12-13 19:51:29 +0100953 clnt.vc_IPA.start(IPA_Emulation.main_client(bsc_host, bsc_port, "", 10000+i, clnt.ccm_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100954 if (handler_mode) {
955 clnt.vc_RSL.start(RSL_Emulation.main());
956 return;
957 }
Harald Welteae026692017-12-09 01:03:01 +0100958
959 /* wait for IPA RSL link to connect and send ID ACK */
960 T.start;
961 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +0700962 [] IPA_RSL[i].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) {
Harald Welteae026692017-12-09 01:03:01 +0100963 T.stop;
Harald Welteae026692017-12-09 01:03:01 +0100964 }
Harald Welte60e823a2017-12-10 14:10:59 +0100965 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100966 [] IPA_RSL[i].receive { repeat }
967 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100968 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200969 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100970 }
971 }
972}
973
Harald Welte12055472018-03-17 20:10:08 +0100974function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100975 var IPL4asp_Types.Result res := {
976 errorCode := omit,
977 connId := omit,
978 os_error_code := omit,
979 os_error_text := omit
980 };
981
Harald Welte12055472018-03-17 20:10:08 +0100982 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
983 return;
984 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100985
986 /* Alive components don't finish sockets (TCP FIN) when they are
987 * stopped. Hence, we need to manually call close() on them to make sure
988 * the IUT knows about it. */
989 f_ipa_cfg_disconnect(IPA_CFG_PORT, res);
990
Harald Welte12055472018-03-17 20:10:08 +0100991 clnt.vc_IPA.stop;
992 if (isbound(clnt.vc_RSL)) {
993 clnt.vc_RSL.stop;
994 }
995}
996
Harald Welte21b46bd2017-12-17 19:46:32 +0100997/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100998function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
999 timer T := secs_max;
1000 T.start;
1001 while (true) {
1002 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1003 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001004 /* the 'degraded' state exists from OML connection time, and we have to wait
1005 * until all MO's are initialized */
1006 T.start(1.0);
1007 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001008 return;
1009 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001010 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001011 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001012 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001013 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001014 }
1015 }
1016}
1017
Harald Welte21b46bd2017-12-17 19:46:32 +01001018/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001019altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001020 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001021 [] T_guard.timeout {
1022 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001023 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001024 }
Harald Welte60e823a2017-12-10 14:10:59 +01001025 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001026 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001027 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001028 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +01001029 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001030 }
Harald Welte28d943e2017-11-25 15:00:50 +01001031}
1032
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001033altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001034 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001035 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001036 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001037 }
1038}
1039
Daniel Willmann191e0d92018-01-17 12:44:35 +01001040function f_init_mgcp(charstring id) runs on test_CT {
1041 id := id & "-MGCP";
1042
1043 var MGCPOps ops := {
1044 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1045 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1046 };
1047 var MGCP_conn_parameters mgcp_pars := {
1048 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001049 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001050 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001051 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001052 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1053 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001054 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001055 };
1056
Harald Welte71389132021-12-09 21:58:18 +01001057 vc_MGCP := MGCP_Emulation_CT.create(id) alive;
Daniel Willmann191e0d92018-01-17 12:44:35 +01001058 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1059}
1060
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001061/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1062 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1063 * OsmuxCID IE.
1064 */
1065private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1066 f_vty_enter_cfg_msc(BSCVTY, 0);
1067 if (allow) {
1068 f_vty_transceive(BSCVTY, "osmux on");
1069 } else {
1070 f_vty_transceive(BSCVTY, "osmux off");
1071 }
1072 f_vty_transceive(BSCVTY, "exit");
1073 f_vty_transceive(BSCVTY, "exit");
1074 g_osmux_enabled := allow;
1075}
1076
Max2253c0b2018-11-06 19:28:05 +01001077function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001078 if (BSCVTY.checkstate("Mapped")) {
1079 /* skip initialization if already executed once */
1080 return;
1081 }
Harald Weltebc03c762018-02-12 18:09:38 +01001082 map(self:BSCVTY, system:BSCVTY);
1083 f_vty_set_prompts(BSCVTY);
1084 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001085 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1086 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001087}
1088
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001089friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001090{
1091 // log on TTCN3 log output
1092 log(log_msg);
1093 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001094 if (pt.checkstate("Mapped")) {
1095 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1096 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001097}
1098
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001099private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1100{
1101 if (rsl_idx >= lengthof(g_system_information)) {
1102 g_system_information[rsl_idx] := SystemInformationConfig_omit
1103 }
1104 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1105}
1106
1107altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1108 var ASP_RSL_Unitdata rx_rsl_ud;
1109
1110 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1111 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1112 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1113 repeat;
1114 }
1115 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1116 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1117 repeat;
1118 }
1119 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1120 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1121 repeat;
1122 }
1123 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1124 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1125 repeat;
1126 }
1127
1128 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1129 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1130 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1131 repeat;
1132 }
1133 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1134 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1135 repeat;
1136 }
1137 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1138 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1139 repeat;
1140 }
1141 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1142 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1143 repeat;
1144 }
1145}
1146
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001147/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1148private type record of boolean my_BooleanList;
1149
1150private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1151{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001152 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1153
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001154 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001155 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1156 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1157 * stepping into that config node. */
1158 log("msc ", msc_nr, " is not configured, skipping");
1159 continue;
1160 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001161 f_vty_enter_cfg_msc(pt, msc_nr);
1162 if (allow_attach_list[msc_nr]) {
1163 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1164 f_vty_transceive(pt, "allow-attach", strict := false);
1165 } else {
1166 f_vty_transceive(pt, "no allow-attach", strict := false);
1167 }
1168 f_vty_transceive(pt, "exit");
1169 f_vty_transceive(pt, "exit");
1170 }
1171}
1172
Harald Welte21b46bd2017-12-17 19:46:32 +01001173/* global initialization function
1174 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001175 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1176 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1177 */
1178function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001179 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001180 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001181
Harald Welteae026692017-12-09 01:03:01 +01001182 if (g_initialized) {
1183 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001184 }
Harald Welteae026692017-12-09 01:03:01 +01001185 g_initialized := true;
1186
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001187 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001188 activate(as_Tguard());
1189
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001190 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001191 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001192
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001193 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001194 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1195
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001196 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1197 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1198 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1199 }
1200
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001201 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001202 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001203 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1204 * MSC-side BSSAP emulation */
1205 if (handler_mode) {
1206 var RanOps ranops := MSC_RanOps;
1207 ranops.use_osmux := g_osmux_enabled;
1208 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1209 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1210 f_ran_adapter_start(g_bssap[bssap_idx]);
1211 } else {
1212 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1213 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1214 f_ran_adapter_start(g_bssap[bssap_idx]);
1215 f_legacy_bssap_reset();
1216 }
Harald Welte67089ee2018-01-17 22:19:03 +01001217 }
Harald Welted5833a82018-05-27 16:52:56 +02001218
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001219 if (mp_enable_lcs_tests) {
1220 if (handler_mode) {
1221 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1222 } else {
1223 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1224 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1225 }
1226 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001227 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001228
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001229 /* start the test with exactly all enabled MSCs allowed to attach */
1230 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1231
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001232 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001233
Daniel Willmann191e0d92018-01-17 12:44:35 +01001234 f_init_mgcp("VirtMSC");
1235
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001236 for (var integer i := 0; i < nr_bts; i := i+1) {
1237 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001238 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001239
1240 /* Emit a marker to appear in the SUT's own logging output */
1241 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001242}
Harald Welte696ddb62017-12-08 14:01:43 +01001243
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001244function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1245runs on test_CT {
1246 /* wait until osmo-bts-omldummy has respawned */
1247 f_wait_oml(bts_idx, "degraded", 5.0);
1248
1249 /* start RSL connection */
1250 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1251 /* wait until BSC tells us "connected" */
1252 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001253}
1254
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001255function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1256 template SystemInformationConfig expect_si)
1257runs on test_CT {
1258 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1259
1260 f_init_bts(bts_idx, handler_mode);
1261
1262 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1263 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1264 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1265 */
1266 f_sleep(5.0);
1267 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1268
1269 deactivate(sysinfo);
1270
1271 if (match(g_system_information[bts_idx], expect_si)) {
1272 setverdict(pass);
1273 } else {
1274 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1275 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1276 setverdict(fail, "received SI does not match expectations");
1277 return;
1278 }
1279}
1280
Maxd4e56962018-10-31 19:08:25 +01001281/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001282function 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 +01001283runs on test_CT return RSL_Message {
1284 var ASP_RSL_Unitdata rx_rsl_ud;
1285 timer T := t_secs;
1286
1287 T.start;
1288 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001289 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001290 T.stop;
1291 }
1292 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001293 [] T.timeout {
1294 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001295 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001296 }
Harald Welteae026692017-12-09 01:03:01 +01001297 }
1298 return rx_rsl_ud.rsl;
1299}
1300
Harald Welte21b46bd2017-12-17 19:46:32 +01001301/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001302function 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 +01001303runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001304 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001305}
1306
1307
Harald Welte4003d112017-12-09 22:35:39 +01001308/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001309testcase TC_chan_act_noreply() runs on test_CT {
1310 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001311 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001312
Harald Welte89d42e82017-12-17 16:42:41 +01001313 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001314
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001315 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001316 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001317 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001318}
1319
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001320const CounterNameVals counternames_bts_chreq := {
1321 { "chreq:total", 0 },
1322 { "chreq:attempted_emerg", 0 },
1323 { "chreq:attempted_call", 0 },
1324 { "chreq:attempted_location_upd", 0 },
1325 { "chreq:attempted_pag", 0 },
1326 { "chreq:attempted_pdch", 0 },
1327 { "chreq:attempted_other", 0 },
1328 { "chreq:attempted_unknown", 0 },
1329 { "chreq:successful", 0 },
1330 { "chreq:successful_emerg", 0 },
1331 { "chreq:successful_call", 0 },
1332 { "chreq:successful_location_upd", 0 },
1333 { "chreq:successful_pag", 0 },
1334 { "chreq:successful_pdch", 0 },
1335 { "chreq:successful_other", 0 },
1336 { "chreq:successful_unknown", 0 },
1337 { "chreq:no_channel", 0 },
1338 { "chreq:max_delay_exceeded", 0 }
1339};
1340
1341/* verify the "chreq:*" counters */
1342private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1343{
1344 var GsmFrameNumber fn := 23;
1345
1346 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1347
1348 var RSL_Message rx_rsl;
1349 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1350 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1351 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1352
1353 f_ctrs_bts_add(0, "chreq:total");
1354 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1355 f_ctrs_bts_verify();
1356
1357 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1358 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1359
1360 f_ctrs_bts_add(0, "chreq:successful");
1361 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1362 f_ctrs_bts_verify();
1363
1364 /* test is done, release RSL Conn Fail Ind to clean up */
1365 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1366 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1367 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
1368 f_sleep(1.0);
1369}
1370
Harald Welte4003d112017-12-09 22:35:39 +01001371testcase TC_chan_act_counter() runs on test_CT {
1372 var BSSAP_N_UNITDATA_ind ud_ind;
1373 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001374 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001375
Harald Welte89d42e82017-12-17 16:42:41 +01001376 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001377
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001378 f_vty_allow_emerg_bts(true, 0);
1379
1380 f_ctrs_bts_init(1, counternames_bts_chreq);
1381
1382 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1383 f_chan_act_counter('a3'O, "emerg");
1384
1385 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1386 f_chan_act_counter('43'O, "call");
1387
1388 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1389 f_chan_act_counter('03'O, "location_upd");
1390
1391 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1392 f_chan_act_counter('23'O, "pag");
1393 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1394 f_chan_act_counter('33'O, "pag");
1395
1396 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1397 /* no PCU, so PDCH not allowed. Skip this test for now. */
1398 /* f_chan_act_counter('7b'O, "pdch"); */
1399
1400 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1401 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001402
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001403 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001404}
1405
Harald Welteae026692017-12-09 01:03:01 +01001406/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001407private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001408 var RSL_Message rx_rsl;
1409
Harald Welteae026692017-12-09 01:03:01 +01001410 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001411 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001412
1413 /* expect BSC to disable the channel again if there's no RLL EST IND */
1414 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1415
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001416 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001417}
1418
Philipp Maier9c60a622020-07-09 15:08:46 +02001419/* Normal variant */
1420testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001421 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001422 f_TC_chan_act_ack_noest();
1423}
1424
1425/* Emergency call variant */
1426testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1427 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001428 f_init(1);
1429 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001430 f_TC_chan_act_ack_noest(ra := 'A5'O);
1431}
1432
Philipp Maier606f07d2020-08-12 17:21:58 +02001433/* Emergency call variant, but emergency calls are not allowed */
1434testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1435 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1436
1437 var RSL_Message rx_rsl;
1438 var GsmRrMessage rr;
1439
1440 f_init(1);
1441 f_vty_allow_emerg_bts(false, 0);
1442
1443 IPA_RSL[0].clear;
1444 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1445
1446 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1447 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1448 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1449 setverdict(pass);
1450 } else {
1451 setverdict(fail, "immediate assignment not rejected");
1452 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001453
1454 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001455}
1456
Harald Welteae026692017-12-09 01:03:01 +01001457/* Test behavior if MSC never answers to CR */
1458testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001459 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1460 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001461 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001462 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001463
Harald Welte89d42e82017-12-17 16:42:41 +01001464 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001465
1466 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001467 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001468
1469 var octetstring l3 := '00010203040506'O
1470 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1471
1472 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1473
1474 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001475 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001476 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001477 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001478}
1479
1480/* Test behavior if MSC answers with CREF to CR */
1481testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1482 var BSSAP_N_CONNECT_ind rx_c_ind;
1483 var RSL_Message rx_rsl;
1484
Harald Welte89d42e82017-12-17 16:42:41 +01001485 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001486
1487 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001488 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001489
1490 var octetstring l3 := '00010203040506'O
1491 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1492
1493 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1494 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1495
1496 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001497 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001498 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001499}
1500
Harald Welte618ef642017-12-14 14:58:20 +01001501/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1502testcase TC_chan_act_nack() runs on test_CT {
1503 var RSL_Message rx_rsl;
1504 var integer chact_nack;
1505
Harald Welte89d42e82017-12-17 16:42:41 +01001506 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001507
1508 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1509
1510 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1511 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1512 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1513
1514 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1515
1516 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1517 f_sleep(0.5);
1518
1519 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1520
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001521 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001522}
1523
Harald Welte799c97b2017-12-14 17:50:30 +01001524/* Test for channel exhaustion due to RACH overload */
1525testcase TC_chan_exhaustion() runs on test_CT {
1526 var ASP_RSL_Unitdata rsl_ud;
1527 var integer i;
1528 var integer chreq_total, chreq_nochan;
1529
Harald Welte89d42e82017-12-17 16:42:41 +01001530 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001531
1532 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1533 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1534
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001535 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001536 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1537 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001538 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 +01001539 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001540 }
1541
1542 IPA_RSL[0].clear;
1543
Harald Weltedd8cbf32018-01-28 12:07:52 +01001544 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001545 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001546
1547 /* now expect additional channel activations to fail */
1548 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1549
1550 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001551 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001552 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1553 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001554 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001555 var GsmRrMessage rr;
1556 /* match on IMM ASS REJ */
1557 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1558 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1559 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001560 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001561 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1562 chreq_nochan+1);
1563 setverdict(pass);
1564 } else {
1565 repeat;
1566 }
1567 }
1568 [] IPA_RSL[0].receive { repeat; }
1569 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001570 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001571}
1572
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001573/* Test channel deactivation due to silence from MS */
1574testcase TC_chan_deact_silence() runs on test_CT {
1575 var RslChannelNr chan_nr;
1576
1577 f_init(1);
1578
1579 /* Request for a dedicated channel */
1580 chan_nr := f_chreq_act_ack('23'O);
1581
1582 /* Wait some time until the channel is released */
1583 f_sleep(2.0);
1584
1585 /* Expect CHANnel RELease */
1586 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001587 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001588 log("Received CHANnel RELease");
1589 setverdict(pass);
1590 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001591 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001592 /* See OS#3709, OsmoBSC should not send Immediate
1593 * Assignment Reject since a dedicated channel was
1594 * already allocated, and Immediate Assignment was
1595 * already sent. */
1596 setverdict(fail, "Unexpected Immediate Assignment!");
1597 }
1598 [] IPA_RSL[0].receive {
1599 setverdict(fail, "Unexpected RSL message!");
1600 }
1601 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001602 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001603}
1604
Harald Weltecfe2c962017-12-15 12:09:32 +01001605/***********************************************************************
1606 * Assignment Testing
1607 ***********************************************************************/
1608
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001609/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1610 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001611testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001612 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001613
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001614 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1615 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001616 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001617 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001618}
1619
Harald Welte16a4adf2017-12-14 18:54:01 +01001620/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001621testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001622 var BSSAP_N_CONNECT_ind rx_c_ind;
1623 var RSL_Message rx_rsl;
1624 var DchanTuple dt;
1625
Harald Welte89d42e82017-12-17 16:42:41 +01001626 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001627
1628 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001629 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001630 /* send assignment without AoIP IEs */
1631 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1632 } else {
1633 /* Send assignmetn without CIC in IPA case */
1634 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1635 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1636 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1637 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001638 alt {
1639 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1640 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1641 }
Harald Welte235ebf12017-12-15 14:18:16 +01001642 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001643 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1644 setverdict(pass);
1645 }
1646 [] BSSAP.receive { repeat; }
1647 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001648 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001649 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001650}
1651
Harald Welteed848512018-05-24 22:27:58 +02001652/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001653function 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 +02001654 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001655 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001656 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001657 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001658 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001659 if (osmux_enabled) {
1660 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1661 } else {
1662 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1663 }
Harald Welteed848512018-05-24 22:27:58 +02001664 } else {
1665 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001666 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001667 }
1668 return ass_cmd;
1669}
1670
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001671function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001672 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001673 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1674 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001675 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001676
1677 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1678 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03001679 var template (omit) BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1680 var template (omit) BSSMAP_IE_KC128 kc128 := omit;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001681 if (ispresent(enc)) {
1682 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001683 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1684 if (ispresent(v_enc.enc_alg_chosen)) {
1685 chosenEncryptionAlgorithm := valueof(
1686 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1687 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1688 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001689 if (ispresent(v_enc.enc_kc128)) {
1690 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1691 }
1692 }
1693
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001694 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001695 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001696 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001697 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1698 cell_id_source := cell_id_source,
1699 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001700 encryptionInformation := encryptionInformation,
1701 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001702 kC128 := kc128,
1703 /* on AoIP, allow "all" codecs (until we add more concise
1704 * tests) */
1705 codecList := ts_BSSMAP_IE_CodecList(
1706 {ts_CodecAMR_F, ts_CodecAMR_H,
1707 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001708 } else {
1709 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001710 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1711 cell_id_source := cell_id_source,
1712 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001713 encryptionInformation := encryptionInformation,
1714 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1715 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001716 }
1717 return ho_req;
1718}
1719
Harald Welteed848512018-05-24 22:27:58 +02001720/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001721function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001722 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001723 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001724 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001725 if (expect_osmux) {
1726 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1727 } else {
1728 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1729 }
Harald Welteed848512018-05-24 22:27:58 +02001730 } else {
1731 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001732 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001733 }
1734 return exp_compl;
1735}
1736
Harald Welte235ebf12017-12-15 14:18:16 +01001737/* Run everything required up to sending a caller-specified assignment command and expect response */
1738function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001739runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001740 var BSSAP_N_CONNECT_ind rx_c_ind;
1741 var RSL_Message rx_rsl;
1742 var DchanTuple dt;
1743
Harald Welte89d42e82017-12-17 16:42:41 +01001744 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001745
1746 dt := f_est_dchan('23'O, 23, '00000000'O);
1747 /* send assignment without AoIP IEs */
1748 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1749 alt {
1750 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1751 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1752 setverdict(pass);
1753 } else {
1754 setverdict(fail, fail_text);
1755 }
1756 }
1757 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1758 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1759 setverdict(pass);
1760 } else {
1761 setverdict(fail, fail_text);
1762 }
1763 }
1764 [] BSSAP.receive { repeat; }
1765 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001766 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001767}
1768testcase TC_assignment_csd() runs on test_CT {
1769 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001770 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001771 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1772 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001773 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1774 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001775 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001776}
1777
1778testcase TC_assignment_ctm() runs on test_CT {
1779 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001780 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001781 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1782 //exp_fail.pdu.bssmap.assignmentFailure.cause.causeValue := int2bit(enum2int(GSM0808_CAUSE_REQ_CODEC_TYPE_OR_CONFIG_UNAVAIL), 7);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001783 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1784 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001785 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001786}
1787
Harald Welte4003d112017-12-09 22:35:39 +01001788type record DchanTuple {
1789 integer sccp_conn_id,
1790 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001791}
1792
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001793type record of DchanTuple DchanTuples;
1794
Harald Welted6939652017-12-13 21:02:46 +01001795/* Send CHAN RQD and wait for allocation; acknowledge it */
1796private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1797runs on test_CT return RslChannelNr {
1798 var RSL_Message rx_rsl;
1799 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1800 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1801 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1802 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001803 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001804 return chan_nr;
1805}
1806
Harald Welte4003d112017-12-09 22:35:39 +01001807/* helper function to establish a dedicated channel via BTS and MSC */
1808function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1809runs on test_CT return DchanTuple {
1810 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001811 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001812
Harald Welte4003d112017-12-09 22:35:39 +01001813 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001814 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001815
1816 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1817
1818 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1819 dt.sccp_conn_id := rx_c_ind.connectionId;
1820 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1821
1822 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001823}
1824
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001825/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1826function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1827runs on test_CT return DchanTuple {
1828 var BSSAP_N_CONNECT_ind rx_c_ind;
1829 var DchanTuple dt;
1830
1831 /* Send CHAN RQD */
1832 var RSL_Message rx_rsl;
1833 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1834
1835 /* The dyn TS first deactivates PDCH */
1836 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1837 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1838 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1839
1840 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1841 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1842
1843 /* Now activates the signalling channel */
1844 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1845 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1846
1847 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1848
1849 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1850 dt.sccp_conn_id := rx_c_ind.connectionId;
1851 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1852
1853 return dt;
1854}
1855
Harald Welte641fcbe2018-06-14 10:58:35 +02001856/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1857private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1858 var RSL_Message rx_rsl;
1859 /* expect BSC to disable the channel */
1860 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1861 /* respond with CHAN REL ACK */
1862 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1863
1864 /* expect Clear Complete from BSC */
1865 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1866
1867 /* MSC disconnects as instructed. */
1868 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1869}
1870
Harald Welte4003d112017-12-09 22:35:39 +01001871/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1872testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001873 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001874 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001875
Harald Welte89d42e82017-12-17 16:42:41 +01001876 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001877
Harald Welte4003d112017-12-09 22:35:39 +01001878 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1879
1880 /* simulate RLL REL IND */
1881 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1882
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001883 /* expect Clear Request on MSC side */
1884 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1885
1886 /* Instruct BSC to clear channel */
1887 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1888 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1889
Harald Welte4003d112017-12-09 22:35:39 +01001890 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001891 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001892
1893 /* wait for SCCP emulation to do its job */
1894 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001895
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001896 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001897}
1898
1899/* Test behavior of channel release after CONN FAIL IND from BTS */
1900testcase TC_chan_rel_conn_fail() runs on test_CT {
1901 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001902 var DchanTuple dt;
1903
Harald Welte89d42e82017-12-17 16:42:41 +01001904 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001905
1906 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1907
1908 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001909 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 +01001910 /* TODO: different cause values? */
1911
Harald Welte4003d112017-12-09 22:35:39 +01001912 /* expect Clear Request from BSC */
1913 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1914
1915 /* Instruct BSC to clear channel */
1916 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1917 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1918
Harald Welte6ff76ea2018-01-28 13:08:01 +01001919 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001920 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001921
1922 /* wait for SCCP emulation to do its job */
1923 f_sleep(1.0);
1924
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001925 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001926}
1927
Harald Welte99f3ca02018-06-14 13:40:29 +02001928/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1929/* See also https://www.osmocom.org/issues/3182 */
1930testcase TC_early_conn_fail() runs on test_CT {
1931 var RSL_Message rx_rsl;
1932 var DchanTuple dt;
1933
1934 f_init(1);
1935
1936 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001937 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001938
1939 /* BTS->BSC: simulate CONN FAIL IND */
1940 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1941
1942 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1943 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1944
1945 /* BTS<-BSC: respond with CHAN REL ACK */
1946 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1947
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001948 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001949}
1950
1951/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1952/* See also https://www.osmocom.org/issues/3182 */
1953testcase TC_late_conn_fail() runs on test_CT {
1954 var RSL_Message rx_rsl;
1955 var DchanTuple dt;
1956
1957 f_init(1);
1958
1959 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1960
1961 /* BSC<-MSC: Instruct BSC to clear connection */
1962 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1963
1964 /* BTS->BSC: expect BSC to deactivate SACCH */
1965 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1966
1967 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1968 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1969
1970 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1971 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1972 /* BTS->BSC: respond with CHAN REL ACK */
1973 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1974
1975 /* BSC->MSC: expect Clear Complete from BSC */
1976 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1977
1978 /* BSC<-MSC: MSC disconnects as requested. */
1979 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1980
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001981 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001982}
1983
Oliver Smithaf03bef2021-08-24 15:34:51 +02001984private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1985 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1986 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1987
1988 f_statsd_reset();
1989
1990 /* Establish SDCCH */
1991 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1992 f_establish_fully(ass_cmd, exp_fail);
1993
1994 /* Expect stats to be 0 */
1995 var StatsDExpects expect := {
1996 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1997 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1998 };
1999 f_statsd_expect(expect);
2000
2001 /* Simulate CONN FAIL IND on SDCCH */
2002 RSL.send(ts_ASP_RSL_UD(
2003 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2004 IPAC_PROTO_RSL_TRX0));
2005
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002006 f_sleep(1.0);
2007
Oliver Smithaf03bef2021-08-24 15:34:51 +02002008 /* Expect stats to be 1 */
2009 expect := {
2010 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2011 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2012 };
2013 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002014 BSSAP.receive(tr_BSSMAP_ClearRequest);
2015 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002016}
2017testcase TC_stats_conn_fail() runs on test_CT {
2018 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2019 var MSC_ConnHdlr vc_conn;
2020
2021 f_init(1, true);
2022 f_sleep(1.0);
2023
2024 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2025 vc_conn.done;
2026
2027 f_shutdown_helper();
2028}
2029
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01002030function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002031 boolean expect_deact_sacch := true,
2032 boolean expect_rr_chan_rel := true,
2033 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002034 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002035 template CellSelIndValue expect_cells := omit,
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002036 template (present) RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002037 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002038
2039 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002040 var boolean got_deact_sacch := false;
2041 var boolean got_rr_chan_rel := false;
2042 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002043 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002044 var RSL_IE_Body l3_ie;
2045 var PDU_ML3_NW_MS l3;
2046 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002047 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2048 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002049 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002050 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002051 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002052 repeat;
2053 }
Vadim Yanitskiya25fe232022-03-16 19:56:19 +03002054 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01002055 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002056
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002057 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2058 setverdict(fail, "cannot find L3");
2059 mtc.stop;
2060 }
2061 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2062
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002063 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002064 var CellSelIndValue cells := dec_CellSelIndValue(
2065 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2066
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002067 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2068 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002069 setverdict(pass);
2070 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002071 log("EXPECTED CELLS: ", expect_cells);
2072 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002073 }
2074 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002075
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002076 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2077 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2078 if (match(got_cause, expect_rr_cause)) {
2079 setverdict(pass);
2080 } else {
2081 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2082 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002083 }
Harald Welte99787102019-02-04 10:41:36 +01002084 repeat;
2085 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002086 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002087 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002088 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002089 if (handle_rll_rel) {
2090 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
2091 }
Harald Welte91d54a52018-01-28 15:35:07 +01002092 repeat;
2093 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002094 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002095 /* respond with CHAN REL ACK */
2096 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
2097 }
2098 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002099 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002100 repeat;
2101 }
2102 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002103
2104 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2105 " got_rll_rel_req=", got_rll_rel_req);
2106
2107 if (expect_deact_sacch != got_deact_sacch) {
2108 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2109 }
2110 if (expect_rr_chan_rel != got_rr_chan_rel) {
2111 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2112 }
2113 if (expect_rll_rel_req != got_rll_rel_req) {
2114 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2115 }
Harald Welte91d54a52018-01-28 15:35:07 +01002116}
2117
Harald Welte4003d112017-12-09 22:35:39 +01002118/* Test behavior of channel release after hard Clear Command from MSC */
2119testcase TC_chan_rel_hard_clear() runs on test_CT {
2120 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002121 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002122
Harald Welte89d42e82017-12-17 16:42:41 +01002123 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002124
2125 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2126
2127 /* Instruct BSC to clear channel */
2128 var BssmapCause cause := 0;
2129 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2130
2131 /* expect Clear Complete from BSC on A */
2132 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2133 /* release the SCCP connection */
2134 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2135 }
2136
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002137 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002138 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002139}
2140
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002141function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2142 var BSSAP_N_DATA_ind rx_di;
2143 var DchanTuple dt;
2144
2145 f_init(1);
2146
2147 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2148 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2149 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2150 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2151
2152 /* Instruct BSC to clear channel */
2153 var BssmapCause cause := 0;
2154 if (tx_csfb_ind) {
2155 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2156 } else {
2157 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2158 }
2159
2160 /* expect Clear Complete from BSC on A */
2161 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2162 /* release the SCCP connection */
2163 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2164 }
2165
2166 /* 1 neighbor is added by default in osmo-bts.cfg and
2167 SystemInformationConfig_default, use that: */
2168 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2169
2170 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2171 f_shutdown_helper();
2172}
2173
2174/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2175 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2176 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2177 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2178 Indicator or not shouldn't matter at all. */
2179testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2180 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2181}
2182
2183/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2184 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2185 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2186 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2187testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2188 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2189}
2190
2191/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2192 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2193 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2194 CSFB Indicator should not be used anymore, and hence, there should be no
2195 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2196 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002197testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2198 var BSSAP_N_DATA_ind rx_di;
2199 var DchanTuple dt;
2200
2201 f_init(1);
2202
2203 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2204
2205 /* Instruct BSC to clear channel */
2206 var BssmapCause cause := 0;
2207 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2208
2209 /* expect Clear Complete from BSC on A */
2210 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2211 /* release the SCCP connection */
2212 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2213 }
2214
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002215 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002216 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002217}
2218
Harald Welted8c36cd2017-12-09 23:05:31 +01002219/* Test behavior of channel release after hard RLSD from MSC */
2220testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002221 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002222
Harald Welte89d42e82017-12-17 16:42:41 +01002223 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002224
2225 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2226
2227 /* release the SCCP connection */
2228 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2229
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002230 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002231 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002232}
2233
Harald Welte550daf92018-06-11 19:22:13 +02002234/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2235testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2236 var DchanTuple dt;
2237
2238 f_init(1);
2239
2240 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2241
2242 /* release the SCCP connection */
2243 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2244
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002245 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002246 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002247}
2248
Harald Welte85804d42017-12-10 14:11:58 +01002249/* Test behavior of channel release after BSSMAP RESET from MSC */
2250testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002251 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002252
Harald Welte89d42e82017-12-17 16:42:41 +01002253 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002254
2255 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2256
2257 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2258 IPA_RSL[0].clear;
2259
2260 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002261 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 +01002262 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002263 [] 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 +01002264 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2265 }
2266
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002267 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002268 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002269}
2270
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002271/* Verify T(iar) triggers and releases the channel */
2272testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2273 var DchanTuple dt;
2274
2275 /* Set T(iar) in BSC low enough that it will trigger before other side
2276 has time to keep alive with a T(ias). Keep recommended ratio of
2277 T(iar) >= T(ias)*2 */
2278 g_bsc_sccp_timer_ias := 2;
2279 g_bsc_sccp_timer_iar := 5;
2280
2281 f_init(1);
2282
2283 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2284 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002285 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002286}
2287
Vadim Yanitskiybc7c35a2022-03-16 19:50:06 +03002288private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause,
2289 template (present) RR_Cause expect_rr_cause)
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002290runs on test_CT
2291{
2292 var DchanTuple dt;
2293
2294 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2295 var BssmapCause cause := 0;
2296 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2297 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2298 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2299 }
2300
2301 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 +02002302}
2303
2304/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2305testcase TC_chan_rel_rr_cause() runs on test_CT {
2306 f_init(1);
2307
2308 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2309 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2310 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2311 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2312 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2313 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002314
2315 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002316}
2317
Harald Welte5cd20ed2017-12-13 21:03:20 +01002318/* Test behavior if RSL EST IND for non-active channel */
2319testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2320 timer T := 2.0;
2321
Harald Welte89d42e82017-12-17 16:42:41 +01002322 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002323
2324 var octetstring l3 := '00010203040506'O;
2325 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2326 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2327
2328 T.start;
2329 alt {
2330 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2331 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2332 }
2333 [] BSSAP.receive {}
2334 [] IPA_RSL[0].receive {}
2335 [] T.timeout {}
2336 }
2337
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002338 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002339}
2340
2341/* Test behavior if RSL EST IND for invalid SAPI */
2342testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2343 var RslChannelNr chan_nr;
2344
Harald Welte89d42e82017-12-17 16:42:41 +01002345 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002346
2347 chan_nr := f_chreq_act_ack()
2348
2349 var octetstring l3 := '00010203040506'O;
2350 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2351
2352 timer T := 2.0;
2353 T.start;
2354 alt {
2355 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2356 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2357 }
2358 [] BSSAP.receive { repeat; }
2359 [] IPA_RSL[0].receive { repeat; }
2360 [] T.timeout {}
2361 }
2362
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002363 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002364}
2365
2366/* Test behavior if RSL EST IND for invalid SAPI */
2367testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2368 timer T := 2.0;
2369
Harald Welte89d42e82017-12-17 16:42:41 +01002370 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002371
2372 var RslChannelNr chan_nr := f_chreq_act_ack();
2373
2374 var octetstring l3 := '00010203040506'O;
2375 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2376
2377 T.start;
2378 alt {
2379 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2380 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2381 }
2382 [] BSSAP.receive { repeat; }
2383 [] IPA_RSL[0].receive { repeat; }
2384 [] T.timeout {}
2385 }
2386
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002387 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002388}
2389
2390/* Test behavior if RSL EST IND for invalid SACCH */
2391testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2392 timer T := 2.0;
2393
Harald Welte89d42e82017-12-17 16:42:41 +01002394 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002395
2396 var RslChannelNr chan_nr := f_chreq_act_ack();
2397
2398 var octetstring l3 := '00010203040506'O;
2399 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2400
2401 T.start;
2402 alt {
2403 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2404 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2405 }
2406 [] BSSAP.receive { repeat; }
2407 [] IPA_RSL[0].receive { repeat; }
2408 [] T.timeout {}
2409 }
2410
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002411 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002412}
2413
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002414/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2415private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2416 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2417 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2418
2419 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2420 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2421
2422 f_establish_fully(ass_cmd, exp_compl);
2423
2424 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2425 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2426 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2427 BSSAP.receive(PDU_BSSAP:{
2428 discriminator := '1'B,
2429 spare := '0000000'B,
2430 dlci := 'C3'O,
2431 lengthIndicator := ?,
2432 pdu := { dtap := '0904'O }
2433 });
2434
2435 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2436 for (var integer i := 0; i < 32; i := i + 1) {
2437 var octetstring l3 := '09'O & f_rnd_octstring(14);
2438 var template (value) RslLinkId link_id;
2439 var template (value) OCT1 dlci;
2440
2441 if (i mod 2 == 0) {
2442 /* SAPI0 on FACCH or SDCCH */
2443 link_id := ts_RslLinkID_DCCH(0);
2444 dlci := '80'O;
2445 } else {
2446 /* SAPI3 on SACCH */
2447 link_id := ts_RslLinkID_SACCH(3);
2448 dlci := 'C3'O;
2449 }
2450
2451 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002452 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002453 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002454 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002455 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002456 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002457}
2458testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2459 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2460 var MSC_ConnHdlr vc_conn;
2461
2462 f_init(1, true);
2463 f_sleep(1.0);
2464
2465 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2466 vc_conn.done;
2467
2468 f_shutdown_helper();
2469}
2470
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002471private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002472 template (present) myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002473 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002474 float T_val := 2.0)
2475runs on test_CT {
2476 var BSSAP_N_DATA_ind rx_di;
2477 timer T;
2478
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03002479 var template (present) BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2480 var template (present) PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002481
2482 T.start(T_val);
2483 alt {
2484 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2485 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2486 if (not match(rx_cause, tr_cause)) {
2487 setverdict(fail, "Rx unexpected Cause IE: ",
2488 rx_cause, " vs expected ", tr_cause);
2489 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002490
2491 /* Who ever on the earth decided to define this field as two separate bits?!? */
2492 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2493 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2494 if (not match(rx_cc, cc)) {
2495 setverdict(fail, "Rx unexpected Control Channel type: ",
2496 rx_cc, " vs expected ", cc);
2497 }
2498
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002499 setverdict(pass);
2500 }
2501 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2502 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2503 }
2504 [] T.timeout {
2505 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2506 }
2507 }
2508}
2509
2510/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2511testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2512 var octetstring rnd_data := f_rnd_octstring(16);
2513 var RSL_Message rx_rsl;
2514 var DchanTuple dt;
2515
2516 f_init(1);
2517
2518 /* MS establishes a SAPI=0 link on DCCH */
2519 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2520
2521 /* MSC sends some data on (not yet established) SAPI=3 link */
2522 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2523 /* BSC attempts to establish a SAPI=3 link on DCCH */
2524 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2525
2526 /* MS sends unexpected RELease INDication on SAPI=3 */
2527 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2528 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2529 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2530
2531 /* Clean up the connection */
2532 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2533 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2534
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002535 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002536}
2537
2538/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2539testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2540 var octetstring rnd_data := f_rnd_octstring(16);
2541 var RSL_Message rx_rsl;
2542 var DchanTuple dt;
2543
2544 f_init(1);
2545
2546 /* MS establishes a SAPI=0 link on DCCH */
2547 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2548
2549 /* MSC sends some data on (not yet established) SAPI=3 link */
2550 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2551 /* BSC attempts to establish a SAPI=3 link on DCCH */
2552 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2553
2554 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2555 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2556 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2557 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2558
2559 /* Clean up the connection */
2560 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2561 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2562
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002563 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002564}
2565
2566/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2567testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2568 var octetstring rnd_data := f_rnd_octstring(16);
2569 var RSL_Message rx_rsl;
2570 var DchanTuple dt;
2571
2572 f_init(1);
2573
2574 /* MS establishes a SAPI=0 link on DCCH */
2575 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2576
2577 /* MSC sends some data on (not yet established) SAPI=3 link */
2578 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2579 /* BSC attempts to establish a SAPI=3 link on DCCH */
2580 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2581
2582 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2583 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2584
2585 /* Clean up the connection */
2586 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2587 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2588
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002589 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002590}
2591
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002592/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2593testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2594 var octetstring rnd_data := f_rnd_octstring(16);
2595 var RSL_Message rx_rsl;
2596 var DchanTuple dt;
2597
2598 f_init(1);
2599
2600 /* MS establishes a SAPI=0 link on DCCH */
2601 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2602
2603 /* MSC sends some data on (not yet established) SAPI=3 link */
2604 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2605 /* BSC attempts to establish a SAPI=3 link on DCCH */
2606 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2607
2608 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
2609 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
Pau Espin Pedrol121f27f2022-01-12 12:02:10 +01002610 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002611
2612 /* Clean up the connection */
2613 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2614 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2615
2616 f_shutdown_helper();
2617}
2618
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002619testcase TC_si_default() runs on test_CT {
2620 f_init(0);
2621 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002622 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002623}
Harald Welte4003d112017-12-09 22:35:39 +01002624
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002625/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2626 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2627private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2628{
2629 select (earfcn_index) {
2630 case (0) {
2631 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2632 return 111;
2633 }
2634 case (1) {
2635 return 1;
2636 }
2637 case (2) {
2638 return 0;
2639 }
2640 case (3) {
2641 return 65535;
2642 }
2643 case else {
2644 return 23 * (earfcn_index - 3);
2645 }
2646 }
2647}
2648
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002649function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2650 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002651
2652 f_init(0);
2653
2654 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2655 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002656 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2657 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002658 }
2659
2660 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2661
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002662 if (not istemplatekind(expect_cells, "omit")) {
2663 /* Also check that RR Channel Release contains these EARFCNs.
2664 * (copied code from TC_chan_rel_hard_clear_csfb) */
2665 var BSSAP_N_DATA_ind rx_di;
2666 var DchanTuple dt;
2667
2668 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002669 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2670 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2671 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002672
2673 /* Instruct BSC to clear channel */
2674 var BssmapCause cause := 0;
2675 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2676
2677 /* expect Clear Complete from BSC on A */
2678 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2679 /* release the SCCP connection */
2680 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2681 }
2682
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002683 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 +02002684 }
2685
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002686 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002687 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 +02002688 }
2689}
2690
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002691private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2692{
2693 var template SI2quaterRestOctetsList si2quater := {};
2694 var integer si2quater_count := (count + 2) / 3;
2695
2696 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002697 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002698 var integer index := i / 3;
2699 var integer earfcn_index := i mod 3;
2700 if (index >= lengthof(si2quater)) {
2701 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2702 }
2703 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);
2704 }
2705
2706 return si2quater;
2707}
2708
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002709private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2710{
2711 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2712
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002713 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002714 for (var integer i := 0; i < count; i := i + 1) {
2715 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002716 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002717 }
2718
2719 return tr_CellSelIndValue_EUTRAN(cells);
2720}
2721
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002722private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2723{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002724 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002725 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002726 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2727 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002728}
2729
2730testcase TC_si2quater_2_earfcns() runs on test_CT {
2731 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002732 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002733}
2734
2735testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002736 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002737 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002738}
2739
2740testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002741 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002742 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002743}
2744
2745testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002746 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002747 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002748}
2749
2750testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002751 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002752 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002753}
2754
2755testcase TC_si2quater_12_earfcns() runs on test_CT {
2756 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002757 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002758}
2759
2760testcase TC_si2quater_23_earfcns() runs on test_CT {
2761 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002762 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002763}
2764
2765testcase TC_si2quater_32_earfcns() runs on test_CT {
2766 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002767 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002768}
2769
2770testcase TC_si2quater_33_earfcns() runs on test_CT {
2771 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002772 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002773}
2774
2775testcase TC_si2quater_42_earfcns() runs on test_CT {
2776 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002777 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002778}
2779
2780testcase TC_si2quater_48_earfcns() runs on test_CT {
2781 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002782 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002783}
2784
2785/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2786 * 48 EARFCNs. */
2787testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002788 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002789 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2790 f_init(0);
2791
2792 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002793 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2794 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002795 }
2796
2797 /* The 49th EARFCN no longer fits, expect VTY error */
2798 f_vty_enter_cfg_bts(BSCVTY, 0);
2799 var charstring vty_error;
2800 vty_error := f_vty_transceive_ret(BSCVTY,
2801 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2802 f_vty_transceive(BSCVTY, "end");
2803
2804 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2805 log("Got expected VTY error: ", vty_error);
2806 setverdict(pass);
2807 } else {
2808 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2809 }
2810
2811 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2812
2813 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002814 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 +02002815 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002816 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002817}
2818
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002819private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2820{
2821 var uint8_t count := 0;
2822 for (var integer i := 5; i < 16; i := i + 1) {
2823 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2824 count := count + 1;
2825 }
2826 }
2827 return count;
2828}
2829
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002830private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2831{
2832 var ASP_RSL_Unitdata rx_rsl_ud;
2833 var SystemInformationType1 last_si1;
2834
2835 timer T := 30.0;
2836 T.start;
2837 alt {
2838 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2839 tr_RSL_BCCH_INFO,
2840 tr_RSL_NO_SACCH_FILL,
2841 tr_RSL_SACCH_FILL))
2842 ) -> value rx_rsl_ud {
2843 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2844 if (g_system_information[rsl_idx].si1 == omit) {
2845 repeat;
2846 }
2847 last_si1 := g_system_information[rsl_idx].si1;
2848 g_system_information[rsl_idx].si1 := omit;
2849 T.stop;
2850 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002851 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002852 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2853 }
2854 return last_si1;
2855}
2856
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002857/* verify ACC rotate feature */
2858testcase TC_si_acc_rotate() runs on test_CT {
2859 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002860 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002861 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002862 var uint8_t count;
2863 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2864
2865 f_init(0, guard_timeout := 60.0);
2866
2867 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2868 "access-control-class-rotate 3",
2869 "access-control-class-rotate-quantum 1"});
2870
2871 /* Init and get first sysinfo */
2872 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2873
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002874 for (var integer i:= 0; i < 20; i := i + 1) {
2875 last_si1 := f_recv_next_si1(0);
2876 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002877 count := f_acc09_count_allowed(acc);
2878 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2879
2880 if (count != 3) {
2881 log("RSL: EXPECTED SI ACC len=3");
2882 setverdict(fail, "received SI does not match expectations");
2883 break;
2884 }
2885
2886 for (var integer j := 0; j < 10; j := j + 1) {
2887 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2888 times_allowed[j] := times_allowed[j] + 1;
2889 }
2890 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002891 }
2892
2893 for (var integer j := 0; j < 10; j := j + 1) {
2894 log("ACC", j, " allowed ", times_allowed[j], " times" );
2895 if (j != 5 and times_allowed[j] < 3) {
2896 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2897 } else if (j == 5 and times_allowed[j] > 0) {
2898 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2899 }
2900 }
2901
2902 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2903 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002904 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002905}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002906
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002907/* verify ACC startup ramp+rotate feature */
2908testcase TC_si_acc_ramp_rotate() runs on test_CT {
2909 var template SystemInformationConfig sic := SystemInformationConfig_default;
2910 var SystemInformationType1 last_si1;
2911 var AccessControlClass acc;
2912 var ASP_RSL_Unitdata rx_rsl_ud;
2913 var uint8_t count;
2914 var uint8_t prev_count;
2915 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2916
2917 f_init(0, guard_timeout := 80.0);
2918
2919 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2920 "access-control-class-rotate 0",
2921 "access-control-class-rotate-quantum 1",
2922 "access-control-class-ramping",
2923 "access-control-class-ramping-step-interval 5",
2924 "access-control-class-ramping-step-size 5"});
2925
2926 /* Init and get first sysinfo */
2927 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2928 last_si1 := g_system_information[0].si1;
2929 acc := last_si1.rach_control.acc;
2930 count := f_acc09_count_allowed(acc);
2931 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2932 while (count > 0) {
2933 last_si1 := f_recv_next_si1(0);
2934 acc := last_si1.rach_control.acc;
2935 count := f_acc09_count_allowed(acc);
2936 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2937 }
2938
2939 /* Increase adm subset size, we should see ramping start up */
2940 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2941 prev_count := 0;
2942 while (true) {
2943 last_si1 := f_recv_next_si1(0);
2944 acc := last_si1.rach_control.acc;
2945 count := f_acc09_count_allowed(acc);
2946 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2947
2948 if (prev_count > count) {
2949 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2950 break;
2951 }
2952
2953 if (count == 9) {
2954 break; /* Maximum reached (10 - 1 perm barred), done here */
2955 }
2956
2957 prev_count := count;
2958 }
2959
2960 setverdict(pass);
2961
2962 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2963 "rach access-control-class 4 allowed",
2964 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002965 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002966}
2967
Harald Welte4003d112017-12-09 22:35:39 +01002968testcase TC_ctrl_msc_connection_status() runs on test_CT {
2969 var charstring ctrl_resp;
2970
Harald Welte89d42e82017-12-17 16:42:41 +01002971 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002972
2973 /* See https://osmocom.org/issues/2729 */
2974 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002975 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002976}
2977
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002978testcase TC_ctrl_msc0_connection_status() runs on test_CT {
2979 var charstring ctrl_resp;
2980
2981 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002982
2983 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002984 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01002985}
2986
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02002987/* Verify correct stats on the number of configured and connected MSCs */
2988private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
2989 g_pars := f_gen_test_hdlr_pars();
2990 var StatsDExpects expect := {
2991 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
2992 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
2993 };
2994 f_statsd_expect(expect);
2995}
2996
2997private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
2998{
2999 var MSC_ConnHdlr vc_conn;
3000
3001 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3002 f_sleep(1.0);
3003 vc_conn := f_start_handler(tc_fn);
3004 vc_conn.done;
3005
3006 /* Also verify stat exposed on CTRL interface */
3007 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3008 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3009
3010 f_shutdown_helper();
3011}
3012
3013/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3014private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3015 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3016}
3017testcase TC_stat_num_msc_connected_1() runs on test_CT {
3018 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3019}
3020
3021/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3022private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3023 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3024}
3025testcase TC_stat_num_msc_connected_2() runs on test_CT {
3026 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3027}
3028
3029/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3030private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3031 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3032}
3033testcase TC_stat_num_msc_connected_3() runs on test_CT {
3034 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3035}
3036
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003037/* Verify correct stats on the number of configured and connected MSCs */
3038private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
3039 g_pars := f_gen_test_hdlr_pars();
3040 var StatsDExpects expect := {
3041 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3042 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3043 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
3044 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3045 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
3046 };
3047 f_statsd_expect(expect);
3048}
3049
3050private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
3051 var MSC_ConnHdlr vc_conn;
3052
3053 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3054 f_sleep(1.0);
3055 vc_conn := f_start_handler(tc_fn);
3056 vc_conn.done;
3057
3058 /* Also verify stat exposed on CTRL interface */
3059 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3060 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
3061 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
3062 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
3063
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003064 /* Verify rf_states exposed on CTRL interface */
3065 var charstring expect_net_rf_states := "";
3066 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
3067 var charstring expect_bts_rf_states := int2str(i) & ",0,";
3068 if (i < NUM_BTS) {
3069 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3070 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3071 } else {
3072 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3073 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3074 }
3075 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3076 expect_bts_rf_states := expect_bts_rf_states & "on,";
3077 if (i < nr_bts) {
3078 /* For BTS where RSL is connected, the RSL state will be "up" */
3079 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3080 } else {
3081 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3082 }
3083
3084 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3085 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3086 }
3087 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3088
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003089 f_shutdown_helper();
3090}
3091
3092/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3093private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3094 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3095}
3096testcase TC_stat_num_bts_connected_1() runs on test_CT {
3097 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3098}
3099
3100/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3101private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3102 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3103}
3104testcase TC_stat_num_bts_connected_2() runs on test_CT {
3105 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3106}
3107
3108/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3109private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3110 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3111}
3112testcase TC_stat_num_bts_connected_3() runs on test_CT {
3113 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3114}
3115
Harald Welte4003d112017-12-09 22:35:39 +01003116testcase TC_ctrl() runs on test_CT {
3117 var charstring ctrl_resp;
3118
Harald Welte89d42e82017-12-17 16:42:41 +01003119 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003120
3121 /* all below values must match the osmo-bsc.cfg config file used */
3122
Harald Welte6a129692018-03-17 17:30:14 +01003123 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3124 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003125 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003126
3127 var integer bts_nr := 0;
3128 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3129 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3130 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3131 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3132 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3133 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3134 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3135
3136 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3137 f_sleep(2.0);
3138 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3139 setverdict(fail, "oml-uptime not incrementing as expected");
3140 }
3141 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3142
3143 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3144
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003145 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003146}
3147
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003148/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3149 "location-state" over the SCCPlite IPA conn */
3150testcase TC_ctrl_location() runs on test_CT {
3151 var MSC_ConnHdlr vc_conn;
3152 var integer bts_nr := 0;
3153
3154 f_init(1, true);
3155 f_sleep(1.0);
3156
3157 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3158 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3159 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3160
3161 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3162 f_sleep(2.0);
3163
3164 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3165 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3166 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3167
3168 /* should match the one from config */
3169 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3170
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003171 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003172}
3173
Harald Welte6f521d82017-12-11 19:52:02 +01003174
3175/***********************************************************************
3176 * Paging Testing
3177 ***********************************************************************/
3178
3179type record Cell_Identity {
3180 GsmMcc mcc,
3181 GsmMnc mnc,
3182 GsmLac lac,
3183 GsmCellId ci
3184};
Harald Welte24135bd2018-03-17 19:27:53 +01003185private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003186private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003187
Harald Welte5d1a2202017-12-13 19:51:29 +01003188type set of integer BtsIdList;
3189
3190private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3191 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3192 if (bts_id == bts_ids[j]) {
3193 return true;
3194 }
3195 }
3196 return false;
3197}
Harald Welte6f521d82017-12-11 19:52:02 +01003198
3199/* core paging test helper function; used by most paging test cases */
3200private function f_pageing_helper(hexstring imsi,
3201 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003202 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003203 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003204 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003205{
3206 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003207 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003208 var RSL_Message rx_rsl;
3209 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003210 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003211
3212 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003213
3214 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003215 for (i := 0; i < NUM_BTS; i := i + 1) {
3216 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003217 }
Harald Welte6f521d82017-12-11 19:52:02 +01003218
3219 if (isvalue(rsl_chneed)) {
3220 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3221 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3222 } else {
3223 bssmap_chneed := omit;
3224 }
3225
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003226 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3227 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003228
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003229 if (not istemplatekind(tmsi, "omit")) {
3230 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003231 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003232 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003233 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003234
Harald Welte5d1a2202017-12-13 19:51:29 +01003235 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003236 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003237 /* check channel type, paging group */
3238 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3239 setverdict(fail, "Paging for wrong paging group");
3240 }
3241 if (ispresent(rsl_chneed) and
3242 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3243 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3244 }
Harald Welte6f521d82017-12-11 19:52:02 +01003245 }
Harald Welte2fccd982018-01-31 15:48:19 +01003246 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003247 /* do a quick check on all not-included BTSs if they received paging */
3248 for (i := 0; i < NUM_BTS; i := i + 1) {
3249 timer T := 0.1;
3250 if (f_bts_in_list(i, bts_ids)) {
3251 continue;
3252 }
3253 T.start;
3254 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003255 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003256 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3257 }
3258 [] IPA_RSL[i].receive { repeat; }
3259 [] T.timeout { }
3260 }
Harald Welte6f521d82017-12-11 19:52:02 +01003261 }
3262
3263 setverdict(pass);
3264}
3265
Harald Welte5d1a2202017-12-13 19:51:29 +01003266const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003267const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003268const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3269const BtsIdList c_BtsId_LAC2 := { 2 };
3270
Harald Welte6f521d82017-12-11 19:52:02 +01003271/* PAGING by IMSI + TMSI */
3272testcase TC_paging_imsi_nochan() runs on test_CT {
3273 var BSSMAP_FIELD_CellIdentificationList cid_list;
3274 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003275 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003276 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003277}
3278
3279/* PAGING by IMSI + TMSI */
3280testcase TC_paging_tmsi_nochan() runs on test_CT {
3281 var BSSMAP_FIELD_CellIdentificationList cid_list;
3282 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003283 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003284 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003285}
3286
3287/* Paging with different "channel needed' values */
3288testcase TC_paging_tmsi_any() runs on test_CT {
3289 var BSSMAP_FIELD_CellIdentificationList cid_list;
3290 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003291 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003292 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003293}
3294testcase TC_paging_tmsi_sdcch() runs on test_CT {
3295 var BSSMAP_FIELD_CellIdentificationList cid_list;
3296 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003297 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003298 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003299}
3300testcase TC_paging_tmsi_tch_f() runs on test_CT {
3301 var BSSMAP_FIELD_CellIdentificationList cid_list;
3302 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003303 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003304 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003305}
3306testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3307 var BSSMAP_FIELD_CellIdentificationList cid_list;
3308 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003309 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003310 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003311}
3312
3313/* Paging by CGI */
3314testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3315 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3316 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003317 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003318 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003319}
3320
3321/* Paging by LAC+CI */
3322testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3323 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3324 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003325 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003326 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003327}
3328
3329/* Paging by CI */
3330testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3331 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3332 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003333 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003334 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003335}
3336
3337/* Paging by LAI */
3338testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3339 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3340 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003341 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003342 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003343}
3344
3345/* Paging by LAC */
3346testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3347 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3348 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003349 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003350 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003351}
3352
3353/* Paging by "all in BSS" */
3354testcase TC_paging_imsi_nochan_all() runs on test_CT {
3355 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3356 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003357 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003358 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003359}
3360
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003361/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003362testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3363 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3364 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 +01003365 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003366 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003367}
Harald Welte6f521d82017-12-11 19:52:02 +01003368
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003369/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003370testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3371 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3372 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003373 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003374 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003375}
3376
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003377/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003378testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3379 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3380 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003381 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003382 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003383}
3384
Harald Welte6f521d82017-12-11 19:52:02 +01003385/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003386testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3387 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3388 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3389 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003390 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003391}
3392
3393/* Paging on empty list: Verify none of them page */
3394testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3395 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3396 cid_list := { cIl_LAC := { } };
3397 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003398 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003399}
3400
Stefan Sperling049a86e2018-03-20 15:51:00 +01003401/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3402testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3403 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3404 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3405 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3406 f_shutdown_helper();
3407}
3408
Harald Welte6f521d82017-12-11 19:52:02 +01003409/* Verify paging retransmission interval + count */
3410/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003411/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003412
Harald Weltee65d40e2017-12-13 00:09:06 +01003413/* Verify PCH load */
3414testcase TC_paging_imsi_load() runs on test_CT {
3415 var BSSMAP_FIELD_CellIdentificationList cid_list;
3416 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003417 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003418 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003419 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003420
3421 /* tell BSC there is no paging space anymore */
3422 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003423 f_sleep(0.2);
3424 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003425
3426 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3427 * there would be 8 retransmissions during 4 seconds */
3428 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003429 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003430 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003431 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003432 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003433 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003434 }
Harald Welte2caa1062018-03-17 18:19:05 +01003435 [] T_retrans.timeout {
3436 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3437 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3438 T_retrans.start;
3439 repeat;
3440 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003441 [] T.timeout {
3442 setverdict(pass);
3443 }
3444 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003445
3446 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003447}
3448
Harald Welte235ebf12017-12-15 14:18:16 +01003449/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003450testcase TC_paging_counter() runs on test_CT {
3451 var BSSMAP_FIELD_CellIdentificationList cid_list;
3452 timer T := 4.0;
3453 var integer i;
3454 var integer paging_attempted_bsc;
3455 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003456 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003457 var integer paging_expired_bts[NUM_BTS];
3458 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3459
3460 f_init();
3461
3462 /* read counters before paging */
3463 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003464 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3465 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3466 }
Harald Welte1ff69992017-12-14 12:31:17 +01003467 for (i := 0; i < NUM_BTS; i := i+1) {
3468 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3469 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3470 }
3471
3472 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3473
3474 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3475 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3476 for (i := 0; i < NUM_BTS; i := i+1) {
3477 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3478 paging_attempted_bts[i]+1);
3479 }
3480
3481 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3482 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003483 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3484 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3485 }
Harald Welte1ff69992017-12-14 12:31:17 +01003486 for (i := 0; i < NUM_BTS; i := i+1) {
3487 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3488 paging_expired_bts[i]+1);
3489 }
Harald Welte1ff69992017-12-14 12:31:17 +01003490
Philipp Maier282ca4b2018-02-27 17:17:00 +01003491 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003492}
3493
3494
Harald Welte10985002017-12-12 09:29:15 +01003495/* Verify paging stops after A-RESET */
3496testcase TC_paging_imsi_a_reset() runs on test_CT {
3497 var BSSMAP_FIELD_CellIdentificationList cid_list;
3498 timer T := 3.0;
3499 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003500 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003501
3502 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003503 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 +01003504 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003505 [] 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 +01003506 [] BSSAP.receive { repeat; }
3507 }
3508
Daniel Willmanncbef3982018-07-30 09:22:40 +02003509 /* Wait to avoid a possible race condition if a paging message is
3510 * received right before the reset ACK. */
3511 f_sleep(0.2);
3512
Harald Welte10985002017-12-12 09:29:15 +01003513 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003514 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3515 IPA_RSL[i].clear;
3516 }
Harald Welte10985002017-12-12 09:29:15 +01003517
3518 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3519 T.start;
3520 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003521 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003522 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003523 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003524 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003525 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003526 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003527 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003528 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003529 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003530 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003531 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003532 }
Harald Welte10985002017-12-12 09:29:15 +01003533 [] T.timeout {
3534 setverdict(pass);
3535 }
3536 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003537
3538 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003539}
Harald Welteae026692017-12-09 01:03:01 +01003540
Philipp Maierf45824a2019-08-14 14:44:10 +02003541/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3542 * paging response we can not know which MSC is in charge, so we will blindly
3543 * pick the first configured MSC. This behavior is required in order to make
3544 * MT-CSFB calls working because in those cases the BSC can not know that the
3545 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3546 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003547 */
3548testcase TC_paging_resp_unsol() runs on test_CT {
3549
3550 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003551 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003552
3553 var BSSAP_N_CONNECT_ind rx_c_ind;
3554 var DchanTuple dt;
3555 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003556 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003557
3558 /* Send CHAN RQD and wait for allocation; acknowledge it */
3559 dt.rsl_chan_nr := f_chreq_act_ack();
3560
3561 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3562 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3563
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003564
Philipp Maierf45824a2019-08-14 14:44:10 +02003565 /* Expevct a CR with a matching Paging response on the A-Interface */
3566 T.start;
3567 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003568 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003569 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003570 dt.sccp_conn_id := rx_c_ind.connectionId;
3571 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003572 }
3573 [] BSSAP.receive {
3574 setverdict(fail, "Received unexpected message on A-Interface!");
3575 }
3576 [] T.timeout {
3577 setverdict(fail, "Received nothing on A-Interface!");
3578 }
3579 }
3580
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003581 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003582 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003583}
3584
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003585/* Verify BSC can schedule N paging requests under one minute if BTS buffer is good enough */
3586function f_TC_paging_Nreq(integer num_subscribers, boolean send_pag_load_ind) runs on test_CT {
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003587 var ASP_RSL_Unitdata rx_rsl_ud;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003588 var Hexstrings imsis := {};
3589 var Booleans rx_paging_done := {};
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003590 var integer rx_paging_num := 0;
3591 var integer i;
3592 timer T_rx := 60.0;
3593 timer T_load_ind := 1.0;
3594
3595 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003596 imsis := imsis & {f_gen_imsi(i)};
3597 rx_paging_done := rx_paging_done & { false };
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003598 }
3599
3600 f_init(1, guard_timeout := 100.0);
3601
3602 /* Clear the queue, it might still contain stuff like BCCH FILLING */
3603 IPA_RSL[0].clear;
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003604 if (send_pag_load_ind) {
3605 /* Tell there's plenty of space at the BTS (UINT16_MAX): */
3606 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(65535));
3607 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003608
3609 for (i := 0; i < num_subscribers; i := i + 1) {
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003610 /* Page on LAC-CI of BTS0: */
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003611 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003612 ts_BSSMAP_Paging(imsis[i], valueof(ts_BSSMAP_CIL_LAC_CI({ts_BSSMAP_CI_LAC_CI(1, 0)})),
3613 omit, omit)));
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003614 }
3615
3616 T_rx.start;
3617 T_load_ind.start;
3618 alt {
3619 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?), IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
3620 var hexstring imsi := rx_rsl_ud.rsl.ies[2].body.ms_identity.mobileIdentityV.oddEvenInd_identity.imsi.digits;
3621 var hexstring imsi_suffix := substr(imsi, lengthof(imsi)-6, 6);
3622 var charstring imsi_str := hex2str(imsi_suffix);
3623 var integer imsi_idx := str2int(imsi_str);
3624 if (rx_paging_done[imsi_idx] == false) {
3625 rx_paging_done[imsi_idx] := true;
3626 rx_paging_num := rx_paging_num + 1;
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003627 } else {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003628 setverdict(fail, "Retrans of ", imsi_str, " happened before Rx initial trans for all reqs. rx_paging_num=", rx_paging_num);
Pau Espin Pedrolef7ef632022-04-25 13:34:57 +02003629 mtc.stop;
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003630 }
3631 if (rx_paging_num < num_subscribers) {
3632 repeat;
3633 }
3634 }
3635 [] IPA_RSL[0].receive { repeat; }
3636 [] T_load_ind.timeout {
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003637 log("[CCH Load Ind timer] received paging requests so far: ", rx_paging_num);
3638 if (send_pag_load_ind) {
3639 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(40));
3640 }
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003641 T_load_ind.start;
3642 repeat;
3643 }
3644 [] T_rx.timeout {
3645 setverdict(fail, "Timeout expecting paging requests, so far ", rx_paging_num);
3646 mtc.stop;
3647 }
3648 }
3649
Pau Espin Pedrold3339a72022-05-03 11:59:15 +02003650 /* Drop OML connection to have all paging requests flushed: */
3651 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
3652
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003653 f_shutdown_helper();
3654}
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +02003655/* Verify BSC can schedule 500 paging requests under one minute if BTS buffer is good enough */
3656testcase TC_paging_500req() runs on test_CT {
3657 f_TC_paging_Nreq(500, true);
3658}
3659/* Same as TC_paging_500req, but without sending CCCH Load Indication, which
3660 * means BTS is always under CCH Load Threshold, aka capable of sending tons of requests.
3661 * Since No CCCH Load Ind, BSC uses a conservative estimation of BTS load, which
3662 * for current config yields ~8req/sec, so 480req/min maximum. */
3663testcase TC_paging_450req_no_paging_load_ind() runs on test_CT {
3664 f_TC_paging_Nreq(450, false);
3665}
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +02003666
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003667/* Test RSL link drop causes counter increment */
3668testcase TC_rsl_drop_counter() runs on test_CT {
3669 var integer rsl_fail;
3670
Harald Welte89d42e82017-12-17 16:42:41 +01003671 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003672
3673 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3674
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01003675 f_ipa_rsl_stop(bts[0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003676
3677 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3678
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003679 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003680}
3681
3682/* TODO: Test OML link drop causes counter increment */
3683
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003684/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3685function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3686 timer T := 10.0;
3687
3688 bts[0].rsl.id := "IPA-0-RSL";
Harald Welte71389132021-12-09 21:58:18 +01003689 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA") alive;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003690 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3691 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003692 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003693
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003694 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003695
3696 f_init_mgcp("VirtMSC");
3697
3698 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3699 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3700 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3701 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3702
3703 /* wait for IPA OML link to connect and then disconnect */
3704 T.start;
3705 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003706 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003707 T.stop;
3708 return true;
3709 }
3710 [] IPA_RSL[0].receive { repeat }
3711 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003712 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003713 }
3714 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003715 return false;
3716}
3717
3718/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3719testcase TC_rsl_unknown_unit_id() runs on test_CT {
3720 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3721 setverdict(pass);
3722 } else {
3723 setverdict(fail, "Timeout RSL waiting for connection to close");
3724 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003725 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003726}
3727
3728
3729/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3730testcase TC_oml_unknown_unit_id() runs on test_CT {
3731 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3732 setverdict(pass);
3733 } else {
3734 setverdict(fail, "Timeout OML waiting for connection to close");
3735 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003736 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003737}
3738
3739
Harald Weltec1a2fff2017-12-17 11:06:19 +01003740/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003741 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003742 ***********************************************************************/
3743
Harald Welte6811d102019-04-14 22:23:14 +02003744import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003745import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003746import from RSL_Emulation all;
3747import from MSC_ConnectionHandler all;
3748
3749type function void_fn(charstring id) runs on MSC_ConnHdlr;
3750
Harald Welte336820c2018-05-31 20:34:52 +02003751/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003752private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3753 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003754 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003755 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003756 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003757 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003758 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3759 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3760 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003761 if (isvalue(bts[2])) {
3762 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3763 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3764 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003765 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003766 if (mp_enable_lcs_tests) {
3767 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3768 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3769 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003770 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003771 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003772 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003773}
3774
Neels Hofmeyrda436782021-07-20 22:09:06 +02003775function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003776runs on test_CT return MSC_ConnHdlr {
3777 var charstring id := testcasename();
3778 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003779 var integer bssap_idx := 0;
3780 if (isvalue(pars)) {
3781 bssap_idx := valueof(pars).mscpool.bssap_idx;
3782 }
Harald Welte336820c2018-05-31 20:34:52 +02003783 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003784 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003785 return vc_conn;
3786}
3787
3788function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3789runs on test_CT return MSC_ConnHdlr {
3790 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003791 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003792 return vc_conn;
3793}
3794
Neels Hofmeyrda436782021-07-20 22:09:06 +02003795function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3796runs on test_CT return MSC_ConnHdlr {
3797 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3798}
3799
Harald Weltea0630032018-03-20 21:09:55 +01003800/* first function inside ConnHdlr component; sets g_pars + starts function */
3801private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3802runs on MSC_ConnHdlr {
3803 if (isvalue(pars)) {
3804 g_pars := valueof(pars);
3805 }
3806 fn.apply(id);
3807}
3808
Oliver Smith26a3db72021-07-09 13:51:29 +02003809private function f_vty_encryption_a5(charstring options) runs on test_CT {
3810 f_vty_transceive(BSCVTY, "configure terminal");
3811 f_vty_transceive(BSCVTY, "network");
3812 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3813 f_vty_transceive(BSCVTY, "exit");
3814 f_vty_transceive(BSCVTY, "exit");
3815}
3816
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003817const charstring VTY_A5_DEFAULT := "0 1 3";
3818
Oliver Smith26a3db72021-07-09 13:51:29 +02003819private function f_vty_encryption_a5_reset() runs on test_CT {
3820 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003821 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003822}
3823
Harald Welte3c86ea02018-05-10 22:28:05 +02003824/* Establish signalling channel (non-assignment case) followed by cipher mode */
3825private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003826 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3827 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003828 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003829 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3830 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3831 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3832 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003833
Philipp Maier23000732018-05-18 11:25:37 +02003834 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003835 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003836}
3837testcase TC_ciph_mode_a5_0() runs on test_CT {
3838 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003839 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003840 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3841
3842 f_init(1, true);
3843 f_sleep(1.0);
3844 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3845 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003846 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003847}
3848testcase TC_ciph_mode_a5_1() runs on test_CT {
3849 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003850 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003851 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3852
3853 f_init(1, true);
3854 f_sleep(1.0);
3855 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3856 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003857 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003858}
Oliver Smith50b98122021-07-09 15:00:28 +02003859/* OS#4975: verify that A5/2 is preferred over A5/0 */
3860testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3861 var MSC_ConnHdlr vc_conn;
3862 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3863
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003864 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003865
3866 f_init(1, true);
3867 f_vty_encryption_a5("0 1 2 3");
3868 f_sleep(1.0);
3869 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3870 vc_conn.done;
3871 f_vty_encryption_a5_reset();
3872 f_shutdown_helper();
3873}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003874/* OS#4975: verify that A5/1 is preferred over A5/2 */
3875testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3876 var MSC_ConnHdlr vc_conn;
3877 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3878
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003879 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003880
3881 f_init(1, true);
3882 f_vty_encryption_a5("1 2");
3883 f_sleep(1.0);
3884 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3885 vc_conn.done;
3886 f_vty_encryption_a5_reset();
3887 f_shutdown_helper();
3888}
Harald Welte3c86ea02018-05-10 22:28:05 +02003889testcase TC_ciph_mode_a5_3() runs on test_CT {
3890 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003891 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003892 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3893
3894 f_init(1, true);
3895 f_sleep(1.0);
3896 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3897 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003898 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003899}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003900/* Establish a Signalling channel with A5/4 encryption. */
3901testcase TC_ciph_mode_a5_4() runs on test_CT {
3902 var MSC_ConnHdlr vc_conn;
3903 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3904 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003905
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003906 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003907 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003908 f_sleep(1.0);
3909 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3910 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003911 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003912 f_shutdown_helper();
3913}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003914/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3915private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3916 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3917 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3918 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3919 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3920
3921 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003922 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003923}
3924testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3925 var MSC_ConnHdlr vc_conn;
3926 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3927
3928 f_init(1, true);
3929 f_sleep(1.0);
3930 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3931 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003932 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003933}
3934
Harald Welte3c86ea02018-05-10 22:28:05 +02003935
3936/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003937private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003938 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3939 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003940
Harald Welte552620d2017-12-16 23:21:36 +01003941 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3942 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003943
Harald Weltea0630032018-03-20 21:09:55 +01003944 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003945 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003946}
Harald Welte552620d2017-12-16 23:21:36 +01003947testcase TC_assignment_fr_a5_0() runs on test_CT {
3948 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003949 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003950 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003951
Harald Welte89d42e82017-12-17 16:42:41 +01003952 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003953 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003954 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003955 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003956 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003957}
Harald Welte552620d2017-12-16 23:21:36 +01003958testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003959 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003960 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003961 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003962
Harald Welte89d42e82017-12-17 16:42:41 +01003963 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003964 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003965 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3966 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003967 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003968}
3969testcase TC_assignment_fr_a5_3() runs on test_CT {
3970 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003971 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003972 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003973
Harald Welte651fcdc2018-05-10 20:23:16 +02003974 f_init(1, true);
3975 f_sleep(1.0);
3976 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003977 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003978 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003979}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003980/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3981testcase TC_assignment_fr_a5_4() runs on test_CT {
3982 var MSC_ConnHdlr vc_conn;
3983 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3984 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3985
3986 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003987 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003988 f_sleep(1.0);
3989 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3990 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003991 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003992 f_shutdown_helper();
3993}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003994
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003995/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3996testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3997 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3998 var MSC_ConnHdlr vc_conn;
3999
4000 f_init(1, true);
4001 f_sleep(1.0);
4002
4003 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
4004 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
4005 vc_conn.done;
4006 f_shutdown_helper();
4007}
4008
Harald Welte552620d2017-12-16 23:21:36 +01004009/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
4010private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004011 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004012 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02004013 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004014
4015 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02004016 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
4017
Harald Weltea0630032018-03-20 21:09:55 +01004018 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004019 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004020}
Harald Welte552620d2017-12-16 23:21:36 +01004021testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
4022 var MSC_ConnHdlr vc_conn;
4023
Harald Welte89d42e82017-12-17 16:42:41 +01004024 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004025 f_sleep(1.0);
4026
Harald Welte8863fa12018-05-10 20:15:27 +02004027 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01004028 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004029 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004030}
4031
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004032private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
4033 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
4034 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01004035
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004036 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4037 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4038
4039 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
4040
4041 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004042
4043 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
4044 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
4045
4046 f_create_chan_and_exp();
4047 /* we should now have a COMPL_L3 at the MSC */
4048
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004049 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02004050 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004051 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01004052}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004053testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
4054 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01004055 var MSC_ConnHdlr vc_conn;
4056
Harald Welte89d42e82017-12-17 16:42:41 +01004057 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01004058 f_sleep(1.0);
4059
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004060 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004061 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004062 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004063 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004064}
4065
4066
Harald Welte4532e0a2017-12-23 02:05:44 +01004067private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004068 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004069 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004070 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004071 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004072
4073 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004074 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004075
4076 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004077 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4078 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004079 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4080 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4081 };
4082 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004083 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004084}
4085
4086testcase TC_assignment_sign() runs on test_CT {
4087 var MSC_ConnHdlr vc_conn;
4088
4089 f_init(1, true);
4090 f_sleep(1.0);
4091
Harald Welte8863fa12018-05-10 20:15:27 +02004092 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004093 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004094 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004095}
4096
Harald Welte60aa5762018-03-21 19:33:13 +01004097/***********************************************************************
4098 * Codec (list) testing
4099 ***********************************************************************/
4100
4101/* check if the given rsl_mode is compatible with the a_elem */
4102private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4103return boolean {
4104 select (a_elem.codecType) {
4105 case (GSM_FR) {
4106 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4107 return true;
4108 }
4109 }
4110 case (GSM_HR) {
4111 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4112 return true;
4113 }
4114 }
4115 case (GSM_EFR) {
4116 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4117 return true;
4118 }
4119 }
4120 case (FR_AMR) {
4121 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4122 return true;
4123 }
4124 }
4125 case (HR_AMR) {
4126 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4127 return true;
4128 }
4129 }
4130 case else { }
4131 }
4132 return false;
4133}
4134
4135/* check if the given rsl_mode is compatible with the a_list */
4136private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4137return boolean {
4138 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4139 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4140 return true;
4141 }
4142 }
4143 return false;
4144}
4145
4146/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004147function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004148return BSSMAP_IE_ChannelType {
4149 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4150 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4151 select (a_elem.codecType) {
4152 case (GSM_FR) {
4153 ret.channelRateAndType := ChRate_TCHF;
4154 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4155 }
4156 case (GSM_HR) {
4157 ret.channelRateAndType := ChRate_TCHH;
4158 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4159 }
4160 case (GSM_EFR) {
4161 ret.channelRateAndType := ChRate_TCHF;
4162 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4163 }
4164 case (FR_AMR) {
4165 ret.channelRateAndType := ChRate_TCHF;
4166 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4167 }
4168 case (HR_AMR) {
4169 ret.channelRateAndType := ChRate_TCHH;
4170 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4171 }
4172 case else {
4173 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004174 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004175 }
4176 }
4177 return ret;
4178}
4179
Harald Weltea63b9102018-03-22 20:36:16 +01004180private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4181return template RSL_IE_Body {
4182 var template RSL_IE_Body mode_ie := {
4183 chan_mode := {
4184 len := ?,
4185 reserved := ?,
4186 dtx_d := ?,
4187 dtx_u := ?,
4188 spd_ind := RSL_SPDI_SPEECH,
4189 ch_rate_type := -,
4190 coding_alg_rate := -
4191 }
4192 }
4193
4194 select (a_elem.codecType) {
4195 case (GSM_FR) {
4196 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4197 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4198 }
4199 case (GSM_HR) {
4200 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4201 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4202 }
4203 case (GSM_EFR) {
4204 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4205 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4206 }
4207 case (FR_AMR) {
4208 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4209 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4210 }
4211 case (HR_AMR) {
4212 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4213 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4214 }
4215 }
4216 return mode_ie;
4217}
4218
Harald Welte60aa5762018-03-21 19:33:13 +01004219type record CodecListTest {
4220 BSSMAP_IE_SpeechCodecList codec_list,
4221 charstring id
4222}
4223type record of CodecListTest CodecListTests
4224
4225private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004226 f_assignment_codec(id);
4227}
4228
4229private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004230 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4231 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004232
4233 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004234 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004235 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4236 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4237 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004238 if (isvalue(g_pars.expect_mr_s0_s7)) {
4239 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4240 g_pars.expect_mr_s0_s7;
4241 }
Harald Welte79f3f542018-05-25 20:02:37 +02004242 }
Harald Welte60aa5762018-03-21 19:33:13 +01004243 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4244 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004245 log("expecting ASS COMPL like this: ", exp_compl);
4246
4247 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004248
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004249 if (not g_pars.expect_channel_mode_modify) {
4250 /* Verify that the RSL-side activation actually matches our expectations */
4251 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004252
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004253 var RSL_IE_Body mode_ie;
4254 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4255 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004256 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004257 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004258 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4259 if (not match(mode_ie, t_mode_ie)) {
4260 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4261 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004262 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004263
4264 var RSL_IE_Body mr_conf;
4265 if (g_pars.expect_mr_conf_ie != omit) {
4266 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4267 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4268 mtc.stop;
4269 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004270 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004271
4272 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4273 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4274 g_pars.expect_mr_conf_ie);
4275 }
4276 } else {
4277 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4278 log("found RSL MR CONFIG IE: ", mr_conf);
4279 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4280 mtc.stop;
4281 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004282 }
4283 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004284
4285 if (do_perform_clear) {
4286 f_perform_clear();
4287 }
Harald Welte60aa5762018-03-21 19:33:13 +01004288}
4289
Philipp Maierd0e64b02019-03-13 14:15:23 +01004290private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4291
4292 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4293 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4294
4295 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004296 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004297 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4298 }
4299 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4300 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4301 log("expecting ASS FAIL like this: ", exp_fail);
4302
4303 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004304 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004305}
4306
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004307const CounterNameVals counternames_bsc_bts_assignment := {
4308 { "assignment:attempted", 0 },
4309 { "assignment:completed", 0 },
4310 { "assignment:stopped", 0 },
4311 { "assignment:no_channel", 0 },
4312 { "assignment:timeout", 0 },
4313 { "assignment:failed", 0 },
4314 { "assignment:error", 0 }
4315};
4316
4317const CounterNameVals counternames_bts_assignment := {
4318 { "assignment:attempted_sign", 0 },
4319 { "assignment:attempted_speech", 0 },
4320 { "assignment:completed_sign", 0 },
4321 { "assignment:completed_speech", 0 },
4322 { "assignment:stopped_sign", 0 },
4323 { "assignment:stopped_speech", 0 },
4324 { "assignment:no_channel_sign", 0 },
4325 { "assignment:no_channel_speech", 0 },
4326 { "assignment:timeout_sign", 0 },
4327 { "assignment:timeout_speech", 0 },
4328 { "assignment:failed_sign", 0 },
4329 { "assignment:failed_speech", 0 },
4330 { "assignment:error_sign", 0 },
4331 { "assignment:error_speech", 0 }
4332};
4333
4334function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4335 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4336 f_ctrs_bts_init(bts_count, bts_names);
4337 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4338}
4339
Harald Welte60aa5762018-03-21 19:33:13 +01004340testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004341 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004342 var MSC_ConnHdlr vc_conn;
4343
4344 f_init(1, true);
4345 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004346 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004347
4348 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004349 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004350 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004351
4352 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4353 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4354 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4355 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4356 f_ctrs_bts_verify();
4357
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004358 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004359}
4360
4361testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004362 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004363 var MSC_ConnHdlr vc_conn;
4364
4365 f_init(1, true);
4366 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004367 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004368
4369 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004370 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004371 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004372
4373 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4374 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4375 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4376 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4377 f_ctrs_bts_verify();
4378
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004379 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004380}
4381
4382testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004383 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004384 var MSC_ConnHdlr vc_conn;
4385
4386 f_init(1, true);
4387 f_sleep(1.0);
4388
4389 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004390 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004391 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004392 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004393}
4394
Philipp Maierd0e64b02019-03-13 14:15:23 +01004395/* Allow 5,90k only (current default config) */
4396private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004397 f_vty_cfg_msc(BSCVTY, 0, {
4398 "amr-config 12_2k forbidden",
4399 "amr-config 10_2k forbidden",
4400 "amr-config 7_95k forbidden",
4401 "amr-config 7_40k forbidden",
4402 "amr-config 6_70k forbidden",
4403 "amr-config 5_90k allowed",
4404 "amr-config 5_15k forbidden",
4405 "amr-config 4_75k forbidden"
4406 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004407}
4408
4409/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4410 * ("Config-NB-Code = 1") */
4411private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004412 f_vty_cfg_msc(BSCVTY, 0, {
4413 "amr-config 12_2k allowed",
4414 "amr-config 10_2k forbidden",
4415 "amr-config 7_95k forbidden",
4416 "amr-config 7_40k allowed",
4417 "amr-config 6_70k forbidden",
4418 "amr-config 5_90k allowed",
4419 "amr-config 5_15k forbidden",
4420 "amr-config 4_75k allowed"
4421 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004422}
4423
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004424private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4425 var charstring tch;
4426 if (fr) {
4427 tch := "tch-f";
4428 } else {
4429 tch := "tch-h";
4430 }
4431 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4432}
4433
4434/* Set the AMR start-mode for this TCH back to the default configuration. */
4435private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4436 f_vty_amr_start_mode_set(fr, "auto");
4437}
4438
Harald Welte60aa5762018-03-21 19:33:13 +01004439testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004440 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004441 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004442
4443 /* Note: This setups the codec configuration. The parameter payload in
4444 * mr_conf must be consistant with the parameter codecElements in pars
4445 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004446 var RSL_IE_Body mr_conf := {
4447 other := {
4448 len := 2,
4449 payload := '2804'O
4450 }
4451 };
Harald Welte60aa5762018-03-21 19:33:13 +01004452
Philipp Maier7695a0d2018-09-27 17:52:14 +02004453 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004454 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004455 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4456 pars.expect_mr_conf_ie := mr_conf;
4457
Harald Welte60aa5762018-03-21 19:33:13 +01004458 f_init(1, true);
4459 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004460 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004461 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004462
Harald Welte8863fa12018-05-10 20:15:27 +02004463 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004464 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004465
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004466 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4467 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4468 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4469 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4470 f_ctrs_bts_verify();
4471
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004472 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004473 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004474}
4475
4476testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004477 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004478 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004479
4480 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004481 var RSL_IE_Body mr_conf := {
4482 other := {
4483 len := 2,
4484 payload := '2804'O
4485 }
4486 };
Harald Welte60aa5762018-03-21 19:33:13 +01004487
Philipp Maier7695a0d2018-09-27 17:52:14 +02004488 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004489 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004490 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4491 pars.expect_mr_conf_ie := mr_conf;
4492
Harald Welte60aa5762018-03-21 19:33:13 +01004493 f_init(1, true);
4494 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004495 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004496 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004497
Harald Welte8863fa12018-05-10 20:15:27 +02004498 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004499 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004500
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004501 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4502 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4503 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4504 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4505 f_ctrs_bts_verify();
4506
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004507 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004508 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004509}
4510
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004511/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4512testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4513 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4514 var MSC_ConnHdlr vc_conn;
4515
4516 f_init(1, true);
4517 f_sleep(1.0);
4518
4519 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4520 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4521 * expecting a Channel Mode Modify if the channel type is compatible. */
4522 f_disable_all_sdcch();
4523 f_disable_all_tch_h();
4524
4525 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4526 pars.expect_channel_mode_modify := true;
4527 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4528 vc_conn.done;
4529
4530 f_enable_all_sdcch();
4531 f_enable_all_tch();
4532 f_shutdown_helper();
4533}
4534
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004535/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4536testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4537 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4538 var MSC_ConnHdlr vc_conn;
4539
4540 var RSL_IE_Body mr_conf := {
4541 other := {
4542 len := 2,
4543 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4544 }
4545 };
4546
4547 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4548 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4549 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4550 pars.expect_mr_conf_ie := mr_conf;
4551
4552 f_init(1, true);
4553 f_sleep(1.0);
4554
4555 /* First set nonzero start mode bits */
4556 f_vty_amr_start_mode_set(true, "4");
4557 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4558 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4559 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4560 f_vty_amr_start_mode_set(true, "auto");
4561
4562 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4563 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004564
4565 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4566 f_vty_amr_start_mode_set(true, "1");
4567 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004568 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004569}
4570
Neels Hofmeyr21863562020-11-26 00:34:33 +00004571function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4572 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004573runs on test_CT {
4574
4575 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4576 var MSC_ConnHdlr vc_conn;
4577
4578 /* See note above */
4579 var RSL_IE_Body mr_conf := {
4580 other := {
4581 len := lengthof(mrconf),
4582 payload := mrconf
4583 }
4584 };
4585
4586 if (fr) {
4587 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4588 } else {
4589 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4590 }
4591 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4592 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4593 pars.expect_mr_conf_ie := mr_conf;
4594 pars.expect_mr_s0_s7 := exp_s8_s0;
4595
4596 f_init(1, true);
4597 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004598 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004599 f_sleep(1.0);
4600
4601 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4602 vc_conn.done;
4603 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004604 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004605}
4606
4607function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4608runs on test_CT {
4609
4610 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4611 var MSC_ConnHdlr vc_conn;
4612
4613 if (fr) {
4614 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4615 } else {
4616 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4617 }
4618 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4619 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4620
4621 f_init(1, true);
4622 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004623 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004624 f_sleep(1.0);
4625
4626 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4627 vc_conn.done;
4628 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004629 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004630}
4631
4632
4633/* Set S1, we expect an AMR multirate configuration IE with all four rates
4634 * set. */
4635testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004636 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004637 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004638}
4639
4640/* Set S1, we expect an AMR multirate configuration IE with the lower three
4641 * rates set. */
4642testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004643 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004644 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004645}
4646
4647/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4648 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4649testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004650 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004651 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004652}
4653
4654/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4655 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4656testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004657 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004658 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004659}
4660
4661/* The following block of tests selects more and more rates until all four
4662 * possible rates are in the active set (full rate) */
4663testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004664 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004665 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004666}
4667
4668testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004669 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004670 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004671}
4672
4673testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004674 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004675 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004676}
4677
4678testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004679 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004680 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004681}
4682
4683/* The following block of tests selects more and more rates until all three
4684 * possible rates are in the active set (half rate) */
4685testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004686 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004687 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004688}
4689
4690testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004691 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004692 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004693}
4694
4695testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004696 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004697 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004698}
4699
4700/* The following block tests what happens when the MSC does offer rate
4701 * configurations that are not supported by the BSC. Normally such situations
4702 * should not happen because the MSC gets informed by the BSC in advance via
4703 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4704 * to offer rates that are not applicable anyway. */
4705
4706testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004707 /* Try to include 12,2k in into the active set even though the channel
4708 * is half rate only. The BSC is expected to remove the 12,0k */
4709 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004710 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004711}
4712
4713testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004714 /* See what happens when all rates are selected at once. Since then
4715 * Also S1 is selected, this setting will be prefered and we should
4716 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4717 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004718 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004719}
4720
4721testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004722 /* Same as above, but with S1 missing, the MSC is then expected to
4723 * select the currently supported rates, which are also 12.2k, 7,40k,
4724 * 5,90k, and 4,75k, into the active set. */
4725 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004726 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004727}
4728
4729testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004730 /* Try to select no rates at all */
4731 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004732 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004733}
4734
4735testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004736 /* Try to select only unsupported rates */
4737 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004738 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004739}
4740
4741testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004742 /* Try to select 12,2k for half rate */
4743 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004744 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004745}
4746
Neels Hofmeyr21863562020-11-26 00:34:33 +00004747testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4748 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4749 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004750 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004751}
4752
4753testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4754 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4755 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004756 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004757}
4758
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004759testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004760 /* "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 +00004761 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4762 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004763 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004764}
4765
4766testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004767 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4768 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004769 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004770 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004771}
4772
Philipp Maierac09bfc2019-01-08 13:41:39 +01004773private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004774 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4775 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4776 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4777 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004778}
4779
4780private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004781 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4782 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004783}
4784
4785private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004786 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4787 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4788 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4789 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4790 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4791 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004792}
4793
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004794private function f_disable_all_sdcch() runs on test_CT {
4795 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4796 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4797 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4798 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4799}
4800
4801private function f_enable_all_sdcch() runs on test_CT {
4802 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4803 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4804 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4805 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4806}
4807
Philipp Maierac09bfc2019-01-08 13:41:39 +01004808/* Allow HR only */
4809private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4810 g_pars := f_gen_test_hdlr_pars();
4811 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4812 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4813 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4814 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4815 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4816 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4817 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004818 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004819}
4820
4821/* Allow FR only */
4822private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4823 g_pars := f_gen_test_hdlr_pars();
4824 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4825 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4826 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4827 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4828 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4829 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4830 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004831 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004832}
4833
4834/* Allow HR only (expect assignment failure) */
4835private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4836 g_pars := f_gen_test_hdlr_pars();
4837 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4838 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4839 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4840 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4841 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4842 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4843 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004844 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004845}
4846
4847/* Allow FR only (expect assignment failure) */
4848private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4849 g_pars := f_gen_test_hdlr_pars();
4850 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4851 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4852 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4853 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4854 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4855 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4856 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004857 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004858}
4859
4860/* Allow FR and HR, but prefer FR */
4861private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4862 g_pars := f_gen_test_hdlr_pars();
4863 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4864 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4865 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4866 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4867 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4868 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4869 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4870 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004871 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004872}
4873
4874/* Allow FR and HR, but prefer HR */
4875private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4876 g_pars := f_gen_test_hdlr_pars();
4877 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4878 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4879 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4880 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4881 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4882 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4883 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4884 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004885 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004886}
4887
4888/* Allow FR and HR, but prefer FR */
4889private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4890 g_pars := f_gen_test_hdlr_pars();
4891 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4892 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4893 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4894 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4895 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4896 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4897 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4898 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004899 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004900}
4901
4902/* Allow FR and HR, but prefer HR */
4903private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4904 g_pars := f_gen_test_hdlr_pars();
4905 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4906 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4907 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4908 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4909 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4910 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4911 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4912 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004913 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004914}
4915
4916/* Request a HR channel while all FR channels are exhausted, this is expected
4917 * to work without conflicts */
4918testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4919 var MSC_ConnHdlr vc_conn;
4920 f_init(1, true);
4921 f_sleep(1.0);
4922 f_enable_all_tch();
4923 f_disable_all_tch_f();
4924 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4925 vc_conn.done;
4926 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004927 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004928}
4929
4930/* Request a FR channel while all FR channels are exhausted, this is expected
4931 * to fail. */
4932testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4933 var MSC_ConnHdlr vc_conn;
4934 f_init(1, true);
4935 f_sleep(1.0);
4936 f_enable_all_tch();
4937 f_disable_all_tch_f();
4938 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4939 vc_conn.done;
4940 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004941 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004942}
4943
4944/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4945 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4946testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4947 var MSC_ConnHdlr vc_conn;
4948 f_init(1, true);
4949 f_sleep(1.0);
4950 f_enable_all_tch();
4951 f_disable_all_tch_f();
4952 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4953 vc_conn.done;
4954 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004955 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004956}
4957
4958/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4959 * are exhausted, this is expected to work without conflicts. */
4960testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4961 var MSC_ConnHdlr vc_conn;
4962 f_init(1, true);
4963 f_sleep(1.0);
4964 f_enable_all_tch();
4965 f_disable_all_tch_f();
4966 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4967 vc_conn.done;
4968 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004969 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004970}
4971
4972/* Request a FR channel while all HR channels are exhausted, this is expected
4973 * to work without conflicts */
4974testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4975 var MSC_ConnHdlr vc_conn;
4976 f_init(1, true);
4977 f_sleep(1.0);
4978 f_enable_all_tch();
4979 f_disable_all_tch_h();
4980 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4981 vc_conn.done;
4982 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004983 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004984}
4985
4986/* Request a HR channel while all HR channels are exhausted, this is expected
4987 * to fail. */
4988testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4989 var MSC_ConnHdlr vc_conn;
4990 f_init(1, true);
4991 f_sleep(1.0);
4992 f_enable_all_tch();
4993 f_disable_all_tch_h();
4994 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4995 vc_conn.done;
4996 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004997 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004998}
4999
5000/* Request a HR (prefered) or alternatively a FR channel while all HR channels
5001 * are exhausted, this is expected to be resolved by selecting a FR channel. */
5002testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
5003 var MSC_ConnHdlr vc_conn;
5004 f_init(1, true);
5005 f_sleep(1.0);
5006 f_enable_all_tch();
5007 f_disable_all_tch_h();
5008 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
5009 vc_conn.done;
5010 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005011 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005012}
5013
5014/* Request a FR (prefered) or alternatively a HR channel while all HR channels
5015 * are exhausted, this is expected to work without conflicts. */
5016testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
5017 var MSC_ConnHdlr vc_conn;
5018 f_init(1, true);
5019 f_sleep(1.0);
5020 f_enable_all_tch();
5021 f_disable_all_tch_h();
5022 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
5023 vc_conn.done;
5024 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005025 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005026}
5027
5028/* Allow FR and HR, but prefer HR */
5029private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
5030 g_pars := f_gen_test_hdlr_pars();
5031 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5032 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5033 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5034 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
5035 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
5036 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
5037 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
5038 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005039 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005040}
5041
5042/* Allow FR and HR, but prefer FR */
5043private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
5044 g_pars := f_gen_test_hdlr_pars();
5045 var PDU_BSSAP ass_cmd := f_gen_ass_req();
5046 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5047 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5048 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
5049 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
5050 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
5051 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
5052 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005053 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005054}
5055
5056/* Request a HR (prefered) or alternatively a FR channel, it is expected that
5057 * HR, which is the prefered type, is selected. */
5058testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5059 var MSC_ConnHdlr vc_conn;
5060 f_init(1, true);
5061 f_sleep(1.0);
5062 f_enable_all_tch();
5063 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5064 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005065 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005066}
5067
5068/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5069 * FR, which is the prefered type, is selected. */
5070testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5071 var MSC_ConnHdlr vc_conn;
5072 f_init(1, true);
5073 f_sleep(1.0);
5074 f_enable_all_tch();
5075 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5076 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005077 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005078}
5079
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005080/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5081private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5082 g_pars := f_gen_test_hdlr_pars();
5083 g_pars.ra := '02'O; /* RA containing reason=LU */
5084
5085 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5086 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5087 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5088 var template uint3_t tsc := ?;
5089
5090 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5091 f_create_bssmap_exp(l3_enc);
5092 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5093 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5094
5095 /* we should now have a COMPL_L3 at the MSC */
5096 timer T := 10.0;
5097 T.start;
5098 alt {
5099 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5100 [] T.timeout {
5101 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5102 }
5103 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005104
5105 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005106}
5107testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5108 var MSC_ConnHdlr vc_conn;
5109 f_init(1, true);
5110 f_sleep(1.0);
5111 f_disable_all_sdcch();
5112 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5113 vc_conn.done;
5114 f_enable_all_sdcch();
5115 f_shutdown_helper();
5116}
5117
5118/* Request a signalling channel with all SDCCH exhausted, it is
5119 expected that no TCH will be selected for signalling and assigment will fail
5120 because it's dictated by VTY config */
5121testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5122 var RSL_Message rsl_unused, rsl_msg;
5123 var GsmRrMessage rr;
5124 f_init(1, false);
5125 f_sleep(1.0);
5126 f_vty_allow_tch_for_signalling(false, 0);
5127 f_disable_all_sdcch();
5128
5129 /* RA containing reason=LU */
5130 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
5131 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
5132 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5133 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5134 setverdict(fail, "Expected reject");
5135 }
5136
5137 f_vty_allow_tch_for_signalling(true, 0);
5138 f_enable_all_sdcch();
5139 f_shutdown_helper();
5140}
5141
5142/* Request a voice channel with all SDCCH exhausted, it is
5143 * expected that TCH channel will be allocated since the VTY option is only
5144 * aimed at signalling requests */
5145private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5146 g_pars := f_gen_test_hdlr_pars();
5147 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5148
5149 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5150 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5151 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5152 var template uint3_t tsc := ?;
5153
5154 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5155 f_create_bssmap_exp(l3_enc);
5156 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5157 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5158
5159 /* we should now have a COMPL_L3 at the MSC */
5160 timer T := 10.0;
5161 T.start;
5162 alt {
5163 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5164 [] T.timeout {
5165 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5166 }
5167 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005168 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005169}
5170testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5171 var MSC_ConnHdlr vc_conn;
5172 f_init(1, true);
5173 f_sleep(1.0);
5174 f_vty_allow_tch_for_signalling(false, 0);
5175 f_disable_all_sdcch();
5176
5177 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5178 vc_conn.done;
5179
5180 f_vty_allow_tch_for_signalling(true, 0);
5181 f_enable_all_sdcch();
5182 f_shutdown_helper();
5183}
5184
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005185testcase TC_assignment_osmux() runs on test_CT {
5186 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5187 var MSC_ConnHdlr vc_conn;
5188
5189 /* See note above */
5190 var RSL_IE_Body mr_conf := {
5191 other := {
5192 len := 2,
5193 payload := '2804'O
5194 }
5195 };
5196
5197 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5198 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5199 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
5200 pars.expect_mr_conf_ie := mr_conf;
5201 pars.use_osmux := true;
5202
5203 f_init(1, true, true);
5204 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005205 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005206
5207 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5208 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005209
5210 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005211 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005212}
5213
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005214/* test the procedure of the MSC requesting a Classmark Update:
5215 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5216 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005217private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005218 g_pars := f_gen_test_hdlr_pars();
5219
Harald Weltea0630032018-03-20 21:09:55 +01005220 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005221 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005222
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005223 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5224 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5225
Harald Welte898113b2018-01-31 18:32:21 +01005226 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5227 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5228 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005229
5230 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005231}
5232testcase TC_classmark() runs on test_CT {
5233 var MSC_ConnHdlr vc_conn;
5234 f_init(1, true);
5235 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005236 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005237 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005238 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005239}
5240
Harald Welteeddf0e92020-06-21 19:42:15 +02005241/* Send a CommonID from the simulated MSC and verify that the information is used to
5242 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5243private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5244 g_pars := f_gen_test_hdlr_pars();
5245 f_MscConnHdlr_init_vty();
5246
5247 f_create_chan_and_exp();
5248 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005249
5250 /* Send CommonID */
5251 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5252
5253 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5254 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5255 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5256
5257 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005258
5259 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005260}
5261testcase TC_common_id() runs on test_CT {
5262 var MSC_ConnHdlr vc_conn;
5263 f_init(1, true);
5264 f_sleep(1.0);
5265 vc_conn := f_start_handler(refers(f_tc_common_id));
5266 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005267 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005268}
5269
Harald Weltee3bd6582018-01-31 22:51:25 +01005270private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005271 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005272 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005273 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005274
Harald Weltee3bd6582018-01-31 22:51:25 +01005275 /* send the single message we want to send */
5276 f_rsl_send_l3(l3);
5277}
5278
5279private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5280 timer T := sec;
5281 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005282 T.start;
5283 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005284 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5285 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005286 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005287 }
5288 [] T.timeout {
5289 setverdict(pass);
5290 }
5291 }
5292}
5293
Harald Weltee3bd6582018-01-31 22:51:25 +01005294/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5295private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5296 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5297 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005298 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005299}
Harald Welte898113b2018-01-31 18:32:21 +01005300testcase TC_unsol_ass_fail() runs on test_CT {
5301 var MSC_ConnHdlr vc_conn;
5302 f_init(1, true);
5303 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005304 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005305 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005306 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005307}
Harald Welte552620d2017-12-16 23:21:36 +01005308
Harald Welteea99a002018-01-31 20:46:43 +01005309
5310/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5311private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005312 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5313 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005314 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005315}
5316testcase TC_unsol_ass_compl() runs on test_CT {
5317 var MSC_ConnHdlr vc_conn;
5318 f_init(1, true);
5319 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005320 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005321 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005322 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005323}
5324
5325
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005326/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5327private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005328 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5329 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005330 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005331}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005332testcase TC_unsol_ho_fail() runs on test_CT {
5333 var MSC_ConnHdlr vc_conn;
5334 f_init(1, true);
5335 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005336 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005337 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005338 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005339}
5340
5341
Harald Weltee3bd6582018-01-31 22:51:25 +01005342/* short message from MS should be ignored */
5343private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005344 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005345 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005346 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005347
5348 /* send short message */
5349 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5350 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005351 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005352}
5353testcase TC_err_82_short_msg() runs on test_CT {
5354 var MSC_ConnHdlr vc_conn;
5355 f_init(1, true);
5356 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005357 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005358 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005359 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005360}
5361
5362
Harald Weltee9e02e42018-01-31 23:36:25 +01005363/* 24.008 8.4 Unknown message must trigger RR STATUS */
5364private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5365 f_est_single_l3(ts_RRM_UL_REL('00'O));
5366 timer T := 3.0
5367 alt {
5368 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5369 setverdict(pass);
5370 }
5371 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005372 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005373 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005374 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005375}
5376testcase TC_err_84_unknown_msg() runs on test_CT {
5377 var MSC_ConnHdlr vc_conn;
5378 f_init(1, true);
5379 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005380 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005381 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005382 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005383}
5384
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005385/***********************************************************************
5386 * Handover
5387 ***********************************************************************/
5388
Harald Welte94e0c342018-04-07 11:33:23 +02005389/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5390private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5391runs on test_CT {
5392 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5393 " timeslot "&int2str(ts_nr)&" ";
5394 f_vty_transceive(BSCVTY, cmd & suffix);
5395}
5396
Harald Welte261af4b2018-02-12 21:20:39 +01005397/* 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 +07005398private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5399 uint8_t bts_nr, uint8_t trx_nr,
5400 in RslChannelNr chan_nr)
5401{
Harald Welte261af4b2018-02-12 21:20:39 +01005402 /* FIXME: resolve those from component-global state */
5403 var integer ts_nr := chan_nr.tn;
5404 var integer ss_nr;
5405 if (ischosen(chan_nr.u.ch0)) {
5406 ss_nr := 0;
5407 } else if (ischosen(chan_nr.u.lm)) {
5408 ss_nr := chan_nr.u.lm.sub_chan;
5409 } else if (ischosen(chan_nr.u.sdcch4)) {
5410 ss_nr := chan_nr.u.sdcch4.sub_chan;
5411 } else if (ischosen(chan_nr.u.sdcch8)) {
5412 ss_nr := chan_nr.u.sdcch8.sub_chan;
5413 } else {
5414 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005415 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005416 }
5417
5418 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5419 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005420 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005421}
5422
Neels Hofmeyr91401012019-07-11 00:42:35 +02005423/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5424 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5425 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5426 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5427 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005428private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5429 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5430{
5431 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005432}
5433
5434/* intra-BSC hand-over between BTS0 and BTS1 */
5435private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005436 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5437 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005438
5439 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5440 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5441
Harald Weltea0630032018-03-20 21:09:55 +01005442 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005443 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005444
5445 var HandoverState hs := {
5446 rr_ho_cmpl_seen := false,
5447 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005448 old_chan_nr := -,
5449 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005450 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005451 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005452 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005453 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5454 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005455
5456 /* From the MGW perspective, a handover is is characterized by
5457 * performing one MDCX operation with the MGW. So we expect to see
5458 * one more MDCX during handover. */
5459 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5460
Harald Welte261af4b2018-02-12 21:20:39 +01005461 alt {
5462 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005463 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005464
Philipp Maier4dae0652018-11-12 12:03:26 +01005465 /* Since this is an internal handover we expect the BSC to inform the
5466 * MSC about the event */
5467 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5468
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005469 /* Check the amount of MGCP transactions is still consistant with the
5470 * test expectation */
5471 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005472
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005473 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5474
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005475 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5476 * g_chan_nr to the new lchan that was handed over to. It lives in bts 1, so look it up at RSL1_PROC. */
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005477 f_verify_encr_info(chan_act);
5478
5479 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005480
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005481 f_perform_clear(RSL1, RSL1_PROC);
5482
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005483 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005484}
5485
5486testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005487 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005488 var MSC_ConnHdlr vc_conn;
5489 f_init(2, true);
5490 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005491
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005492 pars.expect_tsc := BTS_TSC[0];
5493
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005494 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005495
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005496 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005497 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005498
5499 /* from f_establish_fully() */
5500 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5501 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5502 /* from handover */
5503 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5504 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5505 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5506 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005507 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5508 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005509 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005510 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005511}
Harald Weltee9e02e42018-01-31 23:36:25 +01005512
Oliver Smith7eabd312021-07-12 14:18:56 +02005513function 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 +02005514 var MSC_ConnHdlr vc_conn;
5515 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5516 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5517
5518 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005519 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005520 f_sleep(1.0);
5521
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005522 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005523
5524 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5525 vc_conn.done;
5526
5527 /* from f_establish_fully() */
5528 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5529 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5530 /* from handover */
5531 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5532 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5533 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5534 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005535 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5536 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005537 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005538 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005539 f_shutdown_helper();
5540}
5541
5542testcase TC_ho_int_a5_0() runs on test_CT {
5543 f_tc_ho_int_a5('01'O);
5544}
5545
5546testcase TC_ho_int_a5_1() runs on test_CT {
5547 f_tc_ho_int_a5('02'O);
5548}
5549
5550testcase TC_ho_int_a5_3() runs on test_CT {
5551 f_tc_ho_int_a5('08'O);
5552}
5553
5554testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005555 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005556}
5557
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005558/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5559private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5560 g_pars := f_gen_test_hdlr_pars();
5561 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5562 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005563
5564 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5565 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5566
5567 f_establish_fully(ass_cmd, exp_compl);
5568 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5569
5570 var HandoverState hs := {
5571 rr_ho_cmpl_seen := false,
5572 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005573 old_chan_nr := -,
5574 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005575 };
5576 /* issue hand-over command on VTY */
5577 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5578 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5579 f_rslem_suspend(RSL1_PROC);
5580
5581 /* From the MGW perspective, a handover is is characterized by
5582 * performing one MDCX operation with the MGW. So we expect to see
5583 * one more MDCX during handover. */
5584 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5585
5586 var RSL_Message rsl;
5587 var PDU_ML3_NW_MS l3;
5588 var RslChannelNr new_chan_nr;
5589 var GsmArfcn arfcn;
5590 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5591 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5592 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5593 setverdict(fail, "Expected handoverCommand");
5594 mtc.stop;
5595 }
5596 }
5597 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5598 new_chan_nr, arfcn);
5599
5600 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5601
5602 /* resume processing of RSL DChan messages, which was temporarily suspended
5603 * before performing a hand-over */
5604 f_rslem_resume(RSL1_PROC);
5605 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5606
5607 f_sleep(1.0);
5608
5609 /* Handover fails because no HANDO DET appears on the new lchan,
5610 * and the old lchan reports a Radio Link Failure. */
5611 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5612
5613 var PDU_BSSAP rx_clear_request;
5614 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5615 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5616 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5617
5618 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5619
5620 var MgcpCommand mgcp;
5621 interleave {
5622 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5623 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005624 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005625 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005626 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005627 }
5628 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005629 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005630 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005631 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005632 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005633 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5634 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5635 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005636 }
5637
5638 f_sleep(0.5);
5639 setverdict(pass);
5640}
5641testcase TC_ho_int_radio_link_failure() runs on test_CT {
5642 var MSC_ConnHdlr vc_conn;
5643 f_init(2, true);
5644 f_sleep(1.0);
5645
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005646 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005647
5648 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5649 vc_conn.done;
5650
5651 /* from f_establish_fully() */
5652 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5653 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5654 /* from handover */
5655 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5656 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5657 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5658 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005659 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5660 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005661 f_ctrs_bsc_and_bts_verify();
5662 f_shutdown_helper();
5663}
5664
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005665/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005666private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005667 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005668 var template MgcpResponse mgcp_resp;
5669 var MGCP_RecvFrom mrf;
5670 var template MgcpMessage msg_resp;
5671 var template MgcpMessage msg_dlcx := {
5672 command := tr_DLCX()
5673 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005674
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005675 if (g_pars.aoip) {
5676 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005677 log("Got first DLCX: ", mgcp);
5678 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005679 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005680
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005681 MGCP.receive(tr_DLCX()) -> value mgcp {
5682 log("Got second DLCX: ", mgcp);
5683 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5684 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005685 } else {
5686 /* For SCCPLite, BSC doesn't handle the MSC-side */
5687 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5688 log("Got first DLCX: ", mrf.msg.command);
5689 msg_resp := {
5690 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5691 }
5692 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5693 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005694 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005695}
5696
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005697private 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 +01005698
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005699 var NcellReports neighbor_rep := {
5700 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5701 };
5702 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5703 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5704 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005705
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005706 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005707
5708 f_sleep(0.5);
5709 /* The MSC negotiates Handover Request and Handover Request Ack with
5710 * the other BSS and comes back with a BSSMAP Handover Command
5711 * containing an RR Handover Command coming from the target BSS... */
5712
5713 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5714 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5715 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5716 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5717 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5718
5719 /* expect the Handover Command to go out on RR */
5720 var RSL_Message rsl_ho_cmd
5721 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5722 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5723 var RSL_IE_Body rsl_ho_cmd_l3;
5724 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5725 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5726 setverdict(fail);
5727 } else {
5728 log("Found L3 Info: ", rsl_ho_cmd_l3);
5729 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5730 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5731 setverdict(fail);
5732 } else {
5733 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5734 setverdict(pass);
5735 }
5736 }
5737
5738 /* When the other BSS has reported a completed handover, this side is
5739 * torn down. */
5740
5741 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5742 var BssmapCause cause := enum2int(cause_val);
5743 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5744
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005745 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005746
5747 interleave {
5748 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5749 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5750 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005751 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5752 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5753 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005754 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005755 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005756}
5757
5758private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5759 g_pars := f_gen_test_hdlr_pars();
5760 var PDU_BSSAP ass_req := f_gen_ass_req();
5761 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5762 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5763 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5764 f_establish_fully(ass_req, exp_compl);
5765
5766 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005767}
5768testcase TC_ho_out_of_this_bsc() runs on test_CT {
5769 var MSC_ConnHdlr vc_conn;
5770
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005771 f_init_vty();
5772 f_bts_0_cfg(BSCVTY,
5773 {"neighbor-list mode automatic",
5774 "handover 1",
5775 "handover algorithm 2",
5776 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005777 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005778 "neighbor lac 99 arfcn 123 bsic any"});
5779 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5780
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005781 f_init(1, true);
5782 f_sleep(1.0);
5783
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005784 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005785
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005786 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5787 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005788
5789 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5790 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5791 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5792 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5793 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5794 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5795 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005796 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005797}
5798
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005799private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5800 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005801 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005802 octetstring l3 := '0123456789'O)
5803runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005804 /* The old lchan and conn should still be active. See that arbitrary L3
5805 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005806 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005807 var template PDU_BSSAP exp_data := {
5808 discriminator := '1'B,
5809 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005810 dlci := dlci,
5811 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005812 pdu := {
5813 dtap := l3
5814 }
5815 };
5816 BSSAP.receive(exp_data);
5817 setverdict(pass);
5818}
5819
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005820private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5821 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005822 template (value) OCT1 dlci := '00'O,
5823 octetstring l3 := '0123456789'O)
5824runs on MSC_ConnHdlr {
5825 BSSAP.send(PDU_BSSAP:{
5826 discriminator := '1'B,
5827 spare := '0000000'B,
5828 dlci := dlci,
5829 lengthIndicator := lengthof(l3),
5830 pdu := {
5831 dtap := l3
5832 }
5833 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005834 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005835 setverdict(pass);
5836}
5837
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005838/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5839 * simply never sends a BSSMAP Handover Command. */
5840private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005841 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005842
5843 var PDU_BSSAP ass_req := f_gen_ass_req();
5844 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5845 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5846 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5847 f_establish_fully(ass_req, exp_compl);
5848
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005849 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005850 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5851
5852 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5853
5854 /* osmo-bsc should time out 10 seconds after the handover started.
5855 * Let's give it a bit extra. */
5856 f_sleep(15.0);
5857
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005858 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005859 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005860 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005861}
5862testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5863 var MSC_ConnHdlr vc_conn;
5864
5865 f_init(1, true);
5866 f_sleep(1.0);
5867
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005868 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005869
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005870 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5871 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005872
5873 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5874 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5875 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5876 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5877 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5878 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5879 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005880 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005881}
5882
5883/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5884 * RR Handover Failure. */
5885private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005886 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005887
5888 var PDU_BSSAP ass_req := f_gen_ass_req();
5889 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5890 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5891 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5892 f_establish_fully(ass_req, exp_compl);
5893
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005894 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005895 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5896
5897 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5898
5899 f_sleep(0.5);
5900 /* The MSC negotiates Handover Request and Handover Request Ack with
5901 * the other BSS and comes back with a BSSMAP Handover Command
5902 * containing an RR Handover Command coming from the target BSS... */
5903
5904 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5905 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5906 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5907 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5908 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5909
5910 /* expect the Handover Command to go out on RR */
5911 var RSL_Message rsl_ho_cmd
5912 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5913 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5914 var RSL_IE_Body rsl_ho_cmd_l3;
5915 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5916 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5917 setverdict(fail);
5918 } else {
5919 log("Found L3 Info: ", rsl_ho_cmd_l3);
5920 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5921 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5922 setverdict(fail);
5923 } else {
5924 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5925 setverdict(pass);
5926 }
5927 }
5928
5929 f_sleep(0.2);
5930 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5931
5932 /* Should tell the MSC about the failure */
5933 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5934
5935 f_sleep(1.0);
5936
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005937 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005938 f_sleep(1.0);
5939
5940 setverdict(pass);
5941 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005942 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005943}
5944testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5945 var MSC_ConnHdlr vc_conn;
5946
5947 f_init(1, true);
5948 f_sleep(1.0);
5949
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005950 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005951
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005952 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5953 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005954
5955 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5956 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5957 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5958 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5959 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5960 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5961 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005962 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005963}
5964
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005965/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5966 * (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 +02005967 * and the lchan is released. */
5968private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005969 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005970
5971 var PDU_BSSAP ass_req := f_gen_ass_req();
5972 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5973 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5974 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5975 f_establish_fully(ass_req, exp_compl);
5976
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005977 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005978 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5979
5980 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5981
5982 f_sleep(0.5);
5983 /* The MSC negotiates Handover Request and Handover Request Ack with
5984 * the other BSS and comes back with a BSSMAP Handover Command
5985 * containing an RR Handover Command coming from the target BSS... */
5986
5987 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5988 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5989 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5990 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5991 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5992
5993 /* expect the Handover Command to go out on RR */
5994 var RSL_Message rsl_ho_cmd
5995 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5996 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5997 var RSL_IE_Body rsl_ho_cmd_l3;
5998 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5999 log("RSL message contains no L3 Info IE, expected RR Handover Command");
6000 setverdict(fail);
6001 } else {
6002 log("Found L3 Info: ", rsl_ho_cmd_l3);
6003 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
6004 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
6005 setverdict(fail);
6006 } else {
6007 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
6008 setverdict(pass);
6009 }
6010 }
6011
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02006012 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
6013 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
6014 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006015
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006016 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02006017 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
6018 log("Got BSSMAP Clear Request");
6019 /* Instruct BSC to clear channel */
6020 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6021 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6022
6023 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006024 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01006025 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
6026 log("Got Deact SACCH");
6027 }
Harald Welte924b6ea2019-02-04 01:05:34 +01006028 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01006029 log("Got RR Release");
6030 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02006031 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006032 log("Got RF Chan Rel");
6033 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02006034 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006035 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006036 }
6037
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006038 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006039 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006040 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006041
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006042 setverdict(pass);
6043 f_sleep(1.0);
6044}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006045testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006046 var MSC_ConnHdlr vc_conn;
6047
6048 f_init(1, true);
6049 f_sleep(1.0);
6050
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006051 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006052
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02006053 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006054 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006055
6056 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6057 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6058 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6059 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6060 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6061 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6062 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006063 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006064}
6065
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006066private function f_ho_into_this_bsc(charstring id, template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit) runs on MSC_ConnHdlr {
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006067 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006068 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6069 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6070 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6071 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6072 * before we get started. */
6073 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6074 f_rslem_register(0, new_chan_nr);
6075 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006076 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006077 f_sleep(1.0);
6078
6079 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6080 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006081 var default as_media := activate(as_Media());
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006082
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006083 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6084 cell_id_source := g_pars.cell_id_source,
6085 oldToNewBSSIEs := oldToNewBSSIEs,
6086 enc := g_pars.encr);
6087 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6088 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6089 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6090 } else {
6091 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6092 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6093 BSSAP.send(ho_req);
6094 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006095
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006096 alt {
6097 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6098 if (g_pars.expect_ho_fail) {
6099 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6100 "Expected Handover Request to fail, but got Handover Request Ack")
6101 }
6102 }
6103 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6104 if (not g_pars.expect_ho_fail) {
6105 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6106 "Expected Handover Request to succeed, but got Handover Failure")
6107 }
6108 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6109 // For now just accept any cause.
6110 BSSAP.receive(tr_BSSMAP_ClearRequest);
6111 setverdict(pass);
6112 return;
6113 }
6114 }
6115
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006116 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6117
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006118 /* we're sure that the channel activation is done now, verify the parameters in it */
6119 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6120 f_verify_encr_info(chan_act);
6121 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006122
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006123 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6124 if (not g_pars.aoip) {
6125 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6126 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6127 }
6128 /* TODO: check actual codecs? */
6129 } else {
6130 if (g_pars.aoip) {
6131 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6132 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6133 }
6134 }
6135
6136 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6137 if (not g_pars.aoip) {
6138 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6139 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6140 }
6141 /* TODO: check actual codec? */
6142 } else {
6143 if (g_pars.aoip) {
6144 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6145 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6146 }
6147 }
6148
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006149 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006150 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6151 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6152 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6153 log("L3 Info in HO Request Ack is ", ho_command);
6154
6155 var GsmArfcn arfcn;
6156 var RslChannelNr actual_new_chan_nr;
6157 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6158 actual_new_chan_nr, arfcn);
6159
6160 if (actual_new_chan_nr != new_chan_nr) {
6161 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6162 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6163 setverdict(fail);
6164 return;
6165 }
6166 log("Handover Command chan_nr is", actual_new_chan_nr);
6167
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006168 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6169 if (not match(got_tsc, expect_target_tsc)) {
6170 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6171 expect_target_tsc, " got ", got_tsc);
6172 mtc.stop;
6173 } else {
6174 log("handoverCommand: verified TSC = ", got_tsc);
6175 }
6176
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006177 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6178 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6179 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6180 var template (present) CipherModeSetting_TV tr_cms := {
6181 sC := '0'B, /* no ciphering by default */
6182 algorithmIdentifier := '000'B,
6183 elementIdentifier := ?
6184 };
6185 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6186 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6187 tr_cms.sC := '1'B;
6188 }
6189 if (not match(cms, tr_cms)) {
6190 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6191 cms, ", expected: ", tr_cms);
6192 }
6193 } else {
6194 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6195 }
6196
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006197 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6198 * tells the MS to handover to the new lchan. Here comes the new MS on
6199 * the new lchan with a Handover RACH: */
6200
6201 /* send handover detect */
6202
6203 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6204
6205 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6206
6207 /* send handover complete over the new channel */
6208
6209 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6210 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6211 enc_PDU_ML3_MS_NW(l3_tx)));
6212
6213 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Neels Hofmeyr2677b872022-04-12 01:44:43 +02006214 deactivate(as_media);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006215 setverdict(pass);
6216}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006217
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006218private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006219 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006220 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6221 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6222 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006223 }
6224 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006225 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006226 } else {
6227 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006228 }
6229 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006230 if (g_pars.expect_ho_fail) {
6231 f_perform_clear_no_lchan();
6232 } else {
6233 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6234 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006235 setverdict(pass);
6236}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006237function f_tc_ho_into_this_bsc_main(TestHdlrParams pars, charstring vty_a5_cfg := VTY_A5_DEFAULT) runs on test_CT {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006238 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006239
6240 f_init(1, true);
6241 f_sleep(1.0);
6242
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006243 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006244 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006245
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006246 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6247 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006248
6249 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6250 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006251
6252 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006253 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006254 if (pars.expect_ho_fail) {
6255 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6256 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6257 } else {
6258 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6259 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6260 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006261 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006262
6263 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006264}
6265
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006266testcase TC_ho_into_this_bsc() runs on test_CT {
6267 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6268 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006269 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006270}
6271
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006272function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6273 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006274 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006275 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006276 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006277 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006278 f_shutdown_helper();
6279}
6280
6281testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006282 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006283}
6284
6285testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006286 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006287}
6288
6289testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006290 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006291}
6292
6293testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006294 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006295}
6296
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006297/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6298 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6299 *
6300 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6301 * omitted.
6302 *
6303 * Related: SYS#5839
6304 */
6305testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6306 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6307}
6308
6309testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6310 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6311}
6312
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006313/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6314testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6315 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6316 expect_fail := true); // 0x18 = A5/3 and A5/4
6317}
6318
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006319testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6320 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6321 pars.host_aoip_tla := "::6";
6322 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006323 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006324}
6325
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006326/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006327 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006328 channel is later released (RR CHannel Release), should trigger inclusion of
6329 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6330 neighbors. */
6331testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6332 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6333 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006334 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006335 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006336
6337 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6338 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6339 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006340 f_shutdown_helper();
6341}
6342
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006343/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6344testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6345 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6346 pars.encr := f_encr_params('08'O); /* only A5/3 */
6347 pars.last_used_eutran_plmn := '323454'O;
6348 pars.exp_fast_return := true;
6349 f_tc_ho_into_this_bsc_main(pars);
6350
6351 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6352 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6353 f_ctrs_bsc_and_bts_verify();
6354 f_shutdown_helper();
6355}
6356
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006357/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6358 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6359 list when the channel is released. */
6360testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6361 f_init_vty();
6362 f_vty_allow_srvcc_fast_return(true, 0)
6363
6364 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6365 pars.last_used_eutran_plmn := '323454'O;
6366 pars.exp_fast_return := false;
6367 f_tc_ho_into_this_bsc_main(pars);
6368 f_vty_allow_srvcc_fast_return(false, 0);
6369 f_shutdown_helper();
6370}
6371
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006372/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6373testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6374 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6375 pars.last_used_eutran_plmn := '323454'O;
6376 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6377 f_tc_ho_into_this_bsc_main(pars);
6378
6379 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6380 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6381 f_ctrs_bsc_and_bts_verify();
6382 f_shutdown_helper();
6383}
6384
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006385private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6386 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6387 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6388 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6389 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6390 setverdict(pass);
6391}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006392
6393private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6394 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006395 var MSC_ConnHdlr vc_conn;
6396 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6397
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006398 f_init_vty();
6399 f_bts_0_cfg(BSCVTY,
6400 {"neighbor-list mode automatic",
6401 "handover 1",
6402 "handover algorithm 2",
6403 "handover2 window rxlev averaging 1",
6404 "no neighbors",
6405 "neighbor lac 99 arfcn 123 bsic any"});
6406 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6407
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006408 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006409 if (disable_fast_return) {
6410 f_vty_allow_srvcc_fast_return(true, 0);
6411 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006412 f_sleep(1.0);
6413
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006414 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006415
6416 pars.last_used_eutran_plmn := '323454'O;
6417 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6418 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6419
6420 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6421 vc_conn.done;
6422
6423 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6424 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6425 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6426 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6427 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6428 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006429
6430 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6431 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006432 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006433
6434 if (disable_fast_return) {
6435 f_vty_allow_srvcc_fast_return(false, 0);
6436 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006437 f_shutdown_helper();
6438}
6439
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006440/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6441 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6442 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6443 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6444testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6445 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6446}
6447/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6448 * independently of fast-reture allowed/forbidden in local BTS */
6449testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6450 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6451}
6452
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006453private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6454 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6455 f_rslem_register(0, new_chan_nr);
6456 g_chan_nr := new_chan_nr;
6457 f_sleep(1.0);
6458
6459 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6460 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6461 activate(as_Media());
6462
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006463 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006464 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006465 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006466
6467 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6468
6469 var PDU_BSSAP rx_bssap;
6470 var octetstring ho_command_str;
6471
6472 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6473
6474 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6475 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6476 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6477 log("L3 Info in HO Request Ack is ", ho_command);
6478
6479 var GsmArfcn arfcn;
6480 var RslChannelNr actual_new_chan_nr;
6481 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6482 actual_new_chan_nr, arfcn);
6483
6484 if (actual_new_chan_nr != new_chan_nr) {
6485 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6486 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6487 setverdict(fail);
6488 return;
6489 }
6490 log("Handover Command chan_nr is", actual_new_chan_nr);
6491
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006492 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6493 f_sleep(1.0);
6494
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006495 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6496 * tells the MS to handover to the new lchan. In this case, the MS
6497 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6498 * Handover Failure to the MSC. The procedure according to 3GPP TS
6499 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6500 * BSSMAP Clear Command: */
6501
6502 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6503 var BssmapCause cause := enum2int(cause_val);
6504 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6505
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006506 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006507 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006508 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006509
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006510 setverdict(pass);
6511 f_sleep(1.0);
6512
6513 setverdict(pass);
6514}
6515testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6516 var MSC_ConnHdlr vc_conn;
6517 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6518
6519 f_init(1, true);
6520 f_sleep(1.0);
6521
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006522 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006523
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006524 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6525 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006526
6527 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6528 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006529
6530 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6531 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6532 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6533 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6534 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006535 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006536}
6537
6538private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6539 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6540 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6541 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6542 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6543 * before we get started. */
6544 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6545 f_rslem_register(0, new_chan_nr);
6546 g_chan_nr := new_chan_nr;
6547 f_sleep(1.0);
6548
6549 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6550 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6551 activate(as_Media());
6552
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006553 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006554 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006555 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006556
6557 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6558
6559 var PDU_BSSAP rx_bssap;
6560 var octetstring ho_command_str;
6561
6562 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6563
6564 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6565 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6566 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6567 log("L3 Info in HO Request Ack is ", ho_command);
6568
6569 var GsmArfcn arfcn;
6570 var RslChannelNr actual_new_chan_nr;
6571 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6572 actual_new_chan_nr, arfcn);
6573
6574 if (actual_new_chan_nr != new_chan_nr) {
6575 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6576 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6577 setverdict(fail);
6578 return;
6579 }
6580 log("Handover Command chan_nr is", actual_new_chan_nr);
6581
6582 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6583 * tells the MS to handover to the new lchan. Here comes the new MS on
6584 * the new lchan with a Handover RACH: */
6585
6586 /* send handover detect */
6587
6588 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6589
6590 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6591
6592 /* The MSC chooses to clear the connection now, maybe we got the
6593 * Handover RACH on the new cell but the MS still signaled Handover
6594 * Failure to the old BSS? */
6595
6596 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6597 var BssmapCause cause := enum2int(cause_val);
6598 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6599
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006600 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006601 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006602 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006603
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006604 f_sleep(1.0);
6605}
6606testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6607 var MSC_ConnHdlr vc_conn;
6608 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6609
6610 f_init(1, true);
6611 f_sleep(1.0);
6612
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006613 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006614
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006615 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6616 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006617
6618 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6619 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006620
6621 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6622 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6623 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6624 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6625 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006626 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006627}
6628
6629/* The new BSS's lchan times out before the MSC decides that handover failed. */
6630private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6631 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6632 f_rslem_register(0, new_chan_nr);
6633 g_chan_nr := new_chan_nr;
6634 f_sleep(1.0);
6635
6636 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6637 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006638 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006639
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006640 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006641 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006642 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006643
6644 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6645
6646 var PDU_BSSAP rx_bssap;
6647 var octetstring ho_command_str;
6648
6649 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6650
6651 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6652 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6653 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6654 log("L3 Info in HO Request Ack is ", ho_command);
6655
6656 var GsmArfcn arfcn;
6657 var RslChannelNr actual_new_chan_nr;
6658 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6659 actual_new_chan_nr, arfcn);
6660
6661 if (actual_new_chan_nr != new_chan_nr) {
6662 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6663 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6664 setverdict(fail);
6665 return;
6666 }
6667 log("Handover Command chan_nr is", actual_new_chan_nr);
6668
6669 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6670 * tells the MS to handover to the new lchan. But the MS never shows up
6671 * on the new lchan. */
6672
6673 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6674
6675 /* Did osmo-bsc also send a Clear Request? */
6676 timer T := 0.5;
6677 T.start;
6678 alt {
6679 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6680 [] T.timeout { }
6681 }
6682
6683 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6684 * asked for it, this is a Handover Failure after all). */
6685
6686 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6687 var BssmapCause cause := enum2int(cause_val);
6688 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6689
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006690 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006691 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006692 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006693
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006694 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006695}
6696testcase TC_ho_in_fail_no_detect() runs on test_CT {
6697 var MSC_ConnHdlr vc_conn;
6698 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6699
6700 f_init(1, true);
6701 f_sleep(1.0);
6702
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006703 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006704
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006705 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6706 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006707
6708 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6709 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006710
6711 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6712 f_ctrs_bsc_and_bts_add(0, "handover:error");
6713 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6714 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6715 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006716 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006717}
6718
6719/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6720private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6721 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6722 f_rslem_register(0, new_chan_nr);
6723 g_chan_nr := new_chan_nr;
6724 f_sleep(1.0);
6725
6726 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6727 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr9b320c12022-04-07 00:19:01 +02006728 activate(as_Media(fail_on_dlcx := false));
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006729
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006730 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006731 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006732 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006733
6734 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6735
6736 var PDU_BSSAP rx_bssap;
6737 var octetstring ho_command_str;
6738
6739 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6740
6741 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6742 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6743 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6744 log("L3 Info in HO Request Ack is ", ho_command);
6745
6746 var GsmArfcn arfcn;
6747 var RslChannelNr actual_new_chan_nr;
6748 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6749 actual_new_chan_nr, arfcn);
6750
6751 if (actual_new_chan_nr != new_chan_nr) {
6752 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6753 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6754 setverdict(fail);
6755 return;
6756 }
6757 log("Handover Command chan_nr is", actual_new_chan_nr);
6758
6759 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6760 * tells the MS to handover to the new lchan. But the MS never shows up
6761 * on the new lchan. */
6762
6763 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6764
6765 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006766 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006767
6768 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006769 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6770 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6771 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006772 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006773 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006774 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006775
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006776 f_sleep(1.0);
6777}
6778testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6779 var MSC_ConnHdlr vc_conn;
6780 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6781
6782 f_init(1, true);
6783 f_sleep(1.0);
6784
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006785 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006786
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006787 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6788 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006789
6790 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6791 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006792
6793 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6794 f_ctrs_bsc_and_bts_add(0, "handover:error");
6795 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6796 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6797 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006798 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006799}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006800
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006801/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6802 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6803 * empty N-Connect case. */
6804testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6805 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6806 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6807 f_tc_ho_into_this_bsc_main(pars);
6808 f_shutdown_helper();
6809}
6810
Neels Hofmeyr91401012019-07-11 00:42:35 +02006811type record of charstring Commands;
6812
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006813private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006814{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006815 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006816 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006817 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006818 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006819 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006820}
6821
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006822private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6823{
6824 f_vty_enter_cfg_cs7_inst(pt, 0);
6825 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6826 f_vty_transceive(pt, cmds[i]);
6827 }
6828 f_vty_transceive(pt, "end");
6829}
6830
Neels Hofmeyr91401012019-07-11 00:42:35 +02006831private function f_probe_for_handover(charstring log_label,
6832 charstring log_descr,
6833 charstring handover_vty_cmd,
6834 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006835 boolean is_inter_bsc_handover := false,
6836 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006837runs on MSC_ConnHdlr
6838{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006839 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6840 * lchans to be established on bts 1 or bts 2. */
6841 f_rslem_suspend(RSL1_PROC);
6842 f_rslem_suspend(RSL2_PROC);
6843
Neels Hofmeyr91401012019-07-11 00:42:35 +02006844 var RSL_Message rsl;
6845
6846 var charstring log_msg := " (expecting handover)"
6847 if (not expect_handover) {
6848 log_msg := " (expecting NO handover)";
6849 }
6850 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6851 f_vty_transceive(BSCVTY, handover_vty_cmd);
6852
Neels Hofmeyr91401012019-07-11 00:42:35 +02006853 timer T := 2.0;
6854 T.start;
6855
6856 alt {
6857 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6858 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6859 log("Rx L3 from net: ", l3);
6860 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6861 var RslChannelNr new_chan_nr;
6862 var GsmArfcn arfcn;
6863 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6864 new_chan_nr, arfcn);
6865 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6866 log(l3.msgs.rrm.handoverCommand);
6867
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006868 /* Verify correct TSC in handoverCommand */
6869 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6870 if (not match(got_tsc, expect_target_tsc)) {
6871 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6872 expect_target_tsc, " got ", got_tsc);
6873 mtc.stop;
6874 } else {
6875 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6876 expect_target_tsc, ")");
6877 }
6878
Neels Hofmeyr91401012019-07-11 00:42:35 +02006879 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6880 * matter on which BTS it really is, we're not going to follow through an entire handover
6881 * anyway. */
6882 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6883 f_rslem_resume(RSL1_PROC);
6884 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6885 f_rslem_resume(RSL2_PROC);
6886
6887 if (expect_handover and not is_inter_bsc_handover) {
6888 setverdict(pass);
6889 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6890 } else {
6891 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6892 & log_label & ": " & log_descr);
6893 }
6894
6895 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6896 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6897 * Handover Failure. */
6898 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6899
6900 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6901 f_sleep(0.5);
6902 RSL1.clear;
6903 RSL2.clear;
6904 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6905 break;
6906 } else {
6907 repeat;
6908 }
6909 }
6910 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6911 if (expect_handover and is_inter_bsc_handover) {
6912 setverdict(pass);
6913 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6914 } else {
6915 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6916 & log_label & ": " & log_descr);
6917 }
6918
6919 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6920
6921 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6922 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6923 * setting a short timeout and waiting is the only way. */
6924 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6925 f_sleep(1.5);
6926 log("f_probe_for_handover(" & log_label & "): ...done");
6927
6928 break;
6929 }
6930 [] T.timeout {
6931 if (expect_handover) {
6932 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6933 & log_label & ": " & log_descr);
6934 } else {
6935 setverdict(pass);
6936 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6937 }
6938 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6939 break;
6940 }
6941 }
6942
6943 f_rslem_resume(RSL1_PROC);
6944 f_rslem_resume(RSL2_PROC);
6945 f_sleep(3.0);
6946 RSL.clear;
6947
6948 log("f_probe_for_handover(" & log_label & "): done clearing");
6949}
6950
6951/* Test the effect of various neighbor configuration scenarios:
6952 *
6953 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6954 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6955 */
6956private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6957 g_pars := f_gen_test_hdlr_pars();
6958 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6959 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006960
6961 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6962 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6963
6964 /* Establish lchan at bts 0 */
6965 f_establish_fully(ass_cmd, exp_compl);
6966
6967 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6968 f_vty_enter_cfg_network(BSCVTY);
6969 f_vty_transceive(BSCVTY, "timer T7 1");
6970 f_vty_transceive(BSCVTY, "end");
6971}
6972
6973private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6974 f_tc_ho_neighbor_config_start();
6975
6976 /*
6977 * bts 0 ARFCN 871 BSIC 10
6978 * bts 1 ARFCN 871 BSIC 11
6979 * bts 2 ARFCN 871 BSIC 12
6980 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6981 */
6982
6983 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006984 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006985 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6986 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006987 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006988
6989 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6990 "handover any to arfcn 13 bsic 39",
6991 false);
6992
6993 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6994 "handover any to arfcn 871 bsic 12",
6995 false);
6996
6997 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6998 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006999 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007000
7001 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007002}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007003testcase TC_ho_neighbor_config_1() runs on test_CT {
7004 var MSC_ConnHdlr vc_conn;
7005 f_init(3, true, guard_timeout := 60.0);
7006 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007007 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007008 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
7009 vc_conn.done;
7010
7011 /* f_tc_ho_neighbor_config_start() */
7012 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7013 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7014
7015 /* 1.a */
7016 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7017 * handover quickly by sending a Handover Failure message. */
7018 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7019 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7020 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7021 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007022 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7023 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007024
7025 /* 1.b */
7026 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7027 f_ctrs_bsc_and_bts_add(0, "handover:error");
7028
7029 /* 1.c */
7030 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7031 f_ctrs_bsc_and_bts_add(0, "handover:error");
7032
7033 /* 1.d */
7034 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7035 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7036 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7037 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007038 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7039 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007040
7041 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007042 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007043}
7044
Neels Hofmeyr91401012019-07-11 00:42:35 +02007045private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
7046 f_tc_ho_neighbor_config_start();
7047
7048 /*
7049 * bts 0 ARFCN 871 BSIC 10
7050 * bts 1 ARFCN 871 BSIC 11
7051 * bts 2 ARFCN 871 BSIC 12
7052 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7053 */
7054
7055 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007056 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007057 f_sleep(0.5);
7058
7059 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7060 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007061 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007062
7063 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7064 "handover any to arfcn 871 bsic 12",
7065 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007066 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007067}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007068testcase TC_ho_neighbor_config_2() runs on test_CT {
7069 var MSC_ConnHdlr vc_conn;
7070 f_init(3, true, guard_timeout := 50.0);
7071 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007072 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007073 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7074 vc_conn.done;
7075
7076 /* f_tc_ho_neighbor_config_start() */
7077 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7078 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7079
7080 /* 2.a */
7081 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7082 * handover quickly by sending a Handover Failure message. */
7083 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7084 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7085 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7086 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007087 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7088 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007089
7090 /* 2.b */
7091 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7092 f_ctrs_bsc_and_bts_add(0, "handover:error");
7093
7094 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007095 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007096}
7097
Neels Hofmeyr91401012019-07-11 00:42:35 +02007098private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7099 f_tc_ho_neighbor_config_start();
7100
7101 /*
7102 * bts 0 ARFCN 871 BSIC 10
7103 * bts 1 ARFCN 871 BSIC 11
7104 * bts 2 ARFCN 871 BSIC 12
7105 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7106 */
7107
7108 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007109 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007110 f_sleep(0.5);
7111
7112 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7113 "handover any to arfcn 871 bsic 11",
7114 false);
7115 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",
7116 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007117 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007118 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007119}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007120testcase TC_ho_neighbor_config_3() runs on test_CT {
7121 var MSC_ConnHdlr vc_conn;
7122 f_init(3, true, guard_timeout := 50.0);
7123 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007124 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007125 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7126 vc_conn.done;
7127
7128 /* f_tc_ho_neighbor_config_start() */
7129 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7130 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7131
7132 /* 3.a */
7133 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7134 f_ctrs_bsc_and_bts_add(0, "handover:error");
7135
7136 /* 3.b */
7137 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7138 * handover quickly by sending a Handover Failure message. */
7139 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7140 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7141 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7142 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007143 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7144 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007145
7146 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007147 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007148}
7149
Neels Hofmeyr91401012019-07-11 00:42:35 +02007150private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7151 f_tc_ho_neighbor_config_start();
7152
7153 /*
7154 * bts 0 ARFCN 871 BSIC 10
7155 * bts 1 ARFCN 871 BSIC 11
7156 * bts 2 ARFCN 871 BSIC 12
7157 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7158 */
7159
7160 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007161 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007162 f_sleep(0.5);
7163
7164 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7165 "handover any to arfcn 871 bsic 11",
7166 false);
7167 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7168 "handover any to arfcn 871 bsic 12",
7169 false);
7170 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7171 "handover any to arfcn 123 bsic 45",
7172 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007173 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007174}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007175testcase TC_ho_neighbor_config_4() runs on test_CT {
7176 var MSC_ConnHdlr vc_conn;
7177 f_init(3, true, guard_timeout := 50.0);
7178 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007179 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007180 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7181 vc_conn.done;
7182
7183 /* f_tc_ho_neighbor_config_start() */
7184 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7185 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7186
7187 /* 4.a */
7188 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7189 f_ctrs_bsc_and_bts_add(0, "handover:error");
7190
7191 /* 4.b */
7192 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7193 f_ctrs_bsc_and_bts_add(0, "handover:error");
7194
7195 /* 4.c */
7196 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7197 * handover quickly by timing out after the Handover Required message */
7198 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7199 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7200 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7201 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7202
7203 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007204 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007205}
7206
Neels Hofmeyr91401012019-07-11 00:42:35 +02007207private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7208 f_tc_ho_neighbor_config_start();
7209
7210 /*
7211 * bts 0 ARFCN 871 BSIC 10
7212 * bts 1 ARFCN 871 BSIC 11
7213 * bts 2 ARFCN 871 BSIC 12
7214 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7215 */
7216
7217 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 +02007218 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007219 f_sleep(0.5);
7220
7221 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7222 "handover any to arfcn 871 bsic 12",
7223 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007224 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007225}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007226testcase TC_ho_neighbor_config_5() runs on test_CT {
7227 var MSC_ConnHdlr vc_conn;
7228 f_init(3, true);
7229 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007230 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007231 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7232 vc_conn.done;
7233
7234 /* f_tc_ho_neighbor_config_start() */
7235 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7236 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7237
7238 /* 5 */
7239 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7240 * handover quickly by timing out after the Handover Required message */
7241 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7242 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7243 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7244 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7245
7246 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007247 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007248}
7249
Neels Hofmeyr91401012019-07-11 00:42:35 +02007250private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7251 f_tc_ho_neighbor_config_start();
7252
7253 /*
7254 * bts 0 ARFCN 871 BSIC 10
7255 * bts 1 ARFCN 871 BSIC 11
7256 * bts 2 ARFCN 871 BSIC 12
7257 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7258 */
7259
7260 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7261 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007262 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007263 f_sleep(0.5);
7264
7265 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7266 "handover any to arfcn 871 bsic 12",
7267 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007268 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007269}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007270testcase TC_ho_neighbor_config_6() runs on test_CT {
7271 var MSC_ConnHdlr vc_conn;
7272 f_init(3, true);
7273 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007274 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007275 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7276 vc_conn.done;
7277
7278 /* f_tc_ho_neighbor_config_start() */
7279 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7280 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7281
7282 /* 6.a */
7283 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7284 * handover quickly by timing out after the Handover Required message */
7285 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7286 f_ctrs_bsc_and_bts_add(0, "handover:error");
7287
7288 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007289 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007290}
7291
Neels Hofmeyr91401012019-07-11 00:42:35 +02007292private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7293 f_tc_ho_neighbor_config_start();
7294
7295 /*
7296 * bts 0 ARFCN 871 BSIC 10
7297 * bts 1 ARFCN 871 BSIC 11
7298 * bts 2 ARFCN 871 BSIC 12
7299 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7300 */
7301
7302 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7303 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007304 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007305 f_sleep(0.5);
7306
7307 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7308 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007309 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007310 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7311 "handover any to arfcn 123 bsic 45",
7312 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007313 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007314}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007315testcase TC_ho_neighbor_config_7() runs on test_CT {
7316 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007317 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007318 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007319 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007320 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7321 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007322
7323 /* f_tc_ho_neighbor_config_start() */
7324 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7325 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7326
7327 /* 7.a */
7328 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7329 * handover quickly by sending a Handover Failure message. */
7330 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7331 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7332 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7333 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007334 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7335 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007336
7337 /* 7.b */
7338 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7339 * handover quickly by timing out after the Handover Required message */
7340 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7341 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7342 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7343 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7344
7345 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007346 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007347}
7348
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007349/* OS#3041: Open and close N connections in a normal fashion, and expect no
7350 * BSSMAP Reset just because of that. */
7351testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7352 var default d;
7353 var integer i;
7354 var DchanTuple dt;
7355
7356 f_init();
7357
7358 /* Wait for initial BSSMAP Reset to pass */
7359 f_sleep(4.0);
7360
7361 d := activate(no_bssmap_reset());
7362
7363 /* Setup up a number of connections and RLSD them again from the MSC
7364 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7365 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007366 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007367 /* Since we're doing a lot of runs, give each one a fresh
7368 * T_guard from the top. */
7369 T_guard.start;
7370
7371 /* Setup a BSSAP connection and clear it right away. This is
7372 * the MSC telling the BSC about a planned release, it's not an
7373 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007374 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007375
7376 /* MSC disconnects (RLSD). */
7377 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7378 }
7379
7380 /* In the buggy behavior, a timeout of 2 seconds happens between above
7381 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7382 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7383 f_sleep(4.0);
7384
7385 deactivate(d);
7386 f_shutdown_helper();
7387}
Harald Welte552620d2017-12-16 23:21:36 +01007388
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007389/* OS#3041: Open and close N connections in a normal fashion, and expect no
7390 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7391 * the MSC. */
7392testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7393 var default d;
7394 var integer i;
7395 var DchanTuple dt;
7396 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007397 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7398 var BssmapCause cause := enum2int(cause_val);
7399
7400 f_init();
7401
7402 /* Wait for initial BSSMAP Reset to pass */
7403 f_sleep(4.0);
7404
7405 d := activate(no_bssmap_reset());
7406
7407 /* Setup up a number of connections and RLSD them again from the MSC
7408 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7409 * Let's do it some more times for good measure. */
7410 for (i := 0; i < 8; i := i+1) {
7411 /* Since we're doing a lot of runs, give each one a fresh
7412 * T_guard from the top. */
7413 T_guard.start;
7414
7415 /* Setup a BSSAP connection and clear it right away. This is
7416 * the MSC telling the BSC about a planned release, it's not an
7417 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007418 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007419
7420 /* Instruct BSC to clear channel */
7421 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7422
7423 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007424 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007425 }
7426
7427 /* In the buggy behavior, a timeout of 2 seconds happens between above
7428 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7429 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7430 f_sleep(4.0);
7431
7432 deactivate(d);
7433 f_shutdown_helper();
7434}
7435
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007436/* OS#3041: Open and close N connections in a normal fashion, and expect no
7437 * BSSMAP Reset just because of that. Close connections from the MS side with a
7438 * Release Ind on RSL. */
7439testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7440 var default d;
7441 var integer i;
7442 var DchanTuple dt;
7443 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007444 var integer j;
7445
7446 f_init();
7447
7448 /* Wait for initial BSSMAP Reset to pass */
7449 f_sleep(4.0);
7450
7451 d := activate(no_bssmap_reset());
7452
7453 /* Setup up a number of connections and RLSD them again from the MSC
7454 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7455 * Let's do it some more times for good measure. */
7456 for (i := 0; i < 8; i := i+1) {
7457 /* Since we're doing a lot of runs, give each one a fresh
7458 * T_guard from the top. */
7459 T_guard.start;
7460
7461 /* Setup a BSSAP connection and clear it right away. This is
7462 * the MSC telling the BSC about a planned release, it's not an
7463 * erratic loss of a connection. */
7464 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7465
7466 /* simulate RLL REL IND */
7467 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
7468
7469 /* expect Clear Request on MSC side */
7470 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7471
7472 /* Instruct BSC to clear channel */
7473 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7474 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7475
7476 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007477 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007478 }
7479
7480 /* In the buggy behavior, a timeout of 2 seconds happens between above
7481 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7482 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7483 f_sleep(4.0);
7484
7485 deactivate(d);
7486 f_shutdown_helper();
7487}
7488
Harald Welte94e0c342018-04-07 11:33:23 +02007489/***********************************************************************
7490 * IPA style dynamic PDCH
7491 ***********************************************************************/
7492
7493private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7494 template (omit) RSL_Cause nack := omit)
7495runs on test_CT {
7496 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7497 var RSL_Message rsl_unused;
7498 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7499 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7500 /* expect the BSC to issue the related RSL command */
7501 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7502 if (istemplatekind(nack, "omit")) {
7503 /* respond with a related acknowledgement */
7504 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7505 } else {
7506 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7507 }
7508}
7509
7510private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7511 template (omit) RSL_Cause nack := omit)
7512runs on test_CT {
7513 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7514 var RSL_Message rsl_unused;
7515 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7516 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7517 /* expect the BSC to issue the related RSL command */
7518 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7519 if (istemplatekind(nack, "omit")) {
7520 /* respond with a related acknowledgement */
7521 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7522 } else {
7523 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7524 }
7525}
7526
7527private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7528runs on test_CT return charstring {
7529 var charstring cmd, resp;
7530 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007531 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007532}
7533
7534private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7535 template charstring exp)
7536runs on test_CT {
7537 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7538 if (not match(mode, exp)) {
7539 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007540 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007541 }
7542}
7543
7544private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7545runs on test_CT {
7546 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7547 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7548 f_vty_transceive(BSCVTY, "end");
7549}
7550
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007551
7552private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7553 var integer i;
7554 for (i := 0; i < 8; i := i + 1) {
7555 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7556 }
7557}
7558
Harald Welte94e0c342018-04-07 11:33:23 +02007559private const charstring TCHF_MODE := "TCH/F mode";
7560private const charstring TCHH_MODE := "TCH/H mode";
7561private const charstring PDCH_MODE := "PDCH mode";
7562private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007563private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007564
7565/* Test IPA PDCH activation / deactivation triggered by VTY */
7566testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7567 var RSL_Message rsl_unused;
7568
7569 /* change Timeslot 6 before f_init() starts RSL */
7570 f_init_vty();
7571 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7572 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7573
7574 f_init(1, false);
7575 f_sleep(1.0);
7576
7577 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7578
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007579 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007580 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7581 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7582 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7583 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7584 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007585 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007586 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7587
7588 /* De-activate it via VTY */
7589 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7590 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007591 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007592 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7593
7594 /* re-activate it via VTY */
7595 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7596 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007597 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007598 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7599
7600 /* and finally de-activate it again */
7601 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7602 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007603 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007604 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7605
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007606 /* clean up config */
7607 f_ts_set_chcomb(0, 0, 6, "PDCH");
7608
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007609 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007610}
7611
7612/* Test IPA PDCH activation NACK */
7613testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7614 var RSL_Message rsl_unused;
7615
7616 /* change Timeslot 6 before f_init() starts RSL */
7617 f_init_vty();
7618 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7619 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7620
7621 f_init(1, false);
7622 f_sleep(1.0);
7623
7624 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7625
7626 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7627 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7628 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7629 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7630 f_sleep(1.0);
7631 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7632
7633 /* De-activate it via VTY */
7634 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7635 f_sleep(1.0);
7636 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7637
7638 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7639 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7640 f_sleep(1.0);
7641 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7642
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007643 /* clean up config */
7644 f_ts_set_chcomb(0, 0, 6, "PDCH");
7645
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007646 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007647}
7648
7649
7650/***********************************************************************
7651 * Osmocom style dynamic PDCH
7652 ***********************************************************************/
7653
7654private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7655 template (omit) RSL_Cause nack := omit)
7656runs on test_CT {
7657 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7658 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007659 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007660 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7661 /* expect the BSC to issue the related RSL command */
7662 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7663 if (istemplatekind(nack, "omit")) {
7664 /* respond with a related acknowledgement */
7665 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7666 } else {
7667 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7668 }
7669}
7670
7671private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7672 template (omit) RSL_Cause nack := omit)
7673runs on test_CT {
7674 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7675 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007676 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007677 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7678 /* expect the BSC to issue the related RSL command */
7679 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7680 if (istemplatekind(nack, "omit")) {
7681 /* respond with a related acknowledgement */
7682 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7683 } else {
7684 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7685 }
7686}
7687
7688/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7689testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7690 var RSL_Message rsl_unused;
7691
7692 /* change Timeslot 6 before f_init() starts RSL */
7693 f_init_vty();
7694 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7695 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7696
7697 f_init(1, false);
7698 f_sleep(1.0);
7699
7700 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7701
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007702 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007703 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7704 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007705 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007706
7707 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7708 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007709 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 +02007710 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7711
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007712 /* clean up config */
7713 f_ts_set_chcomb(0, 0, 6, "PDCH");
7714
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007715 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007716}
7717
7718/* Test Osmocom dyn PDCH activation NACK behavior */
7719testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7720 var RSL_Message rsl_unused;
7721
7722 /* change Timeslot 6 before f_init() starts RSL */
7723 f_init_vty();
7724 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7725 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7726
7727 f_init(1, false);
7728 f_sleep(1.0);
7729
7730 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7731
7732 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7733 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007734 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007735
7736 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7737 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7738 f_sleep(1.0);
7739 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7740
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007741 /* clean up config */
7742 f_ts_set_chcomb(0, 0, 6, "PDCH");
7743
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007744 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007745}
7746
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007747/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7748testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7749 var RSL_Message rsl_unused, rsl_msg;
7750 var DchanTuple dt;
7751 var BSSAP_N_CONNECT_ind rx_c_ind;
7752
7753 /* change Timeslot 6 before f_init() starts RSL */
7754 f_init_vty();
7755 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7756 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7757
7758 f_init(1, false);
7759 f_sleep(1.0);
7760
7761 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7762
7763 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7764 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7765 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007766 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007767
7768 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7769 f_sleep(1.0);
7770 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7771 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7772
7773 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7774 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007775 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007776 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007777 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007778 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007779 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007780 }
7781
7782 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7783 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7784 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7785 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7786
7787 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7788 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7789
7790 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7791 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7792 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7793 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7794
7795 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7796 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7797 dt.sccp_conn_id := rx_c_ind.connectionId;
7798 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7799
7800 /* Instruct BSC to clear channel */
7801 var BssmapCause cause := 0;
7802 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7803 f_exp_chan_rel_and_clear(dt, 0);
7804
7805 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007806 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007807 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7808 f_sleep(1.0);
7809 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7810
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007811 /* Clean up SDCCH lchans */
7812 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7813 f_perform_clear_test_ct(sdcch_cleanup[i]);
7814 }
7815
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007816 /* clean up config */
7817 f_ts_set_chcomb(0, 0, 6, "PDCH");
7818
7819 f_shutdown_helper();
7820}
7821
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007822/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7823testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7824 var ASP_RSL_Unitdata rsl_ud;
7825 var integer i;
7826 var integer chreq_total, chreq_nochan;
7827
7828 f_init_vty();
7829 for (i := 1; i < 8; i := i + 1) {
7830 if (i == 2) {
7831 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7832 } else {
7833 f_ts_set_chcomb(0, 0, i, "PDCH");
7834 }
7835 }
7836 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7837
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007838 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007839
7840 /* The dyn TS want to activate PDCH mode, ACK that. */
7841 var RslChannelNr chan_nr;
7842 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007843 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007844 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7845
7846 f_sleep(1.0);
7847
7848 /* Exhaust all dedicated SDCCH lchans.
7849 /* GSM 44.018 Table 9.1.8.2:
7850 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7851 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007852 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007853 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007854 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007855 }
7856
7857 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007858 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007859 /* Also occupy the seven other SDCCH of the dyn TS */
7860 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007861 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
7862 }
7863
7864 /* Clean up SDCCH lchans */
7865 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7866 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007867 }
7868
7869 /* clean up config */
7870 f_ts_reset_chcomb(0);
7871
7872 f_shutdown_helper();
7873}
7874
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007875/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7876 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7877 it as TCH directly instead. SYS#5309. */
7878testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7879 var RSL_Message rsl_unused, rsl_msg;
7880 var DchanTuple dt;
7881 var BSSAP_N_CONNECT_ind rx_c_ind;
7882 var integer i;
7883
7884 /* change Timeslot 6 before f_init() starts RSL */
7885 f_init_vty();
7886 for (i := 1; i < 8; i := i + 1) {
7887 if (i == 6) {
7888 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7889 } else {
7890 f_ts_set_chcomb(0, 0, i, "PDCH");
7891 }
7892 }
7893 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7894
7895 f_init(1, false);
7896 f_sleep(1.0);
7897
7898 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7899
7900 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7901 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7902 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007903 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007904
7905 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7906 f_sleep(1.0);
7907 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7908 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7909
7910 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7911 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007912 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007913 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007914 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007915 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007916 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007917 }
7918
7919 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007920 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007921 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7922 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7923
7924 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7925 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7926
7927 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7928 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7929 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7930 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7931
7932 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7933 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7934 dt.sccp_conn_id := rx_c_ind.connectionId;
7935 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7936
7937 /* Instruct BSC to clear channel */
7938 var BssmapCause cause := 0;
7939 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7940 f_exp_chan_rel_and_clear(dt, 0);
7941
7942 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007943 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007944 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7945 f_sleep(1.0);
7946 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7947
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007948 /* Clean up SDCCH lchans */
7949 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7950 f_perform_clear_test_ct(chan_cleanup[i]);
7951 }
7952
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007953 /* clean up config */
7954 f_ts_reset_chcomb(0);
7955 /* TODO: clean up other channels? */
7956
7957 f_shutdown_helper();
7958}
7959
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007960/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7961testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7962 var RSL_Message rsl_unused, rsl_msg;
7963 var DchanTuple dt;
7964 var BSSAP_N_CONNECT_ind rx_c_ind;
7965 var GsmRrMessage rr;
7966
7967 /* change Timeslot 6 before f_init() starts RSL */
7968 f_init_vty();
7969 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7970 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7971
7972 f_init(1, false);
7973 f_sleep(1.0);
7974
7975 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7976
7977 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7978 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7979 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007980 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007981
7982 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7983 f_sleep(1.0);
7984 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7985 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7986
7987 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7988 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007989 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007990 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007991 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007992 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007993 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007994 }
7995
7996 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7997 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7998 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7999 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
8000
8001 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8002 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
8003
8004 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
8005 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
8006 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
8007 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
8008 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
8009 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
8010 }
8011
8012 /* FIXME? Currently the TS stays in state BORKEN: */
8013
8014 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06008015 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008016 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
8017 * f_sleep(1.0);
8018 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
8019 */
8020
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008021 /* Clean up SDCCH lchans */
8022 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
8023 f_perform_clear_test_ct(chan_cleanup[i]);
8024 }
8025
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02008026 /* clean up config */
8027 f_ts_set_chcomb(0, 0, 6, "PDCH");
8028
8029 f_shutdown_helper();
8030}
8031
Stefan Sperling0796a822018-10-05 13:01:39 +02008032testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02008033 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02008034 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8035 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8036 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008037 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02008038}
8039
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008040testcase TC_chopped_ipa_payload() runs on test_CT {
8041 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
8042 /* TODO: mp_bsc_ctrl_port does not work yet */};
8043 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
8044 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
8045 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008046 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008047}
8048
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008049/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
8050 the BTS does autonomous MS power control loop */
8051testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
8052 var MSC_ConnHdlr vc_conn;
8053 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8054 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
8055 pars.exp_ms_power_params := true;
8056
8057 f_init(1, true);
8058 f_sleep(1.0);
8059 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8060 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008061 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008062}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008063
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008064/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8065testcase TC_c0_power_red_mode() runs on test_CT {
8066 f_init(1);
8067
8068 for (var integer red := 6; red >= 0; red := red - 2) {
8069 /* Configure BCCH carrier power reduction mode via the VTY */
8070 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8071
8072 /* Expect Osmocom specific BS Power Control message on the RSL */
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +03008073 var template (present) RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008074 chan_nr := t_RslChanNr_BCCH(0),
8075 bs_power := tr_RSL_IE_BS_Power(red / 2));
8076 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
8077 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
8078
8079 /* Additionally verify the applied value over the CTRL interface */
8080 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8081 if (cred != int2str(red)) {
8082 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8083 cred, " (expected ", red, ")");
8084 }
8085 }
8086
8087 f_shutdown_helper();
8088}
8089
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008090/***********************************************************************
8091 * MSC Pooling
8092 ***********************************************************************/
8093
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008094template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008095 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 +02008096
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008097private 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 +02008098runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008099 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008100 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008101 f_logp(BSCVTY, "Got RSL RR Release");
8102 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008103 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008104 f_logp(BSCVTY, "Got RSL Deact SACCH");
8105 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008106 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008107 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008108 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8109 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008110 break;
8111 }
8112 }
8113}
8114
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008115private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8116 var MgcpCommand mgcp_cmd;
8117 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8118 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8119 repeat;
8120 }
8121}
8122
8123private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8124 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8125 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8126 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8127 repeat;
8128 }
8129}
8130
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008131friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8132 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008133runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008134 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8135 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008136 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008137 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8138 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008139 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008140 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008141 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008142 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008143 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008144 }
8145 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008146 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008147 /* Also drop the SCCP connection */
8148 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8149 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008150 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008151 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008152 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8153 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008154 }
8155 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008156 deactivate(ack_dlcx);
8157 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008158}
8159
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008160friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8161runs on MSC_ConnHdlr {
8162 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8163 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8164 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8165 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8166 interleave {
8167 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8168 f_logp(BSCVTY, "Got RSL Deact SACCH");
8169 }
8170 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8171 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8172 /* Also drop the SCCP connection */
8173 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8174 }
8175 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8176 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8177 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8178 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8179 }
8180 }
8181 deactivate(ack_dlcx);
8182 deactivate(ack_rel_req);
8183}
8184
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008185friend function f_perform_clear_no_lchan()
8186runs on MSC_ConnHdlr {
8187 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8188 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8189 BSSAP.receive(tr_BSSMAP_ClearComplete);
8190 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8191 /* Also drop the SCCP connection */
8192 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8193}
8194
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008195private function f_perform_clear_test_ct(DchanTuple dt)
8196 runs on test_CT
8197{
8198 /* Instruct BSC to clear channel */
8199 var BssmapCause cause := 0;
8200 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
8201 f_exp_chan_rel_and_clear(dt, 0);
8202}
8203
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008204private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8205 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008206runs on MSC_ConnHdlr {
8207 timer T := 10.0;
8208 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8209
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008210 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008211 f_create_bssmap_exp(l3_enc);
8212
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008213 /* RSL_Emulation.f_chan_est() on rsl_pt:
8214 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008215 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8216 */
8217 var RSL_Message rx_rsl;
8218 var GsmRrMessage rr;
8219
8220 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008221 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008222 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008223 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008224 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8225 */
8226 timer Tt := 10.0;
8227
8228 /* request a channel to be established */
8229 Tt.start;
8230 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008231 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008232 Tt.stop;
8233 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008234 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008235 setverdict(fail, "Unexpected RSL message on DCHAN");
8236 mtc.stop;
8237 }
8238 [] Tt.timeout {
8239 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8240 mtc.stop;
8241 }
8242 }
8243 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8244 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008245 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008246
8247
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008248 if (expect_bssmap_l3) {
8249 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8250 var template PDU_BSSAP exp_l3_compl;
8251 exp_l3_compl := tr_BSSMAP_ComplL3()
8252 if (g_pars.aoip == false) {
8253 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8254 } else {
8255 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8256 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008257
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008258 var PDU_BSSAP bssap;
8259 T.start;
8260 alt {
8261 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8262 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8263 log("rx exp_l3_compl = ", bssap);
8264 }
8265 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8266 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8267 }
8268 [] T.timeout {
8269 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8270 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008271 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008272
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008273 /* start ciphering, if requested */
8274 if (ispresent(g_pars.encr)) {
8275 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008276 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008277 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008278 }
8279
8280 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008281 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008282 }
8283 setverdict(pass);
8284 f_sleep(1.0);
8285}
8286
8287private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8288 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8289 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008290 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008291 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008292 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008293 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008294 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008295 }
8296}
8297
8298/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8299private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8300 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008301 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8302 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8303 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8304 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 +02008305}
8306testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8307
8308 f_init(1, true);
8309 f_sleep(1.0);
8310 var MSC_ConnHdlr vc_conn;
8311 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008312
8313 f_ctrs_msc_init();
8314
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008315 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8316 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008317
8318 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008319 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008320}
8321
8322/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8323/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8324 * just as well using only RSL. */
8325testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8326
8327 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8328 f_sleep(1.0);
8329
8330 /* Control which MSC gets chosen next by the round-robin, otherwise
8331 * would be randomly affected by which other tests ran before this. */
8332 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8333
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008334 f_ctrs_msc_init();
8335
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008336 var MSC_ConnHdlr vc_conn1;
8337 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8338 pars1.mscpool.rsl_idx := 0;
8339 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8340 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8341 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008342 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008343
8344 var MSC_ConnHdlr vc_conn2;
8345 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8346 pars2.mscpool.rsl_idx := 1;
8347 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8348 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8349 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008350 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008351
8352 /* Test round-robin wrap to the first MSC */
8353 var MSC_ConnHdlr vc_conn3;
8354 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8355 pars3.mscpool.rsl_idx := 2;
8356 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8357 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8358 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008359 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008360 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008361}
8362
8363/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8364 * (configured in osmo-bsc.cfg). */
8365/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8366 * just as well using only RSL. */
8367testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8368
8369 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8370 f_sleep(1.0);
8371
8372 /* Control which MSC gets chosen next by the round-robin, otherwise
8373 * would be randomly affected by which other tests ran before this. */
8374 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8375
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008376 f_ctrs_msc_init();
8377
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008378 var MSC_ConnHdlr vc_conn1;
8379 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8380 pars1.mscpool.rsl_idx := 0;
8381 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8382 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8383 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008384 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008385
8386 var MSC_ConnHdlr vc_conn2;
8387 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8388 pars2.mscpool.rsl_idx := 1;
8389 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8390 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8391 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008392 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008393
8394 /* Test round-robin wrap to the first MSC */
8395 var MSC_ConnHdlr vc_conn3;
8396 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8397 pars3.mscpool.rsl_idx := 2;
8398 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8399 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8400 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008401 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008402 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008403}
8404
8405/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8406 * (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
8407 * NULL-NRI setting is stronger than that. */
8408/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8409 * just as well using only RSL. */
8410testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8411
8412 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8413 f_sleep(1.0);
8414
8415 /* Control which MSC gets chosen next by the round-robin, otherwise
8416 * would be randomly affected by which other tests ran before this. */
8417 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8418
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008419 f_ctrs_msc_init();
8420
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008421 var MSC_ConnHdlr vc_conn1;
8422 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8423 pars1.mscpool.rsl_idx := 0;
8424 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8425 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8426 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008427 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008428
8429 var MSC_ConnHdlr vc_conn2;
8430 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8431 pars2.mscpool.rsl_idx := 1;
8432 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8433 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8434 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008435 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008436
8437 /* Test round-robin wrap to the first MSC */
8438 var MSC_ConnHdlr vc_conn3;
8439 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8440 pars3.mscpool.rsl_idx := 2;
8441 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8442 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8443 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008444 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008445 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008446}
8447
8448/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8449 * assigned to any MSC (configured in osmo-bsc.cfg). */
8450/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8451 * just as well using only RSL. */
8452testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8453
8454 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8455 f_sleep(1.0);
8456
8457 /* Control which MSC gets chosen next by the round-robin, otherwise
8458 * would be randomly affected by which other tests ran before this. */
8459 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8460
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008461 f_ctrs_msc_init();
8462
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008463 var MSC_ConnHdlr vc_conn1;
8464 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8465 pars1.mscpool.rsl_idx := 0;
8466 /* An NRI that is not assigned to any MSC */
8467 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8468 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8469 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008470 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008471
8472 var MSC_ConnHdlr vc_conn2;
8473 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8474 pars2.mscpool.rsl_idx := 1;
8475 /* An NRI that is not assigned to any MSC */
8476 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8477 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8478 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008479 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008480
8481 /* Test round-robin wrap to the first MSC */
8482 var MSC_ConnHdlr vc_conn3;
8483 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8484 pars3.mscpool.rsl_idx := 2;
8485 /* An NRI that is not assigned to any MSC */
8486 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8487 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8488 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008489 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008490 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008491}
8492
8493/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8494 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8495/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8496 * just as well using only RSL. */
8497testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8498
8499 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8500 f_sleep(1.0);
8501
8502 /* Control which MSC gets chosen next by the round-robin, otherwise
8503 * would be randomly affected by which other tests ran before this. */
8504 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8505
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008506 f_ctrs_msc_init();
8507
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008508 var MSC_ConnHdlr vc_conn1;
8509 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8510 pars1.mscpool.rsl_idx := 0;
8511 /* An NRI that is assigned to an unconnected MSC */
8512 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8513 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8514 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008515 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8516 f_ctrs_msc_add(0, "mscpool:subscr:new");
8517 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008518
8519 var MSC_ConnHdlr vc_conn2;
8520 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8521 pars2.mscpool.rsl_idx := 1;
8522 /* An NRI that is assigned to an unconnected MSC */
8523 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8524 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8525 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008526 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8527 f_ctrs_msc_add(1, "mscpool:subscr:new");
8528 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008529
8530 /* Test round-robin wrap to the first MSC */
8531 var MSC_ConnHdlr vc_conn3;
8532 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8533 pars3.mscpool.rsl_idx := 2;
8534 /* An NRI that is assigned to an unconnected MSC */
8535 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8536 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8537 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008538 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8539 f_ctrs_msc_add(0, "mscpool:subscr:new");
8540 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008541 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008542}
8543
8544/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8545 * osmo-bsc.cfg). */
8546/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8547 * just as well using only RSL. */
8548testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8549
8550 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8551 f_sleep(1.0);
8552
8553 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8554 * this is not using round-robin. */
8555 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8556
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008557 f_ctrs_msc_init();
8558
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008559 var MSC_ConnHdlr vc_conn1;
8560 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8561 pars1.mscpool.rsl_idx := 0;
8562 /* An NRI of the second MSC's range (256-511) */
8563 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8564 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8565 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008566 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008567
8568 var MSC_ConnHdlr vc_conn2;
8569 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8570 pars2.mscpool.rsl_idx := 1;
8571 /* An NRI of the second MSC's range (256-511) */
8572 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8573 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8574 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008575 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008576
8577 var MSC_ConnHdlr vc_conn3;
8578 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8579 pars3.mscpool.rsl_idx := 2;
8580 /* An NRI of the second MSC's range (256-511) */
8581 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8582 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8583 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008584 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008585 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008586}
8587
8588/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8589 * while a round-robin remains unaffected by that. */
8590/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8591 * just as well using only RSL. */
8592testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8593
8594 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8595 f_sleep(1.0);
8596
8597 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8598 * this is not using round-robin. */
8599 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8600
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008601 f_ctrs_msc_init();
8602
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008603 var MSC_ConnHdlr vc_conn1;
8604 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8605 pars1.mscpool.rsl_idx := 0;
8606 /* An NRI of the third MSC's range (512-767) */
8607 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8608 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8609 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008610 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008611
8612 var MSC_ConnHdlr vc_conn2;
8613 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8614 pars2.mscpool.rsl_idx := 1;
8615 /* An NRI of the third MSC's range (512-767) */
8616 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8617 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8618 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008619 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008620
8621 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8622 var MSC_ConnHdlr vc_conn3;
8623 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8624 pars3.mscpool.rsl_idx := 2;
8625 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8626 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8627 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008628 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008629 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008630}
8631
8632/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8633/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8634 * just as well using only RSL. */
8635testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8636
8637 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8638 f_sleep(1.0);
8639
8640 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8641 * instead, and hits msc 0. */
8642 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8643
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008644 f_ctrs_msc_init();
8645
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008646 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8647 var MSC_ConnHdlr vc_conn1;
8648 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8649 pars1.mscpool.rsl_idx := 0;
8650 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8651 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8652 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008653 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008654
8655 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8656 var MSC_ConnHdlr vc_conn2;
8657 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8658 pars2.mscpool.rsl_idx := 1;
8659 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8660 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8661 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008662 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008663 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008664}
8665
8666/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8667 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8668private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8669 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8670 //cid_list := { cIl_allInBSS := ''O };
8671 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8672 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8673 var BSSAP_N_UNITDATA_req paging;
8674 var hexstring imsi := '001010000000123'H;
8675
8676 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8677
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008678 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008679 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8680 BSSAP.send(paging);
8681
8682 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8683 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8684 * channel number is picked here. */
8685 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8686 f_rslem_register(0, new_chan_nr);
8687 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8688 f_rslem_unregister(0, new_chan_nr);
8689
8690 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8691 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008692 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008693 f_sleep(1.0);
8694}
8695testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8696 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8697 f_sleep(1.0);
8698
8699 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8700 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8701 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8702
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008703 f_ctrs_msc_init();
8704
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008705 var MSC_ConnHdlr vc_conn1;
8706 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8707 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008708 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8709 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008710 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8711 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008712 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008713 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008714}
8715
8716/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8717 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8718private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8719 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8720 //cid_list := { cIl_allInBSS := ''O };
8721 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8722 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8723 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008724 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008725 var BSSAP_N_UNITDATA_req paging;
8726
8727 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8728
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008729 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008730 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8731 BSSAP.send(paging);
8732
8733 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8734 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8735 * channel number is picked here. */
8736 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8737 f_rslem_register(0, new_chan_nr);
8738 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8739 f_rslem_unregister(0, new_chan_nr);
8740
8741 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8742 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8743 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008744 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 +02008745 f_sleep(1.0);
8746}
8747testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8748 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8749 f_sleep(1.0);
8750
8751 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8752 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8753 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8754
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008755 f_ctrs_msc_init();
8756
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008757 var MSC_ConnHdlr vc_conn1;
8758 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8759 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008760 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8761 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008762 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8763 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008764 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008765 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008766}
8767
8768/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8769/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8770 * just as well using only RSL. */
8771testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8772
8773 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8774 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008775 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8776 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008777
8778 /* Control which MSC gets chosen next by the round-robin, otherwise
8779 * would be randomly affected by which other tests ran before this. */
8780 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8781
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008782 f_ctrs_msc_init();
8783
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008784 var MSC_ConnHdlr vc_conn1;
8785 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8786 pars1.mscpool.rsl_idx := 0;
8787 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8788 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8789 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008790 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008791
8792 var MSC_ConnHdlr vc_conn2;
8793 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8794 pars2.mscpool.rsl_idx := 1;
8795 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8796 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8797 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008798 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008799
8800 var MSC_ConnHdlr vc_conn3;
8801 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8802 pars3.mscpool.rsl_idx := 2;
8803 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8804 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8805 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008806 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008807 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008808}
8809
8810/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8811 * TMSI NRI. */
8812testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8813
8814 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8815 f_sleep(1.0);
8816
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008817 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8818 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8819
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008820 /* Control which MSC gets chosen next by the round-robin, otherwise
8821 * would be randomly affected by which other tests ran before this. */
8822 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8823
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008824 f_ctrs_msc_init();
8825
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008826 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8827 var MSC_ConnHdlr vc_conn1;
8828 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8829 pars1.mscpool.rsl_idx := 0;
8830 /* An NRI of the second MSC's range (256-511) */
8831 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8832 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8833 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008834 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008835
8836 var MSC_ConnHdlr vc_conn2;
8837 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8838 pars2.mscpool.rsl_idx := 1;
8839 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8840 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8841 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008842 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008843
8844 var MSC_ConnHdlr vc_conn3;
8845 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8846 pars3.mscpool.rsl_idx := 2;
8847 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8848 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8849 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008850 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008851 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008852}
8853
Philipp Maier783681c2020-07-16 16:47:06 +02008854/* Allow/Deny emergency calls globally via VTY */
8855private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8856 f_vty_enter_cfg_msc(BSCVTY, 0);
8857 if (allow) {
8858 f_vty_transceive(BSCVTY, "allow-emergency allow");
8859 } else {
8860 f_vty_transceive(BSCVTY, "allow-emergency deny");
8861 }
8862 f_vty_transceive(BSCVTY, "exit");
8863 f_vty_transceive(BSCVTY, "exit");
8864}
8865
8866/* Allow/Deny emergency calls per BTS via VTY */
8867private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8868 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8869 if (allow) {
8870 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8871 } else {
8872 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8873 }
8874 f_vty_transceive(BSCVTY, "exit");
8875 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008876 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008877}
8878
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008879/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8880private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8881 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8882 if (allow) {
8883 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8884 } else {
8885 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8886 }
8887 f_vty_transceive(BSCVTY, "exit");
8888 f_vty_transceive(BSCVTY, "exit");
8889 f_vty_transceive(BSCVTY, "exit");
8890}
8891
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008892/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8893private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8894 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8895 if (allow) {
8896 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8897 } else {
8898 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8899 }
8900 f_vty_transceive(BSCVTY, "exit");
8901 f_vty_transceive(BSCVTY, "exit");
8902 f_vty_transceive(BSCVTY, "exit");
8903}
8904
Philipp Maier783681c2020-07-16 16:47:06 +02008905/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8906private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8907 var PDU_ML3_MS_NW emerg_setup;
8908 var octetstring emerg_setup_enc;
8909 var RSL_Message emerg_setup_data_ind;
8910
8911 f_establish_fully(omit, omit);
8912
8913 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8914 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8915 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8916
8917 RSL.send(emerg_setup_data_ind);
8918}
8919
8920/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8921 * CALLS are permitted by the BSC config. */
8922private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8923 var PDU_BSSAP emerg_setup_data_ind_bssap;
8924 var PDU_ML3_MS_NW emerg_setup;
8925 timer T := 3.0;
8926
8927 f_assignment_emerg_setup()
8928
8929 T.start;
8930 alt {
8931 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8932 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8933 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8934 setverdict(fail, "no emergency setup");
8935 }
8936 }
8937 [] BSSAP.receive {
8938 setverdict(fail, "unexpected BSSAP message!");
8939 }
8940 [] T.timeout {
8941 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8942 }
8943 }
8944
8945 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008946 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02008947}
8948
8949/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8950 * forbidden by the BSC config. */
8951private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8952 var PDU_BSSAP emerg_setup_data_ind_bssap;
8953 timer T := 3.0;
8954
8955 f_assignment_emerg_setup()
8956
8957 T.start;
8958 alt {
8959 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8960 setverdict(pass);
8961 }
8962 [] RSL.receive {
8963 setverdict(fail, "unexpected RSL message!");
8964 }
8965 [] T.timeout {
8966 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8967 }
8968 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008969 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008970 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02008971}
8972
8973/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8974testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8975 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8976 var MSC_ConnHdlr vc_conn;
8977
8978 f_init(1, true);
8979 f_sleep(1.0);
8980
8981 f_vty_allow_emerg_msc(true);
8982 f_vty_allow_emerg_bts(true, 0);
8983 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8984 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008985 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008986}
8987
8988/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8989testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8990 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8991 var MSC_ConnHdlr vc_conn;
8992
8993 f_init(1, true);
8994 f_sleep(1.0);
8995
8996 f_vty_allow_emerg_msc(false);
8997 f_vty_allow_emerg_bts(true, 0);
8998 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8999 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009000 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009001}
9002
9003/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
9004testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
9005 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9006 var MSC_ConnHdlr vc_conn;
9007
9008 /* Note: This simulates a spec violation by the MS, correct MS
9009 * implementations would not try to establish an emergency call because
9010 * the system information tells in advance that emergency calls are
9011 * not forbidden */
9012
9013 f_init(1, true);
9014 f_sleep(1.0);
9015
9016 f_vty_allow_emerg_msc(true);
9017 f_vty_allow_emerg_bts(false, 0);
9018 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
9019 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009020 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02009021}
9022
Philipp Maier82812002020-08-13 18:48:27 +02009023/* Test what happens when an emergency call arrives while all TCH channels are
9024 * busy, the BSC is expected to terminate one call in favor of the incoming
9025 * emergency call */
9026testcase TC_emerg_premption() runs on test_CT {
9027 var ASP_RSL_Unitdata rsl_ud;
9028 var integer i;
9029 var integer chreq_total, chreq_nochan;
9030 var RSL_Message rx_rsl;
Philipp Maier82812002020-08-13 18:48:27 +02009031
9032 f_init(1);
9033 f_sleep(1.0);
9034
9035 f_vty_allow_emerg_msc(true);
9036 f_vty_allow_emerg_bts(true, 0);
9037
9038 /* Fill up all channels on the BTS */
9039 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
9040 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
9041 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009042 f_chreq_act_ack('33'O, i);
Philipp Maier82812002020-08-13 18:48:27 +02009043 }
9044 IPA_RSL[0].clear;
9045 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
9046 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
9047
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009048 /* Send EST IND for the first TCH, so we get to test the RR release cause */
9049 var RslChannelNr first_tch := valueof(t_RslChanNr_Bm(1));
9050 var octetstring l3 := '00010203040506'O;
9051 f_ipa_tx(0, ts_RSL_EST_IND(first_tch, valueof(ts_RslLinkID_DCCH(0)), l3));
9052
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009053 /* Accept BSSAP conn, so we get to test the Clear Request cause */
9054 var BSSAP_N_CONNECT_ind rx_c_ind;
9055 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
9056 var integer sccp_conn_id := rx_c_ind.connectionId;
9057 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
9058
Philipp Maier82812002020-08-13 18:48:27 +02009059 /* Send Channel request for emegergency call */
9060 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
9061
9062 /* Expect the BSC to release one (the first) TCH/F on the BTS */
Neels Hofmeyrace698c2022-04-24 00:30:21 +02009063 f_expect_chan_rel(0, first_tch, expect_rr_chan_rel := true, expect_rll_rel_req := false,
9064 expect_rr_cause := GSM48_RR_CAUSE_PREMPTIVE_REL);
Philipp Maier82812002020-08-13 18:48:27 +02009065
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009066 /* Also expect a BSSMAP Clear Request with PREEMPTION */
9067 var BSSAP_N_DATA_ind rx_clear_req;
9068 const myBSSMAP_Cause preemption := GSM0808_CAUSE_PREEMPTION;
9069 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_clear_req;
9070 log("XXX ", rx_clear_req);
9071 if (rx_clear_req.userData.pdu.bssmap.clearRequest.cause.causeValue != int2bit(enum2int(preemption), 7)) {
9072 setverdict(fail, "BSSMAP Clear Request: expected cause PREEMPTION");
9073 }
9074
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009075 /* Expect the BSC to send activate/assign the channel for the emergency call */
Philipp Maier82812002020-08-13 18:48:27 +02009076 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr32ef5912022-04-24 00:29:04 +02009077 if (first_tch != rx_rsl.ies[0].body.chan_nr) {
9078 setverdict(fail, "different TCH lchan activated than expected");
9079 }
9080 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(first_tch, 33));
Philipp Maier82812002020-08-13 18:48:27 +02009081 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009082
Neels Hofmeyrde564b12022-04-24 23:11:46 +02009083 /* complete the BSSMAP Clear to satisfy the conn leak check */
9084 BSSAP.send(ts_BSSAP_DATA_req(sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(preemption))));
9085 BSSAP.receive(tr_BSSAP_DATA_ind(sccp_conn_id, tr_BSSMAP_ClearComplete)) {
9086 BSSAP.send(ts_BSSAP_DISC_req(sccp_conn_id, 0));
9087 }
9088
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009089 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009090}
9091
9092/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009093private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009094private type record FHParamsTs {
9095 boolean enabled,
9096 uint6_t hsn,
9097 uint6_t maio,
9098 ArfcnList ma
9099};
9100
9101/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009102private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009103 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009104 FHParamsTs ts[8]
9105};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009106
9107/* Randomly generate the hopping parameters for the given timeslot numbers */
9108private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9109runs on test_CT return FHParamsTrx {
9110 var FHParamsTrx fhp;
9111
Philipp Maier798d8952021-10-19 14:43:19 +02009112 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9113 * fall in the GSM900 band. */
9114 fhp.arfcn.arfcn := f_rnd_int(3);
9115 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009116
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009117 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9118 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009119 fhp.ts[tn].enabled := false;
9120 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009121 continue;
9122 }
9123
9124 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009125 fhp.ts[tn].hsn := f_rnd_int(64);
9126 fhp.ts[tn].maio := f_rnd_int(64);
9127 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009128
9129 /* Random Mobile Allocation (hopping channels) */
9130 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9131 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9132 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009133 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009134 }
9135
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009136 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009137 }
9138
9139 log("f_TC_fh_params_gen(): ", fhp);
9140 return fhp;
9141}
9142
9143/* Make sure that the given Channel Description IE matches the hopping configuration */
9144private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9145{
9146 var template (present) ChannelDescription tr_cd;
9147 var template (present) MaioHsn tr_maio_hsn;
9148 var uint3_t tn := cd.chan_nr.tn;
9149
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009150 if (fhp.ts[tn].enabled) {
9151 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009152 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9153 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009154 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009155 }
9156
9157 if (not match(cd, tr_cd)) {
9158 setverdict(fail, "Channel Description IE does not match: ",
9159 cd, " vs expected ", tr_cd);
9160 }
9161}
9162
9163/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9164private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9165 in MobileAllocationLV ma)
9166{
9167 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9168
9169 if (not match(ma, tr_ma)) {
9170 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9171 tn, "): ", ma, " vs expected: ", tr_ma);
9172 } else {
9173 setverdict(pass);
9174 }
9175}
9176
9177private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9178 in MobileAllocationLV ma)
9179return template MobileAllocationLV {
9180 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009181 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009182 return { len := 0, ma := ''B };
9183 }
9184
9185 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9186 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9187 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009188
9189 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009190 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9191 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9192 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009193 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009194 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009195 }
9196 }
9197
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009198 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009199 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009200
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009201 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009202 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9203 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009204 }
9205
9206 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009207 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009208 if (full_mask[i] != '1'B)
9209 { continue; }
9210
9211 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9212 if (slot_mask[i] == '1'B) {
9213 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009214 } else {
9215 ma_mask := ma_mask & '0'B;
9216 }
9217 }
9218
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009219 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9220 if (full_mask[0] == '1'B) {
9221 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9222 if (slot_mask[0] == '1'B) {
9223 ma_mask := ma_mask & '1'B;
9224 } else {
9225 ma_mask := ma_mask & '0'B;
9226 }
9227 }
9228
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009229 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009230 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009231 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9232
9233 return { len := ma_mask_len, ma := ma_mask };
9234}
9235
Philipp Maier798d8952021-10-19 14:43:19 +02009236/* Configure the appropriate band for a given arfcn, exc */
9237private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9238{
9239 var charstring band;
9240 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9241
9242 select (arfcn_) {
9243 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9244 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9245 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9246 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9247 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9248 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9249 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9250 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9251 case else { return; }
9252 }
9253
9254 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9255 f_vty_transceive(BSCVTY, "band " & band);
9256 f_vty_transceive(BSCVTY, "end");
9257}
9258
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009259/* Configure the hopping parameters in accordance with the given record */
9260private function f_TC_fh_params_set(in FHParamsTrx fhp,
9261 uint8_t bts_nr := 0,
9262 uint8_t trx_nr := 0)
9263runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009264
9265 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9266
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009267 /* Enter the configuration node for the given BTS/TRX numbers */
9268 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9269
Philipp Maier798d8952021-10-19 14:43:19 +02009270 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009271
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009272 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009273 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9274
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009275 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009276 f_vty_transceive(BSCVTY, "hopping enabled 0");
9277 f_vty_transceive(BSCVTY, "exit"); /* go back */
9278 continue;
9279 }
9280
9281 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009282 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9283 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009284
9285 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009286 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9287 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009288 }
9289
9290 f_vty_transceive(BSCVTY, "hopping enabled 1");
9291 f_vty_transceive(BSCVTY, "exit"); /* go back */
9292 }
9293
9294 f_vty_transceive(BSCVTY, "end");
9295}
9296
9297/* Disable frequency hopping on all timeslots */
9298private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9299 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009300 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009301 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009302runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009303
9304 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9305
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009306 /* Enter the configuration node for the given BTS/TRX numbers */
9307 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9308
Philipp Maier798d8952021-10-19 14:43:19 +02009309 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009310
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009311 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009312 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9313
9314 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009315 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9316 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009317 }
9318
9319 f_vty_transceive(BSCVTY, "hopping enabled 0");
9320 f_vty_transceive(BSCVTY, "exit"); /* go back */
9321 }
9322
9323 f_vty_transceive(BSCVTY, "end");
9324 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9325}
9326
9327/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9328 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9329testcase TC_fh_params_chan_activ() runs on test_CT {
9330 var FHParamsTrx fhp := f_TC_fh_params_gen();
9331 var RSL_Message rsl_msg;
9332 var RSL_IE_Body ie;
9333
9334 f_init_vty();
9335
9336 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9337 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9338
9339 f_init(1);
9340
9341 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9342 for (var integer i := 0; i < 9; i := i + 1) {
9343 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9344 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9345
9346 /* Make sure that Channel Identification IE is present */
9347 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9348 setverdict(fail, "RSL Channel Identification IE is absent");
9349 continue;
9350 }
9351
9352 /* Make sure that hopping parameters (HSN/MAIO) match */
9353 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9354
9355 /* "Mobile Allocation shall be included but empty" - let's check this */
9356 if (ie.chan_ident.ma.v.len != 0) {
9357 setverdict(fail, "Mobile Allocation IE is not empty: ",
9358 ie.chan_ident.ma, ", despite it shall be");
9359 continue;
9360 }
9361 }
9362
9363 /* Disable frequency hopping */
9364 f_TC_fh_params_unset(fhp);
9365
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009366 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009367}
9368
9369/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9370testcase TC_fh_params_imm_ass() runs on test_CT {
9371 var FHParamsTrx fhp := f_TC_fh_params_gen();
9372 var RSL_Message rsl_msg;
9373 var RSL_IE_Body ie;
9374
9375 f_init_vty();
9376
9377 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9378 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9379
9380 f_init(1);
9381
9382 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9383 for (var integer i := 0; i < 9; i := i + 1) {
9384 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9385 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9386
9387 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9388 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
9389
9390 /* Make sure that Full Immediate Assign Info IE is present */
9391 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9392 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9393 continue;
9394 }
9395
9396 /* Decode the actual Immediate Assignment message */
9397 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9398 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9399 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9400 continue;
9401 }
9402
9403 /* Make sure that hopping parameters (HSN/MAIO) match */
9404 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9405
9406 /* Make sure that the Mobile Allocation IE matches */
9407 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9408 rr_msg.payload.imm_ass.mobile_allocation);
9409 }
9410
9411 /* Disable frequency hopping */
9412 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009413
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009414 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009415}
9416
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009417/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9418testcase TC_fh_params_assignment_cmd() runs on test_CT {
9419 var FHParamsTrx fhp := f_TC_fh_params_gen();
9420 var RSL_Message rsl_msg;
9421 var RSL_IE_Body ie;
9422
9423 f_init_vty();
9424
9425 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9426 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9427
9428 f_init(1);
9429
9430 /* HACK: work around "Couldn't find Expect for CRCX" */
9431 vc_MGCP.stop;
9432
9433 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9434 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9435
9436 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9437 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9438 for (var integer i := 0; i < 3; i := i + 1) {
9439 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9440 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9441
9442 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9443 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
9444 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9445
9446 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
9447 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9448 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9449
9450 /* Make sure that L3 Information IE is present */
9451 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9452 setverdict(fail, "RSL L3 Information IE is absent");
9453 continue;
9454 }
9455
9456 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9457 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9458 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9459 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9460 continue;
9461 }
9462
9463 /* Make sure that hopping parameters (HSN/MAIO) match */
9464 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9465 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9466
9467 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9468 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009469 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009470 continue;
9471 }
9472
9473 /* Make sure that the Mobile Allocation IE matches (if present) */
9474 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9475 if (chan_desc.h and ma_present) {
9476 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9477 l3_msg.payload.ass_cmd.mobile_allocation.v);
9478 } else if (chan_desc.h and not ma_present) {
9479 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9480 continue;
9481 } else if (not chan_desc.h and ma_present) {
9482 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9483 continue;
9484 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009485
9486 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009487 }
9488
9489 /* Give the IUT some time to release all channels */
9490 f_sleep(3.0);
9491
9492 /* Disable frequency hopping */
9493 f_TC_fh_params_unset(fhp);
9494
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009495 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009496}
9497
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009498/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9499private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9500runs on test_CT {
9501 var RSL_Message rsl_msg;
9502 var RSL_IE_Body ie;
9503 var DchanTuple dt;
9504
9505 /* Establish a dedicated channel, so we can trigger handover */
9506 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009507 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009508
9509 /* Trigger handover from BTS0 to BTS1 */
9510 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9511 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9512
9513 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
9514 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9515
9516 /* ACKnowledge channel activation and expect (RR) Handover Command */
9517 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9518 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9519
9520 /* Make sure that L3 Information IE is present */
9521 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9522 setverdict(fail, "RSL L3 Information IE is absent");
9523 return;
9524 }
9525
9526 /* Decode the L3 message and make sure it is (RR) Handover Command */
9527 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9528 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9529 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9530 return;
9531 }
9532
9533 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9534 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9535 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9536 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9537 return;
9538 }
9539
9540 /* Make sure that hopping parameters (HSN/MAIO) match */
9541 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9542
9543 /* Make sure that Cell Channel Description IE is present */
9544 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9545 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9546 return;
9547 }
9548
9549 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9550 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9551 if (ma_present) {
9552 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9553 l3_msg.payload.ho_cmd.mobile_allocation.v);
9554 } else {
9555 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9556 return;
9557 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009558
9559 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009560}
9561testcase TC_fh_params_handover_cmd() runs on test_CT {
9562 var FHParamsTrx fhp := f_TC_fh_params_gen();
9563
9564 f_init_vty();
9565
9566 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9567 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9568
9569 f_vty_transceive(BSCVTY, "timeslot 0");
9570 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9571 f_vty_transceive(BSCVTY, "exit"); /* go back */
9572
9573 f_vty_transceive(BSCVTY, "timeslot 1");
9574 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9575 f_vty_transceive(BSCVTY, "end"); /* we're done */
9576
9577 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9578 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9579
9580 f_init(2);
9581
9582 f_TC_fh_params_handover_cmd(fhp);
9583
9584 /* Disable frequency hopping on BTS1 */
9585 f_TC_fh_params_unset(fhp, 1);
9586
9587 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9588 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9589
9590 f_vty_transceive(BSCVTY, "timeslot 0");
9591 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9592 f_vty_transceive(BSCVTY, "exit"); /* go back */
9593
9594 f_vty_transceive(BSCVTY, "timeslot 1");
9595 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9596 f_vty_transceive(BSCVTY, "end"); /* we're done */
9597
9598 f_shutdown_helper();
9599}
9600
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009601/* Verify the hopping parameters in System Information Type 4 */
9602testcase TC_fh_params_si4_cbch() runs on test_CT {
9603 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9604 var ASP_RSL_Unitdata rx_rsl_ud;
9605 timer T := 5.0;
9606
9607 f_init_vty();
9608
9609 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9610 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9611
9612 f_vty_transceive(BSCVTY, "timeslot 0");
9613 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9614 f_vty_transceive(BSCVTY, "exit"); /* go back */
9615
9616 f_vty_transceive(BSCVTY, "timeslot 1");
9617 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9618 f_vty_transceive(BSCVTY, "end"); /* we're done */
9619
9620 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9621 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9622
9623 f_init(1);
9624
9625 T.start;
9626 alt {
9627 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9628 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9629 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9630
9631 /* Make sure that what we decoded is System Information Type 4 */
9632 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9633 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9634 repeat;
9635 }
9636
9637 /* Make sure that CBCH Channel Description IE is present */
9638 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9639 setverdict(fail, "CBCH Channel Description IE is absent");
9640 break;
9641 }
9642
9643 /* Finally, check the hopping parameters (HSN, MAIO) */
9644 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9645 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9646
9647 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9648 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9649 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9650 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9651 break;
9652 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9653 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9654 si.payload.si4.cbch_mobile_alloc.v);
9655 }
9656 }
9657 [] IPA_RSL[0].receive { repeat; }
9658 [] T.timeout {
9659 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9660 }
9661 }
9662
9663 /* Disable frequency hopping */
9664 f_TC_fh_params_unset(fhp);
9665
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009666 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009667 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9668
9669 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009670 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009671 f_vty_transceive(BSCVTY, "exit"); /* go back */
9672
9673 f_vty_transceive(BSCVTY, "timeslot 1");
9674 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9675 f_vty_transceive(BSCVTY, "end"); /* we're done */
9676
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009677 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009678}
9679
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009680template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9681 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9682
9683private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9684 template (present) BSSLAP_PDU expect_bsslap)
9685{
9686 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9687 if (not match(bsslap, expect_bsslap)) {
9688 log("EXPECTING BSSLAP: ", expect_bsslap);
9689 log("GOT BSSLAP: ", bsslap);
9690 setverdict(fail, "BSSLAP is not as expected");
9691 mtc.stop;
9692 }
9693 setverdict(pass);
9694}
9695
9696/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9697const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9698
9699private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9700 var PDU_BSSAP_LE rx_bsslap;
9701 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9702 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9703}
9704
9705/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9706 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9707private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9708 f_sleep(1.0);
9709
9710 f_establish_fully(omit, omit);
9711 f_bssap_le_register_imsi(g_pars.imsi, omit);
9712
9713 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9714 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9715
9716 var PDU_BSSAP_LE plr;
9717 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9718
9719 if (not do_ta_request) {
9720 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9721 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9722 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9723 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9724 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9725 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9726 mtc.stop;
9727 }
9728 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9729 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9730 if (not match(bsslap, expect_ta_layer3)) {
9731 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9732 log("GOT BSSLAP: ", bsslap);
9733 setverdict(fail, "BSSLAP is not as expected");
9734 mtc.stop;
9735 }
9736 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9737 * has no need to request the TA from the BSC and directly responds. */
9738 } else {
9739 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9740 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9741 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9742 }
9743
9744 /* SMLC got the TA from the BSC, now responds with geo information data. */
9745 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9746 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9747 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9748
9749 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9750 f_mo_l3_transceive();
9751
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009752 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009753
9754 f_sleep(2.0);
9755 setverdict(pass);
9756}
9757
9758/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9759 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9760private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9761 f_lcs_loc_req_for_active_ms(false);
9762}
9763testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9764 var MSC_ConnHdlr vc_conn;
9765 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9766
9767 f_init(1, true);
9768 f_sleep(1.0);
9769 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9770 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009771 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009772}
9773
9774/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9775 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9776private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9777 f_lcs_loc_req_for_active_ms(true);
9778}
9779testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9780 var MSC_ConnHdlr vc_conn;
9781 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9782
9783 f_init(1, true);
9784 f_sleep(1.0);
9785 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9786 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009787 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009788}
9789
9790/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9791 * conn without an active lchan. */
9792private function f_clear_A_conn() runs on MSC_ConnHdlr
9793{
9794 var BssmapCause cause := 0;
9795 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9796 BSSAP.receive(tr_BSSMAP_ClearComplete);
9797 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9798
9799 timer no_more_bssap := 5.0;
9800 no_more_bssap.start;
9801 alt {
9802 [] no_more_bssap.timeout { break; }
9803 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9804 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9805 mtc.stop;
9806 }
9807 }
9808 setverdict(pass);
9809}
9810
9811/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9812 * for LCS, for cases where there is only an A conn without an active lchan. */
9813private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9814{
9815 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9816
9817 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9818 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9819 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9820 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9821 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9822 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9823
9824 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9825 f_clear_A_conn();
9826 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9827 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9828}
9829
9830/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9831 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9832 */
9833private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9834 f_sleep(1.0);
9835
9836 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9837 f_bssap_le_register_imsi(g_pars.imsi, omit);
9838
9839 /* Register to receive the Paging Command */
9840 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9841 g_chan_nr := new_chan_nr;
9842 f_rslem_register(0, g_chan_nr);
9843
9844 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9845 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9846 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9847 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9848
9849 var PDU_BSSAP_LE plr;
9850 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9851
9852 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9853 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9854
9855 /* OsmoBSC needs to Page */
9856 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9857 f_logp(BSCVTY, "got Paging Command");
9858
9859 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9860 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009861 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);
9862 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009863
9864 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9865
9866 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9867
9868 /* SMLC got the TA from the BSC, now responds with geo information data. */
9869 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9870 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9871
9872 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9873
9874 /* The lchan is gone, the A-interface conn was created for the LCS only.
9875 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9876 f_verify_active_A_conn_and_clear();
9877
9878 f_sleep(2.0);
9879 setverdict(pass);
9880}
9881testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9882 var MSC_ConnHdlr vc_conn;
9883 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9884
9885 f_init(1, true);
9886 f_sleep(1.0);
9887
9888 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9889 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9890
9891 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9892 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009893 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009894}
9895
9896/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9897 */
9898private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9899 f_sleep(1.0);
9900
9901 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9902 f_bssap_le_register_imsi(g_pars.imsi, omit);
9903
9904 /* provoke an abort by omitting both IMSI and IMEI */
9905 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9906 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9907 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9908 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9909
9910 /* BSC tells MSC about failure */
9911 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9912 locationEstimate := omit, positioningData := omit,
9913 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9914
9915 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9916 f_verify_active_A_conn_and_clear();
9917
9918 f_sleep(2.0);
9919 setverdict(pass);
9920}
9921testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9922 var MSC_ConnHdlr vc_conn;
9923 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9924
9925 f_init(1, true);
9926 f_sleep(1.0);
9927
9928 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9929 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9930
9931 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9932 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009933 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009934}
9935
9936/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9937 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9938private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9939 f_sleep(1.0);
9940
9941 f_establish_fully(omit, omit);
9942 f_bssap_le_register_imsi(g_pars.imsi, omit);
9943
9944 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9945 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9946
9947 var PDU_BSSAP_LE plr;
9948 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9949
9950 if (do_ta) {
9951 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9952 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9953 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9954 }
9955
9956 /* SMLC fails to respond, BSC runs into timeout */
9957 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9958 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9959
9960 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9961 locationEstimate := omit, positioningData := omit,
9962 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9963
9964 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9965 f_verify_active_A_conn_and_clear();
9966
9967 f_sleep(2.0);
9968 setverdict(pass);
9969}
9970
9971/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9972 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9973private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9974 f_lcs_loc_req_for_active_ms_le_timeout(false);
9975}
9976
9977testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9978 var MSC_ConnHdlr vc_conn;
9979 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9980
9981 f_init(1, true);
9982 f_sleep(1.0);
9983 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9984 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009985 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009986}
9987
9988/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9989 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9990private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9991 f_lcs_loc_req_for_active_ms_le_timeout(true);
9992}
9993
9994testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9995 var MSC_ConnHdlr vc_conn;
9996 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9997
9998 f_init(1, true);
9999 f_sleep(1.0);
10000 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
10001 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010002 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010003}
10004
10005/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
10006private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
10007 f_sleep(1.0);
10008
10009 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10010 f_bssap_le_register_imsi(g_pars.imsi, omit);
10011
10012 /* Register to receive the Paging Command */
10013 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10014 g_chan_nr := new_chan_nr;
10015 f_rslem_register(0, g_chan_nr);
10016
10017 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10018 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10019 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10020 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10021
10022 var PDU_BSSAP_LE plr;
10023 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10024
10025 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10026 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10027
10028 /* OsmoBSC needs to Page */
10029 var PDU_BSSAP_LE rx_bsslap;
10030 alt {
10031 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
10032 f_logp(BSCVTY, "got Paging Command");
10033 repeat;
10034 }
10035 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10036 /* MS does not respond to Paging, TA Req runs into timeout. */
10037 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
10038 }
10039 }
10040
10041 /* SMLC responds with failure */
10042 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
10043 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10044
10045 /* BSC tells MSC about failure */
10046 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
10047 locationEstimate := omit, positioningData := omit,
10048 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
10049
10050 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
10051 f_verify_active_A_conn_and_clear();
10052
10053 f_sleep(2.0);
10054 setverdict(pass);
10055}
10056testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
10057 var MSC_ConnHdlr vc_conn;
10058 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10059
10060 f_init(1, true);
10061 f_sleep(1.0);
10062
10063 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10064 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10065
10066 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
10067 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010068 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010069}
10070
10071/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
10072 * over. */
10073private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10074 f_sleep(1.0);
10075
10076 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10077 f_bssap_le_register_imsi(g_pars.imsi, omit);
10078
10079 /* Register to receive the Paging Command */
10080 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
10081 g_chan_nr := new_chan_nr;
10082 f_rslem_register(0, g_chan_nr);
10083
10084 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
10085 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10086 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10087 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10088
10089 var PDU_BSSAP_LE plr;
10090 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10091
10092 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10093 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010094 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 +020010095 do_clear := false, expect_bssmap_l3 := true);
10096
10097 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10098 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10099
10100 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10101 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10102
10103 /* SMLC got the TA from the BSC, now responds with geo information data. */
10104 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10105 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10106 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10107
10108 /* The lchan should still exist, it was from a CM Service Request. */
10109 f_mo_l3_transceive();
10110
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010111 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010112
10113 f_sleep(2.0);
10114 setverdict(pass);
10115}
10116testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10117 var MSC_ConnHdlr vc_conn;
10118 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10119
10120 f_init(1, true);
10121 f_sleep(1.0);
10122
10123 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10124 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10125
10126 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10127 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010128 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010129}
10130
10131/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10132 * the new lchan after handover. */
10133private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10134 f_sleep(1.0);
10135
10136 f_establish_fully(omit, omit);
10137 f_bssap_le_register_imsi(g_pars.imsi, omit);
10138
10139 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10140 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10141
10142 var PDU_BSSAP_LE plr;
10143 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10144
10145 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10146 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10147
10148 var HandoverState hs := {
10149 rr_ho_cmpl_seen := false,
10150 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010151 old_chan_nr := -,
10152 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010153 };
10154 /* issue hand-over command on VTY */
10155 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10156 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10157 f_rslem_suspend(RSL1_PROC);
10158
10159 /* From the MGW perspective, a handover is is characterized by
10160 * performing one MDCX operation with the MGW. So we expect to see
10161 * one more MDCX during handover. */
10162 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10163
10164 alt {
10165 [] as_handover(hs);
10166 }
10167
10168 var PDU_BSSAP_LE rx_bsslap;
10169
10170 interleave {
10171 /* Expect the BSC to inform the MSC about the handover */
10172 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10173
10174 /* Expect the BSC to inform the SMLC about the handover */
10175 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10176 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10177 }
10178 }
10179
10180 /* SMLC now responds with geo information data. */
10181 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10182 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10183 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10184
10185 /* lchan still active */
10186 f_mo_l3_transceive(RSL1);
10187
10188 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010189 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010190
10191 f_sleep(2.0);
10192 setverdict(pass);
10193}
10194testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10195 var MSC_ConnHdlr vc_conn;
10196 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10197
10198 f_init(2, true);
10199 f_sleep(1.0);
10200 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10201 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010202 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010203}
10204
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020010205private function f_tc_emerg_call_and_lcs_loc_req(charstring id) runs on MSC_ConnHdlr
10206{
10207 /* Make sure the CHAN RQD indicates an emergency call (0b101xxxxx). The difference is that osmo-bsc directly
10208 * assigns a TCH lchan and establishing voice for the emergency call will use Mode Modify, not reassignment to
10209 * another lchan. */
10210 g_pars.ra := 'b7'O;
10211 f_assignment_emerg_setup();
10212
10213 var PDU_BSSAP emerg_setup_data_ind_bssap;
10214 timer T := 3.0;
10215 T.start;
10216 alt {
10217 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
10218 var PDU_ML3_MS_NW verify_emerg_setup;
10219 verify_emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
10220 if (not isbound(verify_emerg_setup.msgs.cc.emergencySetup)) {
10221 setverdict(fail, "no emergency setup");
10222 }
10223 }
10224 [] BSSAP.receive {
10225 setverdict(fail, "unexpected BSSAP message!");
10226 }
10227 [] T.timeout {
10228 setverdict(fail, "timeout waiting for EMERGENCY SETUP!");
10229 }
10230 }
10231
10232 /* Here would usually be a CC Call Proceeding from the MSC, but what does the BSC care about DTAP. */
10233
10234 /* Do a Location Request in-between the CC call setup */
10235 f_bssap_le_register_imsi(g_pars.imsi, omit);
10236 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10237 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10238 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
10239 /* SMLC got the TA from the BSC, now responds with geo information data. */
10240 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10241 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10242 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10243
10244 /* Go on with voice call assignment */
10245 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10246 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10247
10248 /* Below speechOrDataIndicator and codecList are copied from an emergency call captured during tests.
10249 * They seem a bit weird (AMR-WB, and the order differ between speechId_DataIndicator and the codecList), but
10250 * seems a good idea to see how osmo-bsc reacts to this. */
10251 ass_cmd.pdu.bssmap.assignmentRequest.channelType := {
10252 elementIdentifier := '0B'O, /* overwritten */
10253 lengthIndicator := 0, /* overwritten */
10254 speechOrDataIndicator := '0001'B, /* speech */
10255 spare1_4 := '0000'B,
10256 channelRateAndType := ChRate_TCHForH_Fpref,
10257 speechId_DataIndicator := 'c2918105'O
10258 };
10259 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({
10260 ts_CodecHR, ts_CodecAMR_WB, ts_CodecEFR, ts_CodecFR}));
10261
10262 f_rslem_dchan_queue_enable();
10263
10264 var ExpectCriteria mgcpcrit := {
10265 connid := omit,
10266 endpoint := omit,
10267 transid := omit
10268 };
10269 f_create_mgcp_expect(mgcpcrit);
10270
10271 BSSAP.send(ass_cmd);
10272
10273 var AssignmentState st := valueof(ts_AssignmentStateInit);
10274 st.voice_call := true;
10275 st.is_assignment := false;
10276 alt {
10277 [] as_modify(st);
10278 [] as_Media();
10279 [st.modify_done] BSSAP.receive(exp_compl) {
10280 setverdict(pass);
10281 }
10282 }
10283
10284 /* Voice call carries on ... */
10285 f_sleep(2.0);
10286
10287 setverdict(pass);
10288 f_perform_clear();
10289}
10290
10291testcase TC_emerg_call_and_lcs_loc_req() runs on test_CT {
10292 var MSC_ConnHdlr vc_conn;
10293 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10294
10295 f_init(1, true);
10296 f_sleep(1.0);
10297 f_vty_allow_emerg_msc(true);
10298 f_vty_allow_emerg_bts(true, 0);
10299 vc_conn := f_start_handler(refers(f_tc_emerg_call_and_lcs_loc_req), pars);
10300 vc_conn.done;
10301 f_shutdown_helper();
10302}
10303
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010304/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10305private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10306 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10307
10308 /* Also disable attach for the single connected MSC */
10309 f_vty_msc_allow_attach(BSCVTY, { false });
10310
10311 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) ));
10312 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10313
10314 /* No MSC is found, expecting a proper release on RSL */
10315 interleave {
10316 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10317 f_logp(BSCVTY, "Got RSL RR Release");
10318 }
10319 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10320 f_logp(BSCVTY, "Got RSL Deact SACCH");
10321 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010322 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010323 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10324 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010325 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010326 }
10327 }
10328 setverdict(pass);
10329}
10330testcase TC_no_msc() runs on test_CT {
10331
10332 f_init(1, true);
10333 f_sleep(1.0);
10334 var MSC_ConnHdlr vc_conn;
10335 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10336
10337 f_ctrs_bsc_init(counternames_bsc_mscpool);
10338
10339 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10340 vc_conn.done;
10341
10342 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10343 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010344 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010345}
10346
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010347/* Dyn PDCH todo:
10348 * activate OSMO as TCH/F
10349 * activate OSMO as TCH/H
10350 * does the BSC-located PCU socket get the updated INFO?
10351 * what if no PCU is connected at the time?
10352 * is the info correct on delayed PCU (re)connect?
10353 */
Harald Welte94e0c342018-04-07 11:33:23 +020010354
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010355private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
10356 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
10357 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
10358
10359 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10360 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10361 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10362 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10363 g_pars.ass_codec_list.codecElements[0];
10364 if (isvalue(g_pars.expect_mr_s0_s7)) {
10365 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10366 g_pars.expect_mr_s0_s7;
10367 }
10368 }
10369 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10370 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10371 log("expecting ASS COMPL like this: ", exp_compl);
10372
10373 f_establish_fully(ass_cmd, exp_compl);
10374
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010375 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 +000010376
10377 var RSL_Message rsl;
10378
10379 timer T := 5.0;
10380 T.start;
10381 alt {
10382 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10383 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10384 log("Rx L3 from net: ", l3);
10385 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10386 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10387 mtc.stop;
10388 }
10389 }
10390 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10391 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10392 mtc.stop;
10393 }
10394 [] T.timeout {
10395 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10396 setverdict(pass);
10397 }
10398 }
10399 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010400
10401 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010402}
10403
10404/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10405 * osmo-bsc. */
10406testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10407 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10408 var MSC_ConnHdlr vc_conn;
10409
10410 f_init(1, true);
10411 f_sleep(1.0);
10412
10413 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10414 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10415 vc_conn.done;
10416 f_shutdown_helper();
10417}
10418
10419/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10420 */
10421testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10422 f_init_vty();
10423
10424 f_init(1, false);
10425 f_sleep(1.0);
10426
10427 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10428
10429 var ASP_RSL_Unitdata rx_rsl_ud;
10430 timer T := 5.0;
10431
10432 T.start;
10433 alt {
10434 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
10435 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10436 T.stop;
10437 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10438 mtc.stop;
10439 }
10440 repeat;
10441 }
10442 [] T.timeout {
10443 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10444 setverdict(pass);
10445 }
10446 }
10447}
10448
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010449private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10450 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010451 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010452
10453 /* Trigger re-assignment to another lchan */
10454 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10455
10456 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10457 * one MDCX on MGCP. */
10458 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10459
10460 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10461 * as the old lchan used. */
10462 g_media.bts.ipa_crcx_seen := false;
10463 g_media.bts.ipa_mdcx_seen := false;
10464
10465 /* Send different BTS side RTP port number for the new lchan */
10466 g_media.bts.bts.port_nr := 4223;
10467
10468 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10469
10470 /* Trigger re-assignment. */
10471 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10472
10473 timer T := 5.0;
10474 T.start;
10475 alt {
10476 [] as_assignment(assignment_st);
10477 [] as_Media();
10478 [] T.timeout {
10479 break;
10480 }
10481 }
10482
10483 if (not assignment_st.assignment_done) {
10484 setverdict(fail, "Assignment did not complete");
10485 mtc.stop;
10486 }
10487
10488 f_check_mgcp_expectations()
10489 setverdict(pass);
10490
10491 f_sleep(2.0);
10492 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10493
10494 /* Instruct BSC to clear channel */
10495 var BssmapCause cause := 0;
10496 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10497 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010498 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10499 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010500 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010501 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010502 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010503 }
10504 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10505 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10506 }
10507 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010508 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010509
10510 f_sleep(0.5);
10511}
10512
10513testcase TC_reassignment_fr() runs on test_CT {
10514 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10515 var MSC_ConnHdlr vc_conn;
10516
10517 f_init(1, true);
10518 f_sleep(1.0);
10519
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010520 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010521
10522 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10523 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10524 vc_conn.done;
10525
10526 /* from f_establish_fully() */
10527 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10528 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10529 /* from re-assignment */
10530 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10531 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10532 f_ctrs_bsc_and_bts_verify();
10533 f_shutdown_helper();
10534}
10535
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010536const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10537const charstring REEST_CLEAR := "REEST_CLEAR";
10538const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10539
10540/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10541 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10542 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10543 * the MSC as the CM Re-Establishment is handled.
10544 *
10545 * MS bts0 bts1 bsc msc test-component
10546 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10547 * | | _1 wait a bit, to settle down
10548 * |<-x x--| | _1 "lose connection"
10549 * | | REEST_LOST_CONNECTION
10550 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10551 * | | REEST_CLEAR
10552 * | |<-0---| _1 Clear Command on first A-conn
10553 * | |--0-->| _1 Clear Complete
10554 * | |<----------------->| | _1 Release first channel
10555 * | | REEST_CLEAR_DONE
10556 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10557 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10558 *
10559 */
10560private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10561 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10562 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10563
10564 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10565 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10566
10567 f_establish_fully(ass_cmd, exp_compl);
10568
10569 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10570 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10571 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10572 f_sleep(2.0);
10573 COORD.send(REEST_LOST_CONNECTION);
10574
10575 alt {
10576 [] COORD.receive(REEST_CLEAR);
10577 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10578 setverdict(fail, "Unexpected channel release");
10579 mtc.stop;
10580 }
10581 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10582 setverdict(fail, "Unexpected channel release");
10583 mtc.stop;
10584 }
10585 }
10586 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010587 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010588 COORD.send(REEST_CLEAR_DONE);
10589}
10590
10591private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10592 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10593
10594 /* The MS lost the connection on the first channel, now establishes another one */
10595 COORD.receive(REEST_LOST_CONNECTION);
10596
10597 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10598 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10599 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10600
10601 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010602 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 +020010603 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10604
10605 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10606 COORD.send(REEST_CLEAR);
10607 COORD.receive(REEST_CLEAR_DONE);
10608
10609 f_sleep(2.0);
10610
10611 /* Answer the CM Re-Establishment with an Assignment Command. */
10612 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10613 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10614 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10615 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10616
10617 var AssignmentState st := valueof(ts_AssignmentStateInit);
10618 st.voice_call := true;
10619 st.is_assignment := true;
10620
10621 var ExpectCriteria mgcpcrit := {
10622 connid := omit,
10623 endpoint := omit,
10624 transid := omit
10625 };
10626 f_create_mgcp_expect(mgcpcrit);
10627
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010628 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010629
10630 BSSAP.send(ass_cmd);
10631
10632 var PDU_BSSAP bssap;
10633
10634 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010635 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10636 [] as_Media_ipacc(RSL1, RSL2);
10637 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010638 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10639 break;
10640 }
10641 }
10642
10643 f_sleep(3.0);
10644
10645 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010646 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010647}
10648
10649testcase TC_cm_reestablishment() runs on test_CT {
10650 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10651 var MSC_ConnHdlr vc_conn1;
10652
10653 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10654 var MSC_ConnHdlr vc_conn2;
10655 pars2.imsi := pars1.imsi;
10656 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +020010657 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010658
10659 f_init(2, true, guard_timeout := 40.0);
10660 f_sleep(1.0);
10661
10662 vc_conn1 := f_start_handler_create(pars1);
10663 vc_conn2 := f_start_handler_create(pars2);
10664 connect(vc_conn1:COORD, vc_conn2:COORD);
10665 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10666 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10667 vc_conn1.done;
10668 vc_conn2.done;
10669
10670 f_shutdown_helper();
10671}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010672
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010673function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
10674 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
10675runs on test_CT return template (omit) RSL_Message {
10676 var ASP_RSL_Unitdata rx_rsl_ud;
10677 timer T := t_secs;
10678
10679 T.start;
10680 alt {
10681 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
10682 T.stop;
10683 }
10684 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
10685 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
10686 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10687 T.stop;
10688 return omit;
10689 }
10690 [] T.timeout {
10691 return omit;
10692 }
10693 }
10694 return rx_rsl_ud.rsl;
10695}
10696
10697private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10698 f_vty_enter_cfg_bts(pt, bts_nr);
10699 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10700 f_vty_transceive(pt, "exit");
10701 f_vty_transceive(pt, "exit");
10702 f_vty_transceive(pt, "exit");
10703}
10704
10705private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Vadim Yanitskiy35c9a332022-03-16 20:26:35 +030010706 template (present) RslChannelNr chan_nr := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010707 template (present) uint12_t arfcn := ?,
10708 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010709{
10710 var RSL_IE_Body full_imm_ass_info;
10711 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10712 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10713 mtc.stop;
10714 }
10715
10716 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10717 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10718 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010719 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010720 page_mode := ?);
10721 if (not match(rr_imm_ass, expect_imm_ass)) {
10722 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10723 setverdict(fail, "Failed to match Immediate Assignment");
10724 mtc.stop;
10725 }
10726}
10727
10728testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10729 var RSL_Message chan_act;
10730 var RSL_Message imm_ass;
10731
10732 f_init(1, false);
10733 f_sleep(1.0);
10734
10735 /* (should be the default anyway, just to make things clear) */
10736 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10737
10738 /* RA containing reason=LU */
10739 var GsmFrameNumber fn := 2342;
10740 var uint8_t ra := 2;
10741 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10742
10743 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10744
10745 /* First send the Chan Act ACK */
10746 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010747 var DchanTuple dt;
10748 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010749 var RSL_IE_Body chan_ident_ie;
10750 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10751 setverdict(fail, "RSL Channel Identification IE is absent");
10752 mtc.stop;
10753 }
10754
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010755 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10756
10757 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10758 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10759
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010760 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10761 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010762
10763 /* Check that the lchan is working */
10764 var octetstring l3 := '00010203040506'O;
10765 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10766
10767 var BSSAP_N_CONNECT_ind rx_c_ind;
10768 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010769 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010770 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10771
10772 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010773 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010774 f_shutdown_helper();
10775}
10776
10777testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10778 var RSL_Message chan_act;
10779 var RSL_Message imm_ass;
10780
10781 f_init(1, false);
10782 f_sleep(1.0);
10783
10784 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10785
10786 /* RA containing reason=LU */
10787 var GsmFrameNumber fn := 2342;
10788 var uint8_t ra := 2;
10789 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10790
10791 /* (set bts 0 cfg back to default) */
10792 f_vty_set_imm_ass(BSCVTY);
10793
10794 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10795 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010796 var DchanTuple dt;
10797 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010798 var RSL_IE_Body chan_ident_ie;
10799 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10800 setverdict(fail, "RSL Channel Identification IE is absent");
10801 mtc.stop;
10802 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010803
10804 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10805 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010806 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10807 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010808
10809 /* Only now send the Chan Act ACK */
10810 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10811
10812 /* Check that the lchan is working */
10813 var octetstring l3 := '00010203040506'O;
10814 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10815
10816 var BSSAP_N_CONNECT_ind rx_c_ind;
10817 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010818 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010819 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10820
10821 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010822 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010823 f_shutdown_helper();
10824}
10825
Neels Hofmeyr23158742021-09-07 19:08:07 +020010826testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10827 var RSL_Message chan_act;
10828 var RSL_Message imm_ass;
10829
10830 f_init(1, false);
10831 f_sleep(1.0);
10832
10833 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10834
10835 /* RA containing reason=LU */
10836 var GsmFrameNumber fn := 2342;
10837 var uint8_t ra := 2;
10838 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10839
10840 /* (set bts 0 cfg back to default) */
10841 f_vty_set_imm_ass(BSCVTY);
10842
10843 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10844 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010845 var DchanTuple dt;
10846 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010847 var RSL_IE_Body chan_ident_ie;
10848 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10849 setverdict(fail, "RSL Channel Identification IE is absent");
10850 mtc.stop;
10851 }
10852
10853 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10854 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10855 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10856 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10857
10858 /* Only now send the Chan Act ACK */
10859 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10860
10861 /* Check that the lchan is working */
10862 var octetstring l3 := '00010203040506'O;
10863 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10864
10865 var BSSAP_N_CONNECT_ind rx_c_ind;
10866 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010867 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010868 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10869
10870 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010871 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020010872 f_shutdown_helper();
10873}
10874
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010875testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10876 /* change Timeslot 6 before f_init() starts RSL */
10877 f_init_vty();
10878 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10879 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10880
10881 f_init(1, false);
10882 f_sleep(1.0);
10883
10884 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10885 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010886 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010887 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10888
10889 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10890 f_ts_set_chcomb(0, 0, 6, "PDCH");
10891
10892 /* block all static timeslots so that the dyn TS will be used */
10893 f_disable_all_tch_f();
10894 f_disable_all_tch_h();
10895 f_disable_all_sdcch();
10896
10897 var RSL_Message chan_act;
10898 var RSL_Message imm_ass;
10899
10900 f_init(1, false);
10901 f_sleep(1.0);
10902
10903 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10904
10905 /* RA containing reason=LU */
10906 var GsmFrameNumber fn := 2342;
10907 var uint8_t ra := 2;
10908 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10909
10910 /* (set bts 0 cfg back to default) */
10911 f_vty_set_imm_ass(BSCVTY);
10912
10913 /* Expect the dyn TS to deactivate PDCH first */
10914 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10915 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10916
10917 /* Now activation as SDCCH8 */
10918 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010919 var DchanTuple dt;
10920 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010921
10922 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010923 var RSL_IE_Body chan_ident_ie;
10924 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10925 setverdict(fail, "RSL Channel Identification IE is absent");
10926 mtc.stop;
10927 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010928
10929 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10930 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010931 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10932 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010933
10934 /* Only now send the Chan Act ACK */
10935 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10936
10937 /* Check that the lchan is working */
10938 var octetstring l3 := '00010203040506'O;
10939 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10940
10941 var BSSAP_N_CONNECT_ind rx_c_ind;
10942 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010943 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010944 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10945
10946 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010947 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010948 f_shutdown_helper();
10949}
10950
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010951testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10952 /* change Timeslot 6 before f_init() starts RSL */
10953 f_init_vty();
10954 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10955 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10956
10957 f_init(1, false);
10958 f_sleep(1.0);
10959
10960 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10961 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010962 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010963 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10964
10965 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10966 f_ts_set_chcomb(0, 0, 6, "PDCH");
10967
10968 /* block all static timeslots so that the dyn TS will be used */
10969 f_disable_all_tch_f();
10970 f_disable_all_tch_h();
10971 f_disable_all_sdcch();
10972
10973 var RSL_Message chan_act;
10974 var RSL_Message imm_ass;
10975
10976 f_init(1, false);
10977 f_sleep(1.0);
10978
10979 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10980
10981 /* RA containing reason=LU */
10982 var GsmFrameNumber fn := 2342;
10983 var uint8_t ra := 2;
10984 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10985
10986 /* (set bts 0 cfg back to default) */
10987 f_vty_set_imm_ass(BSCVTY);
10988
10989 /* Expect the dyn TS to deactivate PDCH first */
10990 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10991
10992 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10993 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10994
10995 /* continue the Osmo style PDCH Deact (usual chan rel) */
10996 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10997
10998 /* Now activation as SDCCH8 */
10999 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011000 var DchanTuple dt;
11001 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011002
11003 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011004 var RSL_IE_Body chan_ident_ie;
11005 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
11006 setverdict(fail, "RSL Channel Identification IE is absent");
11007 mtc.stop;
11008 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011009 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
11010
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020011011 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
11012 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011013
11014 /* Check that the lchan is working */
11015 var octetstring l3 := '00010203040506'O;
11016 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
11017
11018 var BSSAP_N_CONNECT_ind rx_c_ind;
11019 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011020 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011021 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
11022
11023 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011024 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011025 f_shutdown_helper();
11026}
11027
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011028/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
11029testcase TC_ctrl_trx_rf_locked() runs on test_CT {
11030 var MSC_ConnHdlr vc_conn;
11031
11032 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
11033 f_sleep(1.0);
11034
11035 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
11036 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11037 "0,0,operational,unlocked,on,rsl-up;" &
11038 "1,0,operational,unlocked,on,rsl-up;" &
11039 "2,0,operational,unlocked,on,rsl-down;" &
11040 "3,0,inoperational,locked,on,rsl-down;");
11041
11042 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
11043 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11044 /* give it a moment to settle the FSM status */
11045 f_sleep(1.0);
11046
11047 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
11048 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
11049 * of "off"? But that's for a future patch if at all. */
11050 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11051 "0,0,operational,unlocked,on,rsl-up;" &
11052 "1,0,operational,locked,on,rsl-up;" &
11053 "2,0,operational,unlocked,on,rsl-down;" &
11054 "3,0,inoperational,locked,on,rsl-down;");
11055
11056 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
11057 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
11058 f_sleep(1.0);
11059 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11060 "0,0,operational,unlocked,on,rsl-up;" &
11061 "1,0,operational,locked,on,rsl-up;" &
11062 "2,0,operational,unlocked,on,rsl-down;" &
11063 "3,0,inoperational,locked,on,rsl-down;");
11064
11065 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
11066 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
11067 f_sleep(1.0);
11068 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11069 "0,0,operational,unlocked,on,rsl-up;" &
11070 "1,0,operational,unlocked,on,rsl-up;" &
11071 "2,0,operational,unlocked,on,rsl-down;" &
11072 "3,0,inoperational,locked,on,rsl-down;");
11073
11074 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
11075 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
11076 f_sleep(1.0);
11077 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11078 "0,0,operational,unlocked,on,rsl-up;" &
11079 "1,0,operational,unlocked,on,rsl-up;" &
11080 "2,0,operational,unlocked,on,rsl-down;" &
11081 "3,0,inoperational,locked,on,rsl-down;");
11082
11083 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
11084 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
11085 f_sleep(1.0);
11086 f_ctrl_get_exp(IPA_CTRL, "rf_states",
11087 "0,0,operational,unlocked,on,rsl-up;" &
11088 "1,0,operational,unlocked,on,rsl-up;" &
11089 "2,0,operational,unlocked,on,rsl-down;" &
11090 "3,0,inoperational,locked,on,rsl-down;");
11091
11092 f_shutdown_helper();
11093}
11094
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011095const CounterNameVals counternames_cm_serv_rej := {
11096 { "cm_serv_rej", 0 },
11097 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
11098 { "cm_serv_rej:illegal_ms", 0 },
11099 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
11100 { "cm_serv_rej:imei_not_accepted", 0 },
11101 { "cm_serv_rej:illegal_me", 0 },
11102 { "cm_serv_rej:plmn_not_allowed", 0 },
11103 { "cm_serv_rej:loc_not_allowed", 0 },
11104 { "cm_serv_rej:roaming_not_allowed", 0 },
11105 { "cm_serv_rej:network_failure", 0 },
11106 { "cm_serv_rej:synch_failure", 0 },
11107 { "cm_serv_rej:congestion", 0 },
11108 { "cm_serv_rej:srv_opt_not_supported", 0 },
11109 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
11110 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
11111 { "cm_serv_rej:call_can_not_be_identified", 0 },
11112 { "cm_serv_rej:incorrect_message", 0 },
11113 { "cm_serv_rej:invalid_mandantory_inf", 0 },
11114 { "cm_serv_rej:msg_type_not_implemented", 0 },
11115 { "cm_serv_rej:msg_type_not_compatible", 0 },
11116 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
11117 { "cm_serv_rej:condtional_ie_error", 0 },
11118 { "cm_serv_rej:msg_not_compatible", 0 },
11119 { "cm_serv_rej:protocol_error", 0 },
11120 { "cm_serv_rej:retry_in_new_cell", 0 }
11121};
11122
11123private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
11124{
11125 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030011126 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011127 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011128 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
11129 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011130 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011131}
11132testcase TC_cm_serv_rej() runs on test_CT {
11133 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11134 var MSC_ConnHdlr vc_conn;
11135
11136 f_init(1, true);
11137 f_sleep(1.0);
11138
11139 f_ctrs_bts_init(1, counternames_cm_serv_rej);
11140
11141 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
11142 vc_conn.done;
11143
11144 f_ctrs_bts_add(0, "cm_serv_rej", 1);
11145 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
11146 f_ctrs_bts_verify();
11147
Neels Hofmeyr87a65612021-11-16 15:56:45 +010011148 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011149 f_shutdown_helper();
11150}
11151
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011152/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
11153 * Activ Ack (SYS#5627). */
11154private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
11155 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030011156
11157 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
11158 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011159
11160 var BSSMAP_FIELD_CodecType codecType;
11161 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
11162
11163 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
11164
11165 /* First establish a signalling lchan */
11166 f_create_chan_and_exp();
11167 f_rslem_dchan_queue_enable();
11168
11169 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011170
11171 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
11172 activate(as_Media_mgw());
11173
11174 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
11175 f_rslem_register(0, chan_nr);
11176
11177 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
11178 BSSAP.send(ass_cmd);
11179
11180
11181 /* Wait for the Channel Activ for the TCH channel */
11182 var ASP_RSL_Unitdata rx_rsl_ud;
11183 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
11184
11185 /* make the original SDCCH disappear */
11186 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11187
11188 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11189 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11190
11191 interleave {
11192 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11193 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11194 }
11195
11196 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11197 BSSAP.receive(tr_BSSMAP_ClearComplete);
11198 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11199
11200 var MgcpCommand mgcp;
11201 MGCP.receive(tr_DLCX()) -> value mgcp {
11202 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11203 };
11204
11205 f_sleep(0.5);
11206}
11207testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11208 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11209 var MSC_ConnHdlr vc_conn;
11210
11211 f_init(1, true);
11212 f_sleep(1.0);
11213
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011214 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11215 vc_conn.done;
11216
11217 f_shutdown_helper();
11218}
11219
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011220const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11221 { "all_allocated:sdcch", 0 },
11222 { "all_allocated:static_sdcch", 0 },
11223 { "all_allocated:tch", 0 },
11224 { "all_allocated:static_tch", 0 }
11225}
11226
11227private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11228{
11229 /* Make sure counters settle first */
11230 f_sleep(1.0);
11231
11232 /* Take a baseline of counters */
11233 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11234
11235 /* Elapse some time so that we see changes in counters, hopefully where expected */
11236 f_sleep(2.0);
11237
11238 /* Get new counters */
11239 var charstring_list all_changed := {};
11240 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11241 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11242
11243 /* Compare with expectations */
11244 var charstring_list all_expect_changed := {};
11245 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11246 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11247 }
11248 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11249}
11250
11251testcase TC_ratectr_all_available_allocated() runs on test_CT {
11252 var ASP_RSL_Unitdata rsl_ud;
11253 var integer i;
11254 var integer chreq_total, chreq_nochan;
11255
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011256 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011257 f_sleep(1.0);
11258
11259 /* Exhaust all dedicated SDCCH lchans.
11260 /* GSM 44.018 Table 9.1.8.2:
11261 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11262 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011263 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011264 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011265 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011266 }
11267
11268 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11269 * level.
11270 * All SDCCH are now occupied. */
11271 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11272
11273 /* Also fill up all remaining (TCH) channels */
11274 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011275 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011276 }
11277
11278 /* All TCH are now also occupied */
11279 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11280 "all_allocated:tch", "all_allocated:static_tch"});
11281
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011282 /* Clean up SDCCH lchans */
11283 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11284 f_perform_clear_test_ct(chan_cleanup[i]);
11285 }
11286
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011287 f_shutdown_helper();
11288}
11289
11290testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11291 var ASP_RSL_Unitdata rsl_ud;
11292 var integer i;
11293 var integer chreq_total, chreq_nochan;
11294
11295 f_init_vty();
11296 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11297 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11298 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11299
11300 f_init(1, guard_timeout := 60.0);
11301 f_sleep(1.0);
11302
11303 /* The dyn TS wants to activate PDCH mode, ACK that. */
11304 var RslChannelNr chan_nr;
11305 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011306 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011307 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11308
11309 /* Exhaust all dedicated SDCCH lchans.
11310 /* GSM 44.018 Table 9.1.8.2:
11311 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11312 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011313 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011314 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011315 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011316 }
11317
11318 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11319 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11320 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11321
11322 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11323 * Will release them later, so remember all the DchanTuples. */
11324 var DchanTuples dyn_sddch := {};
11325 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11326
11327 /* Also occupy the seven other SDCCH of the dyn TS */
11328 for (i := 0; i < 7; i := i+1) {
11329 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11330 }
11331
11332 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11333 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11334
11335 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11336 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011337 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011338 }
11339
11340 /* All TCH lchans are now also occupied, both static and dynamic */
11341 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11342 "all_allocated:tch", "all_allocated:static_tch"});
11343
11344 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11345 * incrementing. */
11346 var BssmapCause cause := 0;
11347 var DchanTuple dt := dyn_sddch[0];
11348 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11349 f_exp_chan_rel_and_clear(dt, 0);
11350
11351 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11352 * count as occupied, so those still both increment. */
11353 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11354 "all_allocated:tch", "all_allocated:static_tch"});
11355
11356 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11357 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11358 dt := dyn_sddch[i];
11359 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11360 f_exp_chan_rel_and_clear(dt, 0);
11361 }
11362
11363 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11364 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011365 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011366 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11367
11368 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11369 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11370
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011371 /* Clean up SDCCH lchans */
11372 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11373 f_perform_clear_test_ct(chan_cleanup[i]);
11374 }
11375
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011376 /* clean up config */
11377 f_ts_reset_chcomb(0);
11378
11379 f_shutdown_helper();
11380}
11381
Harald Welte28d943e2017-11-25 15:00:50 +010011382control {
Harald Welte898113b2018-01-31 18:32:21 +010011383 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010011384 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010011385 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020011386 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
11387 * these in the AoIP test suite. */
11388 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11389 execute( TC_stat_num_msc_connected_1() );
11390 execute( TC_stat_num_msc_connected_2() );
11391 execute( TC_stat_num_msc_connected_3() );
11392 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020011393 execute( TC_stat_num_bts_connected_1() );
11394 execute( TC_stat_num_bts_connected_2() );
11395 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010011396 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011397 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020011398 execute( TC_ctrl_location() );
11399 }
Harald Welte898113b2018-01-31 18:32:21 +010011400
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011401 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020011402 execute( TC_si2quater_2_earfcns() );
11403 execute( TC_si2quater_3_earfcns() );
11404 execute( TC_si2quater_4_earfcns() );
11405 execute( TC_si2quater_5_earfcns() );
11406 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020011407 execute( TC_si2quater_12_earfcns() );
11408 execute( TC_si2quater_23_earfcns() );
11409 execute( TC_si2quater_32_earfcns() );
11410 execute( TC_si2quater_33_earfcns() );
11411 execute( TC_si2quater_42_earfcns() );
11412 execute( TC_si2quater_48_earfcns() );
11413 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020011414 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020011415 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011416
Harald Welte898113b2018-01-31 18:32:21 +010011417 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010011418 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010011419 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010011420 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020011421 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020011422 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010011423 execute( TC_chan_act_ack_est_ind_noreply() );
11424 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010011425 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010011426 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070011427 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010011428 execute( TC_chan_rel_rll_rel_ind() );
11429 execute( TC_chan_rel_conn_fail() );
11430 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020011431 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
11432 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010011433 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010011434 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020011435 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010011436 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010011437 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020011438 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010011439
Harald Weltecfe2c962017-12-15 12:09:32 +010011440 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010011441
11442 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010011443 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010011444 execute( TC_assignment_csd() );
11445 execute( TC_assignment_ctm() );
11446 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011447 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11448 execute( TC_assignment_aoip_tla_v6() );
11449 }
Harald Welte235ebf12017-12-15 14:18:16 +010011450 execute( TC_assignment_fr_a5_0() );
11451 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011452 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020011453 execute( TC_assignment_fr_a5_1_codec_missing() );
11454 }
Harald Welte235ebf12017-12-15 14:18:16 +010011455 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020011456 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020011457 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020011458 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011459 execute( TC_ciph_mode_a5_0() );
11460 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020011461 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020011462 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011463 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020011464 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010011465
Harald Welte60aa5762018-03-21 19:33:13 +010011466 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020011467 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010011468 execute( TC_assignment_codec_hr() );
11469 execute( TC_assignment_codec_efr() );
11470 execute( TC_assignment_codec_amr_f() );
11471 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011472
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011473 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010011474 execute( TC_assignment_codec_amr_f_S1() );
11475 execute( TC_assignment_codec_amr_h_S1() );
11476 execute( TC_assignment_codec_amr_f_S124() );
11477 execute( TC_assignment_codec_amr_h_S124() );
11478 execute( TC_assignment_codec_amr_f_S0() );
11479 execute( TC_assignment_codec_amr_f_S02() );
11480 execute( TC_assignment_codec_amr_f_S024() );
11481 execute( TC_assignment_codec_amr_f_S0247() );
11482 execute( TC_assignment_codec_amr_h_S0() );
11483 execute( TC_assignment_codec_amr_h_S02() );
11484 execute( TC_assignment_codec_amr_h_S024() );
11485 execute( TC_assignment_codec_amr_h_S0247() );
11486 execute( TC_assignment_codec_amr_f_S01234567() );
11487 execute( TC_assignment_codec_amr_f_S0234567() );
11488 execute( TC_assignment_codec_amr_f_zero() );
11489 execute( TC_assignment_codec_amr_f_unsupp() );
11490 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000011491 execute( TC_assignment_codec_amr_f_start_mode_auto() );
11492 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000011493 execute( TC_assignment_codec_amr_f_start_mode_4() );
11494 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000011495 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011496 }
Harald Welte60aa5762018-03-21 19:33:13 +010011497
Philipp Maierac09bfc2019-01-08 13:41:39 +010011498 execute( TC_assignment_codec_fr_exhausted_req_hr() );
11499 execute( TC_assignment_codec_fr_exhausted_req_fr() );
11500 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
11501 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
11502 execute( TC_assignment_codec_hr_exhausted_req_fr() );
11503 execute( TC_assignment_codec_hr_exhausted_req_hr() );
11504 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
11505 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
11506 execute( TC_assignment_codec_req_hr_fr() );
11507 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020011508 execute( TC_assignment_sdcch_exhausted_req_signalling() );
11509 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
11510 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010011511
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020011512 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020011513
Harald Welte898113b2018-01-31 18:32:21 +010011514 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010011515 execute( TC_rll_est_ind_inact_lchan() );
11516 execute( TC_rll_est_ind_inval_sapi1() );
11517 execute( TC_rll_est_ind_inval_sapi3() );
11518 execute( TC_rll_est_ind_inval_sacch() );
11519
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070011520 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
11521 execute( TC_tch_dlci_link_id_sapi() );
11522
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011523 /* SAPI N Reject triggered by RLL establishment failures */
11524 execute( TC_rll_rel_ind_sapi_n_reject() );
11525 execute( TC_rll_err_ind_sapi_n_reject() );
11526 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070011527 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011528
Harald Welte898113b2018-01-31 18:32:21 +010011529 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010011530 execute( TC_paging_imsi_nochan() );
11531 execute( TC_paging_tmsi_nochan() );
11532 execute( TC_paging_tmsi_any() );
11533 execute( TC_paging_tmsi_sdcch() );
11534 execute( TC_paging_tmsi_tch_f() );
11535 execute( TC_paging_tmsi_tch_hf() );
11536 execute( TC_paging_imsi_nochan_cgi() );
11537 execute( TC_paging_imsi_nochan_lac_ci() );
11538 execute( TC_paging_imsi_nochan_ci() );
11539 execute( TC_paging_imsi_nochan_lai() );
11540 execute( TC_paging_imsi_nochan_lac() );
11541 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010011542 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
11543 execute( TC_paging_imsi_nochan_rnc() );
11544 execute( TC_paging_imsi_nochan_lac_rnc() );
11545 execute( TC_paging_imsi_nochan_lacs() );
11546 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010011547 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010011548 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010011549 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010011550 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010011551 execute( TC_paging_resp_unsol() );
Pau Espin Pedrol09b9bad2022-04-21 18:48:08 +020011552 execute( TC_paging_500req() );
Pau Espin Pedrol189bf1b2022-04-27 12:42:13 +020011553 execute( TC_paging_450req_no_paging_load_ind() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010011554
11555 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010011556 execute( TC_rsl_unknown_unit_id() );
11557
11558 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011559
11560 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020011561 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011562 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010011563 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010011564 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010011565 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010011566 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011567
Harald Welte261af4b2018-02-12 21:20:39 +010011568 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020011569 execute( TC_ho_int_a5_0() );
11570 execute( TC_ho_int_a5_1() );
11571 execute( TC_ho_int_a5_3() );
11572 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000011573 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011574
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011575 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020011576 execute( TC_ho_out_fail_no_msc_response() );
11577 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020011578 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011579
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011580 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020011581 execute( TC_ho_into_this_bsc_a5_0() );
11582 execute( TC_ho_into_this_bsc_a5_1() );
11583 execute( TC_ho_into_this_bsc_a5_3() );
11584 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010011585 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
11586 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010011587 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011588 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11589 execute( TC_ho_into_this_bsc_tla_v6() );
11590 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020011591 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030011592 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010011593 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020011594 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020011595 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
11596 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011597 execute( TC_ho_in_fail_msc_clears() );
11598 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
11599 execute( TC_ho_in_fail_no_detect() );
11600 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010011601 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011602
Neels Hofmeyr91401012019-07-11 00:42:35 +020011603 execute( TC_ho_neighbor_config_1() );
11604 execute( TC_ho_neighbor_config_2() );
11605 execute( TC_ho_neighbor_config_3() );
11606 execute( TC_ho_neighbor_config_4() );
11607 execute( TC_ho_neighbor_config_5() );
11608 execute( TC_ho_neighbor_config_6() );
11609 execute( TC_ho_neighbor_config_7() );
11610
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011611 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010011612 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010011613 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020011614
11615 execute( TC_dyn_pdch_ipa_act_deact() );
11616 execute( TC_dyn_pdch_ipa_act_nack() );
11617 execute( TC_dyn_pdch_osmo_act_deact() );
11618 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010011619 execute( TC_dyn_ts_sdcch8_act_deact() );
11620 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
11621 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
11622 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011623
Stefan Sperling0796a822018-10-05 13:01:39 +020011624 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020011625 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020011626
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010011627 /* Power control related */
11628 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020011629 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020011630
11631 /* MSC pooling */
11632 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
11633 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
11634 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
11635 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
11636 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11637 execute( TC_mscpool_L3Compl_on_1_msc() );
11638 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
11639 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
11640 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
11641 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
11642 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
11643 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
11644 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
11645 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
11646 execute( TC_mscpool_paging_and_response_imsi() );
11647 execute( TC_mscpool_paging_and_response_tmsi() );
11648 execute( TC_mscpool_no_allow_attach_round_robin() );
11649 execute( TC_mscpool_no_allow_attach_valid_nri() );
11650 }
11651
Harald Welte99f3ca02018-06-14 13:40:29 +020011652 execute( TC_early_conn_fail() );
11653 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020011654 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011655
Philipp Maier783681c2020-07-16 16:47:06 +020011656 /* Emergency call handling (deny / allow) */
11657 execute( TC_assignment_emerg_setup_allow() );
11658 execute( TC_assignment_emerg_setup_deny_msc() );
11659 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020011660 execute( TC_emerg_premption() );
11661
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070011662 /* Frequency hopping parameters handling */
11663 execute( TC_fh_params_chan_activ() );
11664 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070011665 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070011666 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070011667 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011668
11669 if (mp_enable_lcs_tests) {
11670 execute( TC_lcs_loc_req_for_active_ms() );
11671 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
11672 execute( TC_lcs_loc_req_for_idle_ms() );
11673 execute( TC_lcs_loc_req_no_subscriber() );
11674 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
11675 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
11676 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
11677 execute( TC_cm_service_during_lcs_loc_req() );
11678 execute( TC_ho_during_lcs_loc_req() );
Neels Hofmeyra47a8c62022-04-07 00:31:19 +020011679 execute( TC_emerg_call_and_lcs_loc_req() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011680 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000011681
11682 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011683
11684 execute( TC_refuse_chan_act_to_vamos() );
11685 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011686
11687 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011688
11689 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011690
11691 execute( TC_imm_ass_post_chan_ack() );
11692 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020011693 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011694 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011695 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011696
11697 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011698
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011699 execute( TC_ratectr_all_available_allocated() );
11700 execute( TC_ratectr_all_available_allocated_dyn() );
11701
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011702 execute( TC_cm_serv_rej() );
11703
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011704 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011705
11706 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
11707 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
11708 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010011709}
11710
11711}