blob: 758b989780c12cd37c1e06dbd16e3849ca0ab99a [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;
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +0700964 IPA_RSL[i].send(ts_ASP_RSL_UD(ts_RSL_PAGING_LOAD_IND(23)));
Harald Welteae026692017-12-09 01:03:01 +0100965 }
Harald Welte60e823a2017-12-10 14:10:59 +0100966 [] IPA_RSL[i].receive(ASP_IPA_Event:?) { repeat }
Harald Welteae026692017-12-09 01:03:01 +0100967 [] IPA_RSL[i].receive { repeat }
968 [] T.timeout {
Harald Welte96c94412017-12-09 03:12:45 +0100969 setverdict(fail, "Timeout RSL waiting for ASP_IPA_EVENT_ID_ACK");
Daniel Willmannafce8662018-07-06 23:11:32 +0200970 mtc.stop;
Harald Welteae026692017-12-09 01:03:01 +0100971 }
972 }
973}
974
Harald Welte12055472018-03-17 20:10:08 +0100975function f_ipa_rsl_stop(inout IPA_Client clnt) runs on test_CT {
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100976 var IPL4asp_Types.Result res := {
977 errorCode := omit,
978 connId := omit,
979 os_error_code := omit,
980 os_error_text := omit
981 };
982
Harald Welte12055472018-03-17 20:10:08 +0100983 if (not isbound(clnt) or not isbound(clnt.vc_IPA)) {
984 return;
985 }
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +0100986
987 /* Alive components don't finish sockets (TCP FIN) when they are
988 * stopped. Hence, we need to manually call close() on them to make sure
989 * the IUT knows about it. */
990 f_ipa_cfg_disconnect(IPA_CFG_PORT, res);
991
Harald Welte12055472018-03-17 20:10:08 +0100992 clnt.vc_IPA.stop;
993 if (isbound(clnt.vc_RSL)) {
994 clnt.vc_RSL.stop;
995 }
996}
997
Harald Welte21b46bd2017-12-17 19:46:32 +0100998/* Wait for the OML connection to be brought up by the external osmo-bts-omldummy */
Harald Weltea5d2ab22017-12-09 14:21:42 +0100999function f_wait_oml(integer bts_nr, charstring status, float secs_max) runs on test_CT {
1000 timer T := secs_max;
1001 T.start;
1002 while (true) {
1003 if (f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-connection-state") == status) {
1004 T.stop;
Harald Weltebd868bd2017-12-10 18:28:40 +01001005 /* the 'degraded' state exists from OML connection time, and we have to wait
1006 * until all MO's are initialized */
1007 T.start(1.0);
1008 T.timeout;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001009 return;
1010 }
Harald Weltef0d6ac62017-12-17 17:02:21 +01001011 f_sleep(0.1);
Harald Weltea5d2ab22017-12-09 14:21:42 +01001012 if (not T.running) {
Max99253902018-11-16 17:57:39 +01001013 setverdict(fail, "Timeout waiting for BTS" & int2str(bts_nr) & " oml-connection-state ", status);
Daniel Willmannafce8662018-07-06 23:11:32 +02001014 mtc.stop;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001015 }
1016 }
1017}
1018
Harald Welte21b46bd2017-12-17 19:46:32 +01001019/* global altstep for global guard timer; also takes care of responding RESET witH RESET-ACK */
Harald Welteae026692017-12-09 01:03:01 +01001020altstep as_Tguard() runs on test_CT {
Harald Welte60e823a2017-12-10 14:10:59 +01001021 var BSSAP_N_UNITDATA_ind ud_ind;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001022 [] T_guard.timeout {
1023 setverdict(fail, "Timeout of T_guard");
Daniel Willmannafce8662018-07-06 23:11:32 +02001024 mtc.stop;
Neels Hofmeyrcc3f76a2018-03-12 01:43:25 +01001025 }
Harald Welte60e823a2017-12-10 14:10:59 +01001026 /* always respond with RESET ACK to RESET */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001027 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) -> value ud_ind {
Harald Welte60e823a2017-12-10 14:10:59 +01001028 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001029 ts_BSSMAP_ResetAck(g_osmux_enabled)));
Harald Welte69c1c262017-12-13 21:02:08 +01001030 repeat;
Harald Welte60e823a2017-12-10 14:10:59 +01001031 }
Harald Welte28d943e2017-11-25 15:00:50 +01001032}
1033
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001034altstep no_bssmap_reset() runs on test_CT {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001035 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset(g_osmux_enabled))) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001036 setverdict(fail, "unexpected BSSMAP Reset");
Daniel Willmannafce8662018-07-06 23:11:32 +02001037 mtc.stop;
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01001038 }
1039}
1040
Daniel Willmann191e0d92018-01-17 12:44:35 +01001041function f_init_mgcp(charstring id) runs on test_CT {
1042 id := id & "-MGCP";
1043
1044 var MGCPOps ops := {
1045 create_cb := refers(MGCP_Emulation.ExpectedCreateCallback),
1046 unitdata_cb := refers(MGCP_Emulation.DummyUnitdataCallback)
1047 };
1048 var MGCP_conn_parameters mgcp_pars := {
1049 callagent_ip := mp_bsc_ip,
Harald Welte9e4273e2018-01-29 22:01:22 +01001050 callagent_udp_port := -1,
Daniel Willmann191e0d92018-01-17 12:44:35 +01001051 mgw_ip := mp_test_ip,
Pau Espin Pedrol1a026a52019-06-18 17:21:52 +02001052 mgw_udp_port := 2427,
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02001053 /* Enable it for SCCPlite, since we have 2 MGCP sockets towards MGW (UDP one +
1054 the on with MGCP over IPA forwarded from MSC one) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001055 multi_conn_mode := (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER)
Daniel Willmann191e0d92018-01-17 12:44:35 +01001056 };
1057
Harald Welte71389132021-12-09 21:58:18 +01001058 vc_MGCP := MGCP_Emulation_CT.create(id) alive;
Daniel Willmann191e0d92018-01-17 12:44:35 +01001059 vc_MGCP.start(MGCP_Emulation.main(ops, mgcp_pars, id));
1060}
1061
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001062/* Enable or disable (current default) Osmux. When enabling, BSSMAP Reset
1063 * contains extra IE (OsmuxSupport) and osmo-bsc will handle AssignReq with
1064 * OsmuxCID IE.
1065 */
1066private function f_vty_allow_osmux(boolean allow) runs on test_CT {
1067 f_vty_enter_cfg_msc(BSCVTY, 0);
1068 if (allow) {
1069 f_vty_transceive(BSCVTY, "osmux on");
1070 } else {
1071 f_vty_transceive(BSCVTY, "osmux off");
1072 }
1073 f_vty_transceive(BSCVTY, "exit");
1074 f_vty_transceive(BSCVTY, "exit");
1075 g_osmux_enabled := allow;
1076}
1077
Max2253c0b2018-11-06 19:28:05 +01001078function f_init_vty(charstring id := "foo") runs on test_CT {
Harald Welte94e0c342018-04-07 11:33:23 +02001079 if (BSCVTY.checkstate("Mapped")) {
1080 /* skip initialization if already executed once */
1081 return;
1082 }
Harald Weltebc03c762018-02-12 18:09:38 +01001083 map(self:BSCVTY, system:BSCVTY);
1084 f_vty_set_prompts(BSCVTY);
1085 f_vty_transceive(BSCVTY, "enable");
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01001086 f_cs7_inst_0_cfg(BSCVTY, {"sccp-timer ias " & int2str(g_bsc_sccp_timer_ias),
1087 "sccp-timer iar " & int2str(g_bsc_sccp_timer_iar)});
Harald Weltebc03c762018-02-12 18:09:38 +01001088}
1089
Neels Hofmeyr9f3e6ac2021-04-08 23:09:24 +02001090friend function f_logp(TELNETasp_PT pt, charstring log_msg)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001091{
1092 // log on TTCN3 log output
1093 log(log_msg);
1094 // log in stderr log
Neels Hofmeyr8bdafe52021-12-14 17:25:48 +01001095 if (pt.checkstate("Mapped")) {
1096 f_vty_transceive(pt, "logp lglobal notice TTCN3 f_logp(): " & log_msg);
1097 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02001098}
1099
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001100private function f_sysinfo_seen(integer rsl_idx, RSL_Message rsl) runs on test_CT
1101{
1102 if (rsl_idx >= lengthof(g_system_information)) {
1103 g_system_information[rsl_idx] := SystemInformationConfig_omit
1104 }
1105 f_sysinfo_dec_raw(g_system_information[rsl_idx], rsl);
1106}
1107
1108altstep as_catch_RSL_sysinfo(integer rsl_idx) runs on test_CT {
1109 var ASP_RSL_Unitdata rx_rsl_ud;
1110
1111 /* For handler_mode := false, receiving the RSL bootstrap messages directly on IPA_RSL */
1112 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1113 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1114 repeat;
1115 }
1116 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1117 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1118 repeat;
1119 }
1120 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1121 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1122 repeat;
1123 }
1124 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1125 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1126 repeat;
1127 }
1128
1129 /* For handler_mode := true, receiving the RSL bootstrap messages via RSL_Emulation */
1130 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_BCCH_INFO)) -> value rx_rsl_ud {
1131 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1132 repeat;
1133 }
1134 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO)) -> value rx_rsl_ud {
1135 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1136 repeat;
1137 }
1138 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_NO_SACCH_FILL)) -> value rx_rsl_ud {
1139 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1140 repeat;
1141 }
1142 [] RSL_CCHAN[rsl_idx].receive(tr_ASP_RSL_UD(tr_RSL_SACCH_FILL)) -> value rx_rsl_ud {
1143 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
1144 repeat;
1145 }
1146}
1147
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001148/* TODO: use BooleanList from COMMON/src/General_Types.ttcn */
1149private type record of boolean my_BooleanList;
1150
1151private function f_vty_msc_allow_attach(TELNETasp_PT pt, my_BooleanList allow_attach_list)
1152{
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001153 var charstring config := f_vty_transceive_ret(pt, "show running-config");
1154
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001155 for (var integer msc_nr := 0; msc_nr < sizeof(allow_attach_list); msc_nr := msc_nr+1) {
Neels Hofmeyr8f576712020-08-12 22:49:53 +00001156 if (f_strstr(config, "\nmsc " & int2str(msc_nr) & "\n") < 0) {
1157 /* There is no 'msc N' for this msc_nr in the running config, so don't create an empty msc by
1158 * stepping into that config node. */
1159 log("msc ", msc_nr, " is not configured, skipping");
1160 continue;
1161 }
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001162 f_vty_enter_cfg_msc(pt, msc_nr);
1163 if (allow_attach_list[msc_nr]) {
1164 /* strict := false: ignore if osmo-bsc does not support this config option (latest build) */
1165 f_vty_transceive(pt, "allow-attach", strict := false);
1166 } else {
1167 f_vty_transceive(pt, "no allow-attach", strict := false);
1168 }
1169 f_vty_transceive(pt, "exit");
1170 f_vty_transceive(pt, "exit");
1171 }
1172}
1173
Harald Welte21b46bd2017-12-17 19:46:32 +01001174/* global initialization function
1175 * \param nr_bts Number of BTSs we should start/bring up
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001176 * \param handler_mode Start an RSL_Emulation_CT component (true) or not (false).
1177 * \param nr_msc Number of virtual MSCs to bring up to connect to osmo-bsc.
1178 */
1179function f_init(integer nr_bts := NUM_BTS, boolean handler_mode := false, boolean allow_osmux := false,
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001180 integer nr_msc := 1, float guard_timeout := 30.0) runs on test_CT {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001181 var integer bssap_idx;
Harald Welte28d943e2017-11-25 15:00:50 +01001182
Harald Welteae026692017-12-09 01:03:01 +01001183 if (g_initialized) {
1184 return;
Harald Welte28d943e2017-11-25 15:00:50 +01001185 }
Harald Welteae026692017-12-09 01:03:01 +01001186 g_initialized := true;
1187
Neels Hofmeyr4fbad7f2020-06-16 00:30:47 +02001188 T_guard.start(guard_timeout);
Daniel Willmanne68f9272018-11-27 15:15:28 +01001189 activate(as_Tguard());
1190
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001191 f_init_vty("VirtMSC");
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +02001192 f_vty_allow_osmux(allow_osmux);
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001193
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001194 var my_BooleanList allow_attach := { false, false, false };
Daniel Willmannebdecc02020-08-12 15:30:17 +02001195 f_init_statsd("VirtMSC", vc_STATSD, mp_test_ip, mp_bsc_statsd_port);
1196
Neels Hofmeyr9db8e0e2021-08-23 20:45:58 +02001197 /* Make sure each MSC's internal state is "DISCONNECTED" at first */
1198 for (bssap_idx := 0; bssap_idx < NUM_MSC; bssap_idx := bssap_idx+1) {
1199 f_vty_transceive(BSCVTY, "msc " & int2str(bssap_idx) & " bssmap reset", strict := false);
1200 }
1201
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001202 for (bssap_idx := 0; bssap_idx < nr_msc; bssap_idx := bssap_idx+1) {
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001203 allow_attach[bssap_idx] := true;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001204 /* Call a function of our 'parent component' RAN_Adapter_CT to start the
1205 * MSC-side BSSAP emulation */
1206 if (handler_mode) {
1207 var RanOps ranops := MSC_RanOps;
1208 ranops.use_osmux := g_osmux_enabled;
1209 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", ranops);
1210 connect(self:SCCPLITE_IPA_CTRL, g_bssap[bssap_idx].vc_RAN:CTRL_CLIENT);
1211 f_ran_adapter_start(g_bssap[bssap_idx]);
1212 } else {
1213 f_ran_adapter_init(g_bssap[bssap_idx], mp_bssap_cfg[bssap_idx], "VirtMSC", omit);
1214 connect(self:BSSAP, g_bssap[bssap_idx].vc_SCCP:SCCP_SP_PORT);
1215 f_ran_adapter_start(g_bssap[bssap_idx]);
1216 f_legacy_bssap_reset();
1217 }
Harald Welte67089ee2018-01-17 22:19:03 +01001218 }
Harald Welted5833a82018-05-27 16:52:56 +02001219
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02001220 if (mp_enable_lcs_tests) {
1221 if (handler_mode) {
1222 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", SMLC_BssapLeOps);
1223 } else {
1224 f_bssap_le_adapter_init(g_bssap_le, mp_bssap_le_cfg, "VirtSMLC", omit);
1225 connect(self:BSSAP_LE, g_bssap_le.vc_SCCP:SCCP_SP_PORT);
1226 }
1227 f_bssap_le_adapter_start(g_bssap_le);
Harald Welte47cd0e32020-08-21 12:39:11 +02001228 }
Harald Welte47cd0e32020-08-21 12:39:11 +02001229
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00001230 /* start the test with exactly all enabled MSCs allowed to attach */
1231 f_vty_msc_allow_attach(BSCVTY, allow_attach);
1232
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01001233 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Harald Welte28d943e2017-11-25 15:00:50 +01001234
Daniel Willmann191e0d92018-01-17 12:44:35 +01001235 f_init_mgcp("VirtMSC");
1236
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001237 for (var integer i := 0; i < nr_bts; i := i+1) {
1238 f_init_bts(i, handler_mode);
Harald Welte696ddb62017-12-08 14:01:43 +01001239 }
Neels Hofmeyr9c0f9c82022-01-23 01:20:28 +01001240
1241 /* Emit a marker to appear in the SUT's own logging output */
1242 f_logp(BSCVTY, testcasename() & "() start");
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001243}
Harald Welte696ddb62017-12-08 14:01:43 +01001244
Neels Hofmeyr0b7365b2020-07-04 00:52:34 +02001245function f_init_bts(integer bts_idx := 0, boolean handler_mode := false)
1246runs on test_CT {
1247 /* wait until osmo-bts-omldummy has respawned */
1248 f_wait_oml(bts_idx, "degraded", 5.0);
1249
1250 /* start RSL connection */
1251 f_ipa_rsl_start(bts[bts_idx].rsl, mp_bsc_ip, mp_bsc_rsl_port, bts_idx, handler_mode);
1252 /* wait until BSC tells us "connected" */
1253 f_wait_oml(bts_idx, "connected", 5.0);
Harald Welte28d943e2017-11-25 15:00:50 +01001254}
1255
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02001256function f_init_bts_and_check_sysinfo(integer bts_idx := 0, boolean handler_mode := false,
1257 template SystemInformationConfig expect_si)
1258runs on test_CT {
1259 var default sysinfo := activate(as_catch_RSL_sysinfo(bts_idx));
1260
1261 f_init_bts(bts_idx, handler_mode);
1262
1263 /* Give some time to (hopefully/most likely) collect all system informations from RSL startup.
1264 * We could stop as soon as all expected SI are received, but then we might miss SI that we don't expect and
1265 * that might be sent afterwards. So rather give a generous timeout and be quite sure to catch all SI.
1266 */
1267 f_sleep(5.0);
1268 log("RSL ", bts_idx, " SYSTEM INFORMATION: ", g_system_information[bts_idx]);
1269
1270 deactivate(sysinfo);
1271
1272 if (match(g_system_information[bts_idx], expect_si)) {
1273 setverdict(pass);
1274 } else {
1275 log("RSL ", bts_idx, ": EXPECTED SI: ", expect_si);
1276 log("RSL ", bts_idx, ": GOT SI: ", g_system_information[bts_idx]);
1277 setverdict(fail, "received SI does not match expectations");
1278 return;
1279 }
1280}
1281
Maxd4e56962018-10-31 19:08:25 +01001282/* expect to receive a RSL message matching a specified template on a given BTS / stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001283function 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 +01001284runs on test_CT return RSL_Message {
1285 var ASP_RSL_Unitdata rx_rsl_ud;
1286 timer T := t_secs;
1287
1288 T.start;
1289 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001290 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
Harald Welteae026692017-12-09 01:03:01 +01001291 T.stop;
1292 }
1293 [] IPA_RSL[bts_nr].receive { repeat; }
Harald Welteb2917702017-12-10 15:48:52 +01001294 [] T.timeout {
1295 setverdict(fail, "Timeout expecting ", t_rx);
Daniel Willmannafce8662018-07-06 23:11:32 +02001296 mtc.stop;
Harald Welteb2917702017-12-10 15:48:52 +01001297 }
Harald Welteae026692017-12-09 01:03:01 +01001298 }
1299 return rx_rsl_ud.rsl;
1300}
1301
Harald Welte21b46bd2017-12-17 19:46:32 +01001302/* helper function to transmit RSL on a given BTS/stream */
Harald Welte65e419a2020-08-21 12:38:33 +02001303function 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 +01001304runs on test_CT {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001305 IPA_RSL[bts_nr].send(ts_ASP_RSL_UD(t_tx, sid));
Harald Welteae026692017-12-09 01:03:01 +01001306}
1307
1308
Harald Welte4003d112017-12-09 22:35:39 +01001309/* verify we get a CHAN_ACT after CHAN RQD */
Harald Welteae026692017-12-09 01:03:01 +01001310testcase TC_chan_act_noreply() runs on test_CT {
1311 var BSSAP_N_UNITDATA_ind ud_ind;
Harald Welte930d0a72018-03-22 22:08:40 +01001312 var RSL_Message rsl_unused;
Harald Welte28d943e2017-11-25 15:00:50 +01001313
Harald Welte89d42e82017-12-17 16:42:41 +01001314 f_init(1);
Harald Welte28d943e2017-11-25 15:00:50 +01001315
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001316 IPA_RSL[0].send(ts_ASP_RSL_UD(ts_RSL_CHAN_RQD('23'O, 23)));
Harald Welte930d0a72018-03-22 22:08:40 +01001317 rsl_unused := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001318 f_shutdown_helper();
Harald Welte28d943e2017-11-25 15:00:50 +01001319}
1320
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001321const CounterNameVals counternames_bts_chreq := {
1322 { "chreq:total", 0 },
1323 { "chreq:attempted_emerg", 0 },
1324 { "chreq:attempted_call", 0 },
1325 { "chreq:attempted_location_upd", 0 },
1326 { "chreq:attempted_pag", 0 },
1327 { "chreq:attempted_pdch", 0 },
1328 { "chreq:attempted_other", 0 },
1329 { "chreq:attempted_unknown", 0 },
1330 { "chreq:successful", 0 },
1331 { "chreq:successful_emerg", 0 },
1332 { "chreq:successful_call", 0 },
1333 { "chreq:successful_location_upd", 0 },
1334 { "chreq:successful_pag", 0 },
1335 { "chreq:successful_pdch", 0 },
1336 { "chreq:successful_other", 0 },
1337 { "chreq:successful_unknown", 0 },
1338 { "chreq:no_channel", 0 },
1339 { "chreq:max_delay_exceeded", 0 }
1340};
1341
1342/* verify the "chreq:*" counters */
1343private function f_chan_act_counter(OCT1 ra, charstring chreq_ctr_suffix) runs on test_CT
1344{
1345 var GsmFrameNumber fn := 23;
1346
1347 f_logp(BSCVTY, "f_chan_act_counter(" & chreq_ctr_suffix & ")");
1348
1349 var RSL_Message rx_rsl;
1350 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1351 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1352 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1353
1354 f_ctrs_bts_add(0, "chreq:total");
1355 f_ctrs_bts_add(0, "chreq:attempted_" & chreq_ctr_suffix);
1356 f_ctrs_bts_verify();
1357
1358 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
1359 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1360
1361 f_ctrs_bts_add(0, "chreq:successful");
1362 f_ctrs_bts_add(0, "chreq:successful_" & chreq_ctr_suffix);
1363 f_ctrs_bts_verify();
1364
1365 /* test is done, release RSL Conn Fail Ind to clean up */
1366 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1367 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1368 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
1369 f_sleep(1.0);
1370}
1371
Harald Welte4003d112017-12-09 22:35:39 +01001372testcase TC_chan_act_counter() runs on test_CT {
1373 var BSSAP_N_UNITDATA_ind ud_ind;
1374 var integer chreq_total;
Harald Welte930d0a72018-03-22 22:08:40 +01001375 var RSL_Message rsl_unused;
Harald Welte4003d112017-12-09 22:35:39 +01001376
Harald Welte89d42e82017-12-17 16:42:41 +01001377 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001378
Neels Hofmeyr734b1a32021-11-29 16:00:17 +01001379 f_vty_allow_emerg_bts(true, 0);
1380
1381 f_ctrs_bts_init(1, counternames_bts_chreq);
1382
1383 /* emergency call: RA & 0xe0 == 0xa0 --> CHREQ_T_EMERG_CALL */
1384 f_chan_act_counter('a3'O, "emerg");
1385
1386 /* voice TCH/H: RA & 0xf0 == 0x40 --> CHREQ_T_VOICE_CALL_TCH_H */
1387 f_chan_act_counter('43'O, "call");
1388
1389 /* LU: RA & 0xf0 == 0x00 --> CHREQ_T_LOCATION_UPD */
1390 f_chan_act_counter('03'O, "location_upd");
1391
1392 /* Paging: RA & 0xf0 == 0x20 --> CHREQ_T_PAG_R_TCH_F */
1393 f_chan_act_counter('23'O, "pag");
1394 /* Paging: RA & 0xf0 == 0x30 --> CHREQ_T_PAG_R_TCH_FH */
1395 f_chan_act_counter('33'O, "pag");
1396
1397 /* LU: RA & 0xfc == 0x78 --> CHREQ_T_PDCH_TWO_PHASE */
1398 /* no PCU, so PDCH not allowed. Skip this test for now. */
1399 /* f_chan_act_counter('7b'O, "pdch"); */
1400
1401 /* LU: RA & 0xf0 == 0x10 --> CHREQ_T_SDCCH */
1402 f_chan_act_counter('13'O, "other");
Harald Welte4003d112017-12-09 22:35:39 +01001403
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001404 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001405}
1406
Harald Welteae026692017-12-09 01:03:01 +01001407/* CHAN RQD -> CHAN ACT -> CHAN ACT ACK -> RF CHAN REL */
Philipp Maier9c60a622020-07-09 15:08:46 +02001408private function f_TC_chan_act_ack_noest(OCT1 ra := '23'O) runs on test_CT {
Harald Welteae026692017-12-09 01:03:01 +01001409 var RSL_Message rx_rsl;
1410
Harald Welteae026692017-12-09 01:03:01 +01001411 /* Send CHAN RQD and wait for allocation; acknowledge it */
Philipp Maier9c60a622020-07-09 15:08:46 +02001412 var RslChannelNr chan_nr := f_chreq_act_ack(ra);
Harald Welteae026692017-12-09 01:03:01 +01001413
1414 /* expect BSC to disable the channel again if there's no RLL EST IND */
1415 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1416
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001417 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001418}
1419
Philipp Maier9c60a622020-07-09 15:08:46 +02001420/* Normal variant */
1421testcase TC_chan_act_ack_noest() runs on test_CT {
Philipp Maieraf58db22020-08-12 17:24:40 +02001422 f_init(1);
Philipp Maier9c60a622020-07-09 15:08:46 +02001423 f_TC_chan_act_ack_noest();
1424}
1425
1426/* Emergency call variant */
1427testcase TC_chan_act_ack_noest_emerg() runs on test_CT {
1428 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
Philipp Maieraf58db22020-08-12 17:24:40 +02001429 f_init(1);
1430 f_vty_allow_emerg_bts(true, 0);
Philipp Maier9c60a622020-07-09 15:08:46 +02001431 f_TC_chan_act_ack_noest(ra := 'A5'O);
1432}
1433
Philipp Maier606f07d2020-08-12 17:21:58 +02001434/* Emergency call variant, but emergency calls are not allowed */
1435testcase TC_chan_rqd_emerg_deny() runs on test_CT {
1436 /* See also: 3GPP TS 04.08, Table 9.9, ra=101xxxxx */
1437
1438 var RSL_Message rx_rsl;
1439 var GsmRrMessage rr;
1440
1441 f_init(1);
1442 f_vty_allow_emerg_bts(false, 0);
1443
1444 IPA_RSL[0].clear;
1445 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
1446
1447 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
1448 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
1449 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1450 setverdict(pass);
1451 } else {
1452 setverdict(fail, "immediate assignment not rejected");
1453 }
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01001454
1455 f_shutdown_helper();
Philipp Maier606f07d2020-08-12 17:21:58 +02001456}
1457
Harald Welteae026692017-12-09 01:03:01 +01001458/* Test behavior if MSC never answers to CR */
1459testcase TC_chan_act_ack_est_ind_noreply() runs on test_CT {
Harald Weltef77aef62018-01-28 15:35:42 +01001460 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
1461 var IpaStreamId sid := IPAC_PROTO_RSL_TRX0;
Harald Welteae026692017-12-09 01:03:01 +01001462 var RSL_Message rx_rsl;
Harald Weltef77aef62018-01-28 15:35:42 +01001463 var ASP_RSL_Unitdata rx_rsl_ud;
Harald Welteae026692017-12-09 01:03:01 +01001464
Harald Welte89d42e82017-12-17 16:42:41 +01001465 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001466
1467 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001468 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001469
1470 var octetstring l3 := '00010203040506'O
1471 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1472
1473 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3)));
1474
1475 /* expect BSC to disable the channel again if there's no response from MSC */
Harald Weltef77aef62018-01-28 15:35:42 +01001476 /* MS waits 20s (T3210) at LU; 10s (T3230) at CM SERV REQ and 5s (T3220) AT detach */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001477 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001478 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001479}
1480
1481/* Test behavior if MSC answers with CREF to CR */
1482testcase TC_chan_act_ack_est_ind_refused() runs on test_CT {
1483 var BSSAP_N_CONNECT_ind rx_c_ind;
1484 var RSL_Message rx_rsl;
1485
Harald Welte89d42e82017-12-17 16:42:41 +01001486 f_init(1);
Harald Welteae026692017-12-09 01:03:01 +01001487
1488 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001489 var RslChannelNr chan_nr := f_chreq_act_ack();
Harald Welteae026692017-12-09 01:03:01 +01001490
1491 var octetstring l3 := '00010203040506'O
1492 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1493
1494 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1495 BSSAP.send(ts_BSSAP_DISC_req(rx_c_ind.connectionId, 0));
1496
1497 /* expect BSC to disable the channel */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01001498 f_expect_chan_rel(0, chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001499 f_shutdown_helper();
Harald Welteae026692017-12-09 01:03:01 +01001500}
1501
Harald Welte618ef642017-12-14 14:58:20 +01001502/* CHAN RQD -> CHAN ACT -> CHAN ACT NACK -> RF CHAN REL */
1503testcase TC_chan_act_nack() runs on test_CT {
1504 var RSL_Message rx_rsl;
1505 var integer chact_nack;
1506
Harald Welte89d42e82017-12-17 16:42:41 +01001507 f_init(1);
Harald Welte618ef642017-12-14 14:58:20 +01001508
1509 chact_nack := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack");
1510
1511 f_ipa_tx(0, ts_RSL_CHAN_RQD('33'O, 33));
1512 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1513 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1514
1515 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
1516
1517 /* wait for some time to hope the NACK arrives before the CTRL GET below */
1518 f_sleep(0.5);
1519
1520 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chan_act:nack", chact_nack+1);
1521
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001522 f_shutdown_helper();
Harald Welte618ef642017-12-14 14:58:20 +01001523}
1524
Harald Welte799c97b2017-12-14 17:50:30 +01001525/* Test for channel exhaustion due to RACH overload */
1526testcase TC_chan_exhaustion() runs on test_CT {
1527 var ASP_RSL_Unitdata rsl_ud;
1528 var integer i;
1529 var integer chreq_total, chreq_nochan;
1530
Harald Welte89d42e82017-12-17 16:42:41 +01001531 f_init(1);
Harald Welte799c97b2017-12-14 17:50:30 +01001532
1533 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
1534 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
1535
Neels Hofmeyr85fa37f2021-10-06 13:50:38 +02001536 /* GSM 44.018 Table 9.1.8.2:
Pau Espin Pedrolfe200d72018-12-10 12:41:04 +01001537 * RA = '33'O -> Establishment cause = 0011xxxx (MS dual rate capable and asks for "TCH/H or TCH/F").
1538 * With current setup, expect 4xSDCCH + 4xTCH/F + 1xTCH/H to succeed */
Philipp Maiercb6cc482018-03-26 13:08:00 +02001539 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 +01001540 var RslChannelNr chan_nr := f_chreq_act_ack('33'O, i);
Harald Welte799c97b2017-12-14 17:50:30 +01001541 }
1542
1543 IPA_RSL[0].clear;
1544
Harald Weltedd8cbf32018-01-28 12:07:52 +01001545 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001546 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
Harald Welte799c97b2017-12-14 17:50:30 +01001547
1548 /* now expect additional channel activations to fail */
1549 f_ipa_tx(0, ts_RSL_CHAN_RQD('42'O, 42));
1550
1551 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001552 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV))) {
Harald Welte799c97b2017-12-14 17:50:30 +01001553 setverdict(fail, "Received CHAN ACT ACK without resources?!?");
1554 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001555 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) -> value rsl_ud {
Harald Welte799c97b2017-12-14 17:50:30 +01001556 var GsmRrMessage rr;
1557 /* match on IMM ASS REJ */
1558 rr := dec_GsmRrMessage(rsl_ud.rsl.ies[1].body.full_imm_ass_info.payload);
1559 if (rr.header.message_type == IMMEDIATE_ASSIGNMENT_REJECT) {
1560 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
Philipp Maiercb6cc482018-03-26 13:08:00 +02001561 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS+1);
Harald Welte799c97b2017-12-14 17:50:30 +01001562 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel",
1563 chreq_nochan+1);
1564 setverdict(pass);
1565 } else {
1566 repeat;
1567 }
1568 }
1569 [] IPA_RSL[0].receive { repeat; }
1570 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001571 f_shutdown_helper();
Harald Welte799c97b2017-12-14 17:50:30 +01001572}
1573
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001574/* Test channel deactivation due to silence from MS */
1575testcase TC_chan_deact_silence() runs on test_CT {
1576 var RslChannelNr chan_nr;
1577
1578 f_init(1);
1579
1580 /* Request for a dedicated channel */
1581 chan_nr := f_chreq_act_ack('23'O);
1582
1583 /* Wait some time until the channel is released */
1584 f_sleep(2.0);
1585
1586 /* Expect CHANnel RELease */
1587 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001588 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001589 log("Received CHANnel RELease");
1590 setverdict(pass);
1591 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07001592 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_IMM_ASSIGN(?))) {
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001593 /* See OS#3709, OsmoBSC should not send Immediate
1594 * Assignment Reject since a dedicated channel was
1595 * already allocated, and Immediate Assignment was
1596 * already sent. */
1597 setverdict(fail, "Unexpected Immediate Assignment!");
1598 }
1599 [] IPA_RSL[0].receive {
1600 setverdict(fail, "Unexpected RSL message!");
1601 }
1602 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001603 f_shutdown_helper();
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +07001604}
1605
Harald Weltecfe2c962017-12-15 12:09:32 +01001606/***********************************************************************
1607 * Assignment Testing
1608 ***********************************************************************/
1609
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02001610/* Verify that the BSC refuses any BSSAP connection from the MSC (They are all BSC->MSC direction,
1611 * except for the inter-BSC handover, MT side) */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001612testcase TC_outbound_connect(integer bssap_idx := 0) runs on test_CT {
Harald Welte89d42e82017-12-17 16:42:41 +01001613 f_init(1);
Harald Weltecfe2c962017-12-15 12:09:32 +01001614
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001615 BSSAP.send(ts_BSSAP_CONNECT_req(g_bssap[bssap_idx].sccp_addr_peer, g_bssap[bssap_idx].sccp_addr_own,
1616 2342, ts_BSSMAP_AssignmentReq));
Harald Weltecfe2c962017-12-15 12:09:32 +01001617 BSSAP.receive(tr_BSSAP_DISC_ind(2342, ?, ?));
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001618 f_shutdown_helper();
Harald Weltecfe2c962017-12-15 12:09:32 +01001619}
1620
Harald Welte16a4adf2017-12-14 18:54:01 +01001621/* Test behavior if MSC answers with CREF to CR */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001622testcase TC_assignment_cic_only(integer bssap_idx := 0) runs on test_CT {
Harald Welte16a4adf2017-12-14 18:54:01 +01001623 var BSSAP_N_CONNECT_ind rx_c_ind;
1624 var RSL_Message rx_rsl;
1625 var DchanTuple dt;
1626
Harald Welte89d42e82017-12-17 16:42:41 +01001627 f_init(1);
Harald Welte16a4adf2017-12-14 18:54:01 +01001628
1629 dt := f_est_dchan('23'O, 23, '00000000'O);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001630 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte17b27da2018-05-25 20:33:53 +02001631 /* send assignment without AoIP IEs */
1632 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(ts_BSSMAP_IE_CIC(0, 1))));
1633 } else {
1634 /* Send assignmetn without CIC in IPA case */
1635 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
1636 valueof(ts_BSSMAP_IE_AoIP_TLA4('01020304'O, 2342));
1637 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_AssignmentReq(omit, tla)));
1638 }
Harald Welte16a4adf2017-12-14 18:54:01 +01001639 alt {
1640 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1641 setverdict(fail, "AoIP BSC cannot accept ASSIGNMENT without AoIP Transport IE");
1642 }
Harald Welte235ebf12017-12-15 14:18:16 +01001643 /* TODO: Actually expect GSM0808_CAUSE_REQ_A_IF_TYPE_NOT_SUPP */
Harald Welte16a4adf2017-12-14 18:54:01 +01001644 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1645 setverdict(pass);
1646 }
1647 [] BSSAP.receive { repeat; }
1648 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001649 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001650 f_shutdown_helper();
Harald Welte16a4adf2017-12-14 18:54:01 +01001651}
1652
Harald Welteed848512018-05-24 22:27:58 +02001653/* generate an assignment request for either AoIP or SCCPlite */
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001654function 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 +02001655 var PDU_BSSAP ass_cmd;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001656 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001657 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welteed848512018-05-24 22:27:58 +02001658 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001659 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001660 if (osmux_enabled) {
1661 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla, osmux_cid));
1662 } else {
1663 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(omit, tla));
1664 }
Harald Welteed848512018-05-24 22:27:58 +02001665 } else {
1666 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001667 ass_cmd := valueof(ts_BSSMAP_AssignmentReq(cic, omit));
Harald Welteed848512018-05-24 22:27:58 +02001668 }
1669 return ass_cmd;
1670}
1671
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02001672function f_gen_handover_req(integer bssap_idx := 0, charstring aoip_tla := "1.2.3.4",
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001673 template (value) BSSMAP_IE_CellIdentifier cell_id_source := ts_CellID_LAC_CI(1, 1),
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001674 template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit,
1675 template (omit) TestHdlrEncrParams enc := omit) return PDU_BSSAP {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001676 var PDU_BSSAP ho_req;
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001677
1678 var BSSMAP_IE_EncryptionInformation encryptionInformation :=
1679 valueof(ts_BSSMAP_IE_EncrInfo('0000000000000000'O,'01'O));
1680 var template BSSMAP_IE_ChosenEncryptionAlgorithm chosenEncryptionAlgorithm := omit;
1681 var template BSSMAP_IE_KC128 kc128 := omit;
1682 if (ispresent(enc)) {
1683 var TestHdlrEncrParams v_enc := valueof(enc);
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01001684 encryptionInformation := valueof(ts_BSSMAP_IE_EncrInfo(v_enc.enc_key, v_enc.enc_alg_permitted));
1685 if (ispresent(v_enc.enc_alg_chosen)) {
1686 chosenEncryptionAlgorithm := valueof(
1687 ts_BSSMAP_IE_ChosenEncryptionAlgorithm(int2oct(enum2int(
1688 f_cipher_mode_bssmap_to_rsl(v_enc.enc_alg_chosen)), 1)));
1689 }
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001690 if (ispresent(v_enc.enc_kc128)) {
1691 kc128 := ts_BSSMAP_IE_Kc128(v_enc.enc_kc128);
1692 }
1693 }
1694
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001695 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001696 var BSSMAP_IE_AoIP_TransportLayerAddress tla :=
Pau Espin Pedrol07866632020-09-03 19:10:55 +02001697 valueof(f_ts_BSSMAP_IE_AoIP_TLA(aoip_tla, 2342));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001698 ho_req := valueof(ts_BSSMAP_HandoverRequest(omit, tla,
1699 cell_id_source := cell_id_source,
1700 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001701 encryptionInformation := encryptionInformation,
1702 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
Neels Hofmeyr9fe13202022-03-04 00:05:43 +01001703 kC128 := kc128,
1704 /* on AoIP, allow "all" codecs (until we add more concise
1705 * tests) */
1706 codecList := ts_BSSMAP_IE_CodecList(
1707 {ts_CodecAMR_F, ts_CodecAMR_H,
1708 ts_CodecEFR, ts_CodecFR, ts_CodecHR})));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001709 } else {
1710 var BSSMAP_IE_CircuitIdentityCode cic := valueof(ts_BSSMAP_IE_CIC(0,1));
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01001711 ho_req := valueof(ts_BSSMAP_HandoverRequest(cic, omit,
1712 cell_id_source := cell_id_source,
1713 oldToNewBSSIEs := oldToNewBSSIEs,
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02001714 encryptionInformation := encryptionInformation,
1715 chosenEncryptionAlgorithm := chosenEncryptionAlgorithm,
1716 kC128 := kc128));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01001717 }
1718 return ho_req;
1719}
1720
Harald Welteed848512018-05-24 22:27:58 +02001721/* generate an assignment complete template for either AoIP or SCCPlite */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001722function f_gen_exp_compl(boolean expect_osmux := false, integer bssap_idx := 0) return template PDU_BSSAP {
Harald Welteed848512018-05-24 22:27:58 +02001723 var template PDU_BSSAP exp_compl;
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001724 var BSSMAP_IE_Osmo_OsmuxCID osmux_cid := valueof(ts_OsmuxCID(0));
Neels Hofmeyrf246a922020-05-13 02:27:10 +02001725 if (mp_bssap_cfg[bssap_idx].transport == BSSAP_TRANSPORT_AoIP) {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02001726 if (expect_osmux) {
1727 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, osmux_cid);
1728 } else {
1729 exp_compl := tr_BSSMAP_AssignmentComplete(omit, ?, omit);
1730 }
Harald Welteed848512018-05-24 22:27:58 +02001731 } else {
1732 /* CIC is optional "*" as the MSC allocated it */
Pau Espin Pedrol096d73d2019-06-06 12:49:17 +02001733 exp_compl := tr_BSSMAP_AssignmentComplete(*, omit);
Harald Welteed848512018-05-24 22:27:58 +02001734 }
1735 return exp_compl;
1736}
1737
Harald Welte235ebf12017-12-15 14:18:16 +01001738/* Run everything required up to sending a caller-specified assignment command and expect response */
1739function f_assignment_exp(PDU_BSSAP ass_cmd, template PDU_BSSAP exp, charstring fail_text)
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001740runs on test_CT return DchanTuple {
Harald Welte235ebf12017-12-15 14:18:16 +01001741 var BSSAP_N_CONNECT_ind rx_c_ind;
1742 var RSL_Message rx_rsl;
1743 var DchanTuple dt;
1744
Harald Welte89d42e82017-12-17 16:42:41 +01001745 f_init(1);
Harald Welte235ebf12017-12-15 14:18:16 +01001746
1747 dt := f_est_dchan('23'O, 23, '00000000'O);
1748 /* send assignment without AoIP IEs */
1749 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
1750 alt {
1751 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentComplete)) {
1752 if (ischosen(exp.pdu.bssmap.assignmentComplete)) {
1753 setverdict(pass);
1754 } else {
1755 setverdict(fail, fail_text);
1756 }
1757 }
1758 [] BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_AssignmentFail)) {
1759 if (ischosen(exp.pdu.bssmap.assignmentFailure)) {
1760 setverdict(pass);
1761 } else {
1762 setverdict(fail, fail_text);
1763 }
1764 }
1765 [] BSSAP.receive { repeat; }
1766 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01001767 return dt;
Harald Welte235ebf12017-12-15 14:18:16 +01001768}
1769testcase TC_assignment_csd() runs on test_CT {
1770 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001771 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001772 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1773 //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 +01001774 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for CSD");
1775 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001776 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001777}
1778
1779testcase TC_assignment_ctm() runs on test_CT {
1780 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02001781 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte235ebf12017-12-15 14:18:16 +01001782 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCTM);
1783 //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 +01001784 var DchanTuple dt := f_assignment_exp(ass_cmd, exp_fail, "BSC accepted Assignment for Speech+CTM");
1785 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001786 f_shutdown_helper();
Harald Welte235ebf12017-12-15 14:18:16 +01001787}
1788
Harald Welte4003d112017-12-09 22:35:39 +01001789type record DchanTuple {
1790 integer sccp_conn_id,
1791 RslChannelNr rsl_chan_nr
Harald Weltea5d2ab22017-12-09 14:21:42 +01001792}
1793
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +02001794type record of DchanTuple DchanTuples;
1795
Harald Welted6939652017-12-13 21:02:46 +01001796/* Send CHAN RQD and wait for allocation; acknowledge it */
1797private function f_chreq_act_ack(OCT1 ra := '23'O, GsmFrameNumber fn := 23)
1798runs on test_CT return RslChannelNr {
1799 var RSL_Message rx_rsl;
1800 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1801 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1802 var RslChannelNr chan_nr := rx_rsl.ies[0].body.chan_nr;
1803 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
Daniel Willmannf4ac4ce2018-08-02 14:06:30 +02001804 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Harald Welted6939652017-12-13 21:02:46 +01001805 return chan_nr;
1806}
1807
Harald Welte4003d112017-12-09 22:35:39 +01001808/* helper function to establish a dedicated channel via BTS and MSC */
1809function f_est_dchan(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1810runs on test_CT return DchanTuple {
1811 var BSSAP_N_CONNECT_ind rx_c_ind;
Harald Welte4003d112017-12-09 22:35:39 +01001812 var DchanTuple dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001813
Harald Welte4003d112017-12-09 22:35:39 +01001814 /* Send CHAN RQD and wait for allocation; acknowledge it */
Harald Welted6939652017-12-13 21:02:46 +01001815 dt.rsl_chan_nr := f_chreq_act_ack(ra, fn);
Harald Welte4003d112017-12-09 22:35:39 +01001816
1817 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1818
1819 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1820 dt.sccp_conn_id := rx_c_ind.connectionId;
1821 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1822
1823 return dt;
Harald Weltea5d2ab22017-12-09 14:21:42 +01001824}
1825
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02001826/* Like f_est_dchan(), but for the first lchan of a dynamic timeslot: first ACK the deactivation of PDCH. */
1827function f_est_dchan_dyn(OCT1 ra, GsmFrameNumber fn, octetstring l3)
1828runs on test_CT return DchanTuple {
1829 var BSSAP_N_CONNECT_ind rx_c_ind;
1830 var DchanTuple dt;
1831
1832 /* Send CHAN RQD */
1833 var RSL_Message rx_rsl;
1834 f_ipa_tx(0, ts_RSL_CHAN_RQD(ra, fn));
1835
1836 /* The dyn TS first deactivates PDCH */
1837 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1838 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1839 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1840
1841 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
1842 dt.rsl_chan_nr := rx_rsl.ies[0].body.chan_nr;
1843
1844 /* Now activates the signalling channel */
1845 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, fn+10));
1846 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
1847
1848 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
1849
1850 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
1851 dt.sccp_conn_id := rx_c_ind.connectionId;
1852 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
1853
1854 return dt;
1855}
1856
Harald Welte641fcbe2018-06-14 10:58:35 +02001857/* expect RF CAN REL from BTS, acknowledge it and clear the MSC side */
1858private function f_exp_chan_rel_and_clear(DchanTuple dt, integer bts_nr := 0) runs on test_CT {
1859 var RSL_Message rx_rsl;
1860 /* expect BSC to disable the channel */
1861 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), T3101_MAX);
1862 /* respond with CHAN REL ACK */
1863 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1864
1865 /* expect Clear Complete from BSC */
1866 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1867
1868 /* MSC disconnects as instructed. */
1869 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1870}
1871
Harald Welte4003d112017-12-09 22:35:39 +01001872/* Test behavior of channel release after unilateral RLL REL IND (DISC from MS) */
1873testcase TC_chan_rel_rll_rel_ind() runs on test_CT {
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001874 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001875 var DchanTuple dt;
Harald Welte96c94412017-12-09 03:12:45 +01001876
Harald Welte89d42e82017-12-17 16:42:41 +01001877 f_init(1);
Harald Welte96c94412017-12-09 03:12:45 +01001878
Harald Welte4003d112017-12-09 22:35:39 +01001879 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1880
1881 /* simulate RLL REL IND */
1882 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
1883
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001884 /* expect Clear Request on MSC side */
1885 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1886
1887 /* Instruct BSC to clear channel */
1888 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1889 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1890
Harald Welte4003d112017-12-09 22:35:39 +01001891 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001892 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr27f64362018-03-12 01:44:00 +01001893
1894 /* wait for SCCP emulation to do its job */
1895 f_sleep(1.0);
Harald Welte4003d112017-12-09 22:35:39 +01001896
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001897 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001898}
1899
1900/* Test behavior of channel release after CONN FAIL IND from BTS */
1901testcase TC_chan_rel_conn_fail() runs on test_CT {
1902 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01001903 var DchanTuple dt;
1904
Harald Welte89d42e82017-12-17 16:42:41 +01001905 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01001906
1907 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1908
1909 /* simulate CONN FAIL IND */
Harald Weltea8ed9062017-12-14 09:46:01 +01001910 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 +01001911 /* TODO: different cause values? */
1912
Harald Welte4003d112017-12-09 22:35:39 +01001913 /* expect Clear Request from BSC */
1914 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
1915
1916 /* Instruct BSC to clear channel */
1917 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
1918 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
1919
Harald Welte6ff76ea2018-01-28 13:08:01 +01001920 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02001921 f_exp_chan_rel_and_clear(dt, 0);
Harald Welte4003d112017-12-09 22:35:39 +01001922
1923 /* wait for SCCP emulation to do its job */
1924 f_sleep(1.0);
1925
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001926 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01001927}
1928
Harald Welte99f3ca02018-06-14 13:40:29 +02001929/* Test behavior of early CONN FAIL IND from BTS (before EST IND!) */
1930/* See also https://www.osmocom.org/issues/3182 */
1931testcase TC_early_conn_fail() runs on test_CT {
1932 var RSL_Message rx_rsl;
1933 var DchanTuple dt;
1934
1935 f_init(1);
1936
1937 /* BTS->BSC: Send CHAN RQD and wait for allocation; acknowledge it */
Harald Weltec46ea3c2020-10-10 18:46:12 +02001938 dt.rsl_chan_nr := f_chreq_act_ack(f_rnd_ra_cs(), 23);
Harald Welte99f3ca02018-06-14 13:40:29 +02001939
1940 /* BTS->BSC: simulate CONN FAIL IND */
1941 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1942
1943 /* BTS->BSC: Expect RF channel release from BSC on Abis */
1944 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1945
1946 /* BTS<-BSC: respond with CHAN REL ACK */
1947 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1948
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001949 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001950}
1951
1952/* Test behavior of late CONN FAIL IND from BTS (ater REL IND!) */
1953/* See also https://www.osmocom.org/issues/3182 */
1954testcase TC_late_conn_fail() runs on test_CT {
1955 var RSL_Message rx_rsl;
1956 var DchanTuple dt;
1957
1958 f_init(1);
1959
1960 dt := f_est_dchan('23'O, 23, '00010203040506'O);
1961
1962 /* BSC<-MSC: Instruct BSC to clear connection */
1963 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(0)));
1964
1965 /* BTS->BSC: expect BSC to deactivate SACCH */
1966 rx_rsl := f_exp_ipa_rx(0, tr_RSL_DEACT_SACCH(dt.rsl_chan_nr));
1967
1968 /* BTS->BSC: simulate a late CONN FAIL IND from BTS */
1969 f_ipa_tx(0, ts_RSL_CONN_FAIL_IND(dt.rsl_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
1970
1971 /* BTS<-BSC: Expect RF channel release from BSC on Abis */
1972 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL), 10.0);
1973 /* BTS->BSC: respond with CHAN REL ACK */
1974 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(dt.rsl_chan_nr));
1975
1976 /* BSC->MSC: expect Clear Complete from BSC */
1977 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete));
1978
1979 /* BSC<-MSC: MSC disconnects as requested. */
1980 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
1981
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02001982 f_shutdown_helper();
Harald Welte99f3ca02018-06-14 13:40:29 +02001983}
1984
Oliver Smithaf03bef2021-08-24 15:34:51 +02001985private function f_TC_stats_conn_fail(charstring id) runs on MSC_ConnHdlr {
1986 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
1987 var PDU_BSSAP ass_cmd := f_gen_ass_req();
1988
1989 f_statsd_reset();
1990
1991 /* Establish SDCCH */
1992 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeCSD);
1993 f_establish_fully(ass_cmd, exp_fail);
1994
1995 /* Expect stats to be 0 */
1996 var StatsDExpects expect := {
1997 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 0, max := 0},
1998 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 0, max := 0}
1999 };
2000 f_statsd_expect(expect);
2001
2002 /* Simulate CONN FAIL IND on SDCCH */
2003 RSL.send(ts_ASP_RSL_UD(
2004 ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL),
2005 IPAC_PROTO_RSL_TRX0));
2006
Neels Hofmeyr58be48a2021-09-07 18:39:21 +02002007 f_sleep(1.0);
2008
Oliver Smithaf03bef2021-08-24 15:34:51 +02002009 /* Expect stats to be 1 */
2010 expect := {
2011 {name := "TTCN3.bts.0.chan.rf_fail", mtype := "c", min := 1, max := 1},
2012 {name := "TTCN3.bts.0.chan.rf_fail_sdcch", mtype := "c", min := 1, max := 1}
2013 };
2014 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002015 BSSAP.receive(tr_BSSMAP_ClearRequest);
2016 f_perform_clear();
Oliver Smithaf03bef2021-08-24 15:34:51 +02002017}
2018testcase TC_stats_conn_fail() runs on test_CT {
2019 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2020 var MSC_ConnHdlr vc_conn;
2021
2022 f_init(1, true);
2023 f_sleep(1.0);
2024
2025 vc_conn := f_start_handler(refers(f_TC_stats_conn_fail), pars);
2026 vc_conn.done;
2027
2028 f_shutdown_helper();
2029}
2030
Neels Hofmeyrf44ccd12018-11-05 19:15:23 +01002031function f_expect_chan_rel(integer bts_nr, RslChannelNr rsl_chan_nr,
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002032 boolean expect_deact_sacch := true,
2033 boolean expect_rr_chan_rel := true,
2034 boolean expect_rll_rel_req := true,
Harald Welte99787102019-02-04 10:41:36 +01002035 boolean handle_rll_rel := true,
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002036 template CellSelIndValue expect_cells := omit,
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002037 template RR_Cause expect_rr_cause := ?
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002038 ) runs on test_CT {
Harald Welte91d54a52018-01-28 15:35:07 +01002039
2040 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002041 var boolean got_deact_sacch := false;
2042 var boolean got_rr_chan_rel := false;
2043 var boolean got_rll_rel_req := false;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002044 var ASP_RSL_Unitdata ud;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002045 var RSL_IE_Body l3_ie;
2046 var PDU_ML3_NW_MS l3;
2047 var RR_Cause got_cause;
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002048 log("f_expect_chan_rel() expecting: expect_deact_sacch=", expect_deact_sacch, " expect_rr_chan_rel=", expect_rr_chan_rel,
2049 " expect_rll_rel_req=", expect_rll_rel_req);
Harald Welte91d54a52018-01-28 15:35:07 +01002050 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002051 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DEACT_SACCH(rsl_chan_nr))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002052 got_deact_sacch := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002053 repeat;
2054 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002055 [not istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE_CellSelectInd))) -> value ud {
Harald Welte99787102019-02-04 10:41:36 +01002056 got_rr_chan_rel := true;
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002057
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002058 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2059 setverdict(fail, "cannot find L3");
2060 mtc.stop;
2061 }
2062 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2063
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002064 if (not istemplatekind(expect_cells, "omit")) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002065 var CellSelIndValue cells := dec_CellSelIndValue(
2066 l3.msgs.rrm.channelRelease.cellSelectionIndicator.cellSelectionIndicatorValue);
2067
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002068 log("GOT RR CHANNEL RELEASE WITH CELLS: ", cells);
2069 if (match(cells, expect_cells)) {
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002070 setverdict(pass);
2071 } else {
Pau Espin Pedrol36bd4fa2021-04-15 13:00:24 +02002072 log("EXPECTED CELLS: ", expect_cells);
2073 setverdict(fail, "Received cells list on RR Channel Release does not match expectations");
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002074 }
2075 }
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002076
2077 if (not istemplatekind(expect_rr_cause, "omit")) {
2078 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2079 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2080 if (match(got_cause, expect_rr_cause)) {
2081 setverdict(pass);
2082 } else {
2083 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2084 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
2085 }
2086 }
Harald Welte99787102019-02-04 10:41:36 +01002087 repeat;
2088 }
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002089 [istemplatekind(expect_cells, "omit")] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_DATA_REQ(rsl_chan_nr, ?, decmatch tr_RRM_RR_RELEASE))) -> value ud {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002090 got_rr_chan_rel := true;
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002091
2092 if (not istemplatekind(expect_rr_cause, "omit")) {
2093 if (f_rsl_find_ie(ud.rsl, RSL_IE_L3_INFO, l3_ie) == false) {
2094 setverdict(fail, "cannot find L3");
2095 mtc.stop;
2096 }
2097 l3 := dec_PDU_ML3_NW_MS(l3_ie.l3_info.payload);
2098
2099 int2enum(oct2int(l3.msgs.rrm.channelRelease.rRCause.valuePart), got_cause);
2100 log("GOT CAUSE CODE: ", l3.msgs.rrm.channelRelease.rRCause.valuePart, " = ", got_cause);
2101 if (match(got_cause, expect_rr_cause)) {
2102 setverdict(pass);
2103 } else {
2104 log("EXPECTED CAUSE CODE: ", expect_rr_cause);
2105 setverdict(fail, "Received RR Channel Release Cause code does not match expectations");
2106 }
2107 }
Neels Hofmeyr211169d2018-11-07 00:37:29 +01002108 repeat;
2109 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002110 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_REL_REQ(rsl_chan_nr, ?))) {
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002111 got_rll_rel_req := true;
Harald Welte91d54a52018-01-28 15:35:07 +01002112 /* FIXME: Why are we getting this for LinkID SACCH? */
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002113 if (handle_rll_rel) {
2114 f_ipa_tx(0, ts_RSL_REL_CONF(rsl_chan_nr, main_dcch));
2115 }
Harald Welte91d54a52018-01-28 15:35:07 +01002116 repeat;
2117 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002118 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_RF_CHAN_REL))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002119 /* respond with CHAN REL ACK */
2120 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(rsl_chan_nr));
2121 }
2122 /* ignore any user data */
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07002123 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeR(?))) {
Harald Welte91d54a52018-01-28 15:35:07 +01002124 repeat;
2125 }
2126 }
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002127
2128 log("f_expect_chan_rel() summary: got_deact_sacch=", got_deact_sacch, " got_rr_chan_rel=", got_rr_chan_rel,
2129 " got_rll_rel_req=", got_rll_rel_req);
2130
2131 if (expect_deact_sacch != got_deact_sacch) {
2132 setverdict(fail, "f_expect_chan_rel(): expect_deact_sacch=", expect_deact_sacch, " got_deact_sacch=", got_deact_sacch);
2133 }
2134 if (expect_rr_chan_rel != got_rr_chan_rel) {
2135 setverdict(fail, "f_expect_chan_rel(): expect_rr_chan_rel=", expect_rr_chan_rel, " got_rr_chan_rel=", got_rr_chan_rel);
2136 }
2137 if (expect_rll_rel_req != got_rll_rel_req) {
2138 setverdict(fail, "f_expect_chan_rel(): expect_rll_rel_req=", expect_rll_rel_req, " got_rll_rel_req=", got_rll_rel_req);
2139 }
Harald Welte91d54a52018-01-28 15:35:07 +01002140}
2141
Harald Welte4003d112017-12-09 22:35:39 +01002142/* Test behavior of channel release after hard Clear Command from MSC */
2143testcase TC_chan_rel_hard_clear() runs on test_CT {
2144 var BSSAP_N_DATA_ind rx_di;
Harald Welte4003d112017-12-09 22:35:39 +01002145 var DchanTuple dt;
Harald Welte4003d112017-12-09 22:35:39 +01002146
Harald Welte89d42e82017-12-17 16:42:41 +01002147 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002148
2149 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2150
2151 /* Instruct BSC to clear channel */
2152 var BssmapCause cause := 0;
2153 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2154
2155 /* expect Clear Complete from BSC on A */
2156 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2157 /* release the SCCP connection */
2158 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2159 }
2160
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002161 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002162 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002163}
2164
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002165function f_TC_chan_rel_last_eutran_plmn_hard_clear(boolean tx_csfb_ind) runs on test_CT {
2166 var BSSAP_N_DATA_ind rx_di;
2167 var DchanTuple dt;
2168
2169 f_init(1);
2170
2171 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2172 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2173 /* yet when generating the EUTRAN neigh list in RR CHannel Release) */
2174 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
2175
2176 /* Instruct BSC to clear channel */
2177 var BssmapCause cause := 0;
2178 if (tx_csfb_ind) {
2179 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2180 } else {
2181 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
2182 }
2183
2184 /* expect Clear Complete from BSC on A */
2185 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2186 /* release the SCCP connection */
2187 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2188 }
2189
2190 /* 1 neighbor is added by default in osmo-bts.cfg and
2191 SystemInformationConfig_default, use that: */
2192 var template CellSelIndValue exp_cells := f_tr_rr_chan_rel_earfcns(1);
2193
2194 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false, expect_cells := exp_cells);
2195 f_shutdown_helper();
2196}
2197
2198/* Test behavior of RR Channel rRelease after Clear Command without CSFB indicator
2199 from MSC, previously receiving any CommonID containing the "Last Used E-UTRAN
2200 PLMN Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2201 EUTRAN neighbor list sent later on by BSC in RR Channel, so receiving CSFB
2202 Indicator or not shouldn't matter at all. */
2203testcase TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() runs on test_CT {
2204 f_TC_chan_rel_last_eutran_plmn_hard_clear(false);
2205}
2206
2207/* Test behavior of RR Channel rRelease after Clear Command with CSFB indicator from
2208 MSC, previously receiving any CommonID containing the "Last Used E-UTRAN PLMN
2209 Id". According to spec (3GPP TS 48.008 sec 3.1.30) that's the bit requesting
2210 EUTRAN neighbor list sent later on by BSC in RR Channel. */
2211testcase TC_chan_rel_last_eutran_plmn_hard_clear_csfb() runs on test_CT {
2212 f_TC_chan_rel_last_eutran_plmn_hard_clear(true);
2213}
2214
2215/* Test behavior of RR Channel Release after Clear Command with CSFB indicator from
2216 MSC, without receiving any CommonID containing the "Last Used E-UTRAN PLMN
2217 Id". According to spec (TS 48.008 version 16.0.0 Release 16 "3.2.1.21") the
2218 CSFB Indicator should not be used anymore, and hence, there should be no
2219 EUTRAN neighbor list sent by BSC in RR Channel release since no CommonId with
2220 Last Used E-UTRAN PLMN Id" IE was sent for this conn. */
Harald Welte99787102019-02-04 10:41:36 +01002221testcase TC_chan_rel_hard_clear_csfb() runs on test_CT {
2222 var BSSAP_N_DATA_ind rx_di;
2223 var DchanTuple dt;
2224
2225 f_init(1);
2226
2227 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2228
2229 /* Instruct BSC to clear channel */
2230 var BssmapCause cause := 0;
2231 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2232
2233 /* expect Clear Complete from BSC on A */
2234 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2235 /* release the SCCP connection */
2236 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2237 }
2238
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002239 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002240 f_shutdown_helper();
Harald Welte99787102019-02-04 10:41:36 +01002241}
2242
Harald Welted8c36cd2017-12-09 23:05:31 +01002243/* Test behavior of channel release after hard RLSD from MSC */
2244testcase TC_chan_rel_hard_rlsd() runs on test_CT {
Harald Welted8c36cd2017-12-09 23:05:31 +01002245 var DchanTuple dt;
Harald Welted8c36cd2017-12-09 23:05:31 +01002246
Harald Welte89d42e82017-12-17 16:42:41 +01002247 f_init(1);
Harald Welted8c36cd2017-12-09 23:05:31 +01002248
2249 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2250
2251 /* release the SCCP connection */
2252 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2253
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002254 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002255 f_shutdown_helper();
Harald Welted8c36cd2017-12-09 23:05:31 +01002256}
2257
Harald Welte550daf92018-06-11 19:22:13 +02002258/* Test behavior of channel release after hard RLSD from MSC and MS is not responding to RLL REL REQ */
2259testcase TC_chan_rel_hard_rlsd_ms_dead() runs on test_CT {
2260 var DchanTuple dt;
2261
2262 f_init(1);
2263
2264 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2265
2266 /* release the SCCP connection */
2267 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2268
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002269 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002270 f_shutdown_helper();
Harald Welte550daf92018-06-11 19:22:13 +02002271}
2272
Harald Welte85804d42017-12-10 14:11:58 +01002273/* Test behavior of channel release after BSSMAP RESET from MSC */
2274testcase TC_chan_rel_a_reset() runs on test_CT {
Harald Welte85804d42017-12-10 14:11:58 +01002275 var DchanTuple dt;
Harald Welte85804d42017-12-10 14:11:58 +01002276
Harald Welte89d42e82017-12-17 16:42:41 +01002277 f_init(1);
Harald Welte85804d42017-12-10 14:11:58 +01002278
2279 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2280
2281 /* Clear the queue, it might still contain stuff like IMMEDIATE ASSIGN */
2282 IPA_RSL[0].clear;
2283
2284 /* perform BSSAP RESET, expect RESET ACK and DISC.ind on connection */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002285 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 +01002286 interleave {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02002287 [] 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 +01002288 [] BSSAP.receive(tr_BSSAP_DISC_ind(dt.sccp_conn_id, ?, ?)) { }
2289 }
2290
Neels Hofmeyra5302c82018-11-04 23:09:58 +01002291 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002292 f_shutdown_helper();
Harald Welte85804d42017-12-10 14:11:58 +01002293}
2294
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002295/* Verify T(iar) triggers and releases the channel */
2296testcase TC_chan_rel_sccp_tiar_timeout() runs on test_CT {
2297 var DchanTuple dt;
2298
2299 /* Set T(iar) in BSC low enough that it will trigger before other side
2300 has time to keep alive with a T(ias). Keep recommended ratio of
2301 T(iar) >= T(ias)*2 */
2302 g_bsc_sccp_timer_ias := 2;
2303 g_bsc_sccp_timer_iar := 5;
2304
2305 f_init(1);
2306
2307 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2308 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002309 f_shutdown_helper();
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01002310}
2311
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002312private function f_tc_chan_rel_rr_cause(myBSSMAP_Cause clear_cmd_cause, template RR_Cause expect_rr_cause)
2313runs on test_CT
2314{
2315 var DchanTuple dt;
2316
2317 dt := f_est_dchan('23'O, 23, '00010203040506'O);
2318 var BssmapCause cause := 0;
2319 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(enum2int(clear_cmd_cause))));
2320 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2321 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2322 }
2323
2324 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 +02002325}
2326
2327/* Test that Clear Command cause codes affect the RR Channel Release cause code */
2328testcase TC_chan_rel_rr_cause() runs on test_CT {
2329 f_init(1);
2330
2331 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_CALL_CONTROL, GSM48_RR_CAUSE_NORMAL);
2332 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_HANDOVER_SUCCESSFUL, GSM48_RR_CAUSE_NORMAL);
2333 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_PREEMPTION, GSM48_RR_CAUSE_PREMPTIVE_REL);
2334 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_MESSAGE_FAILURE, GSM48_RR_CAUSE_PROT_ERROR_UNSPC);
2335 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
2336 f_tc_chan_rel_rr_cause(GSM0808_CAUSE_EQUIPMENT_FAILURE, GSM48_RR_CAUSE_ABNORMAL_UNSPEC);
Vadim Yanitskiye18aebb2021-01-03 13:10:43 +01002337
2338 f_shutdown_helper();
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +02002339}
2340
Harald Welte5cd20ed2017-12-13 21:03:20 +01002341/* Test behavior if RSL EST IND for non-active channel */
2342testcase TC_rll_est_ind_inact_lchan() runs on test_CT {
2343 timer T := 2.0;
2344
Harald Welte89d42e82017-12-17 16:42:41 +01002345 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002346
2347 var octetstring l3 := '00010203040506'O;
2348 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
2349 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
2350
2351 T.start;
2352 alt {
2353 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2354 setverdict(fail, "MSC received COMPL L3 for non-active lchan");
2355 }
2356 [] BSSAP.receive {}
2357 [] IPA_RSL[0].receive {}
2358 [] T.timeout {}
2359 }
2360
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002361 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002362}
2363
2364/* Test behavior if RSL EST IND for invalid SAPI */
2365testcase TC_rll_est_ind_inval_sapi1() runs on test_CT {
2366 var RslChannelNr chan_nr;
2367
Harald Welte89d42e82017-12-17 16:42:41 +01002368 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002369
2370 chan_nr := f_chreq_act_ack()
2371
2372 var octetstring l3 := '00010203040506'O;
2373 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(1)), l3));
2374
2375 timer T := 2.0;
2376 T.start;
2377 alt {
2378 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2379 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 1");
2380 }
2381 [] BSSAP.receive { repeat; }
2382 [] IPA_RSL[0].receive { repeat; }
2383 [] T.timeout {}
2384 }
2385
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002386 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002387}
2388
2389/* Test behavior if RSL EST IND for invalid SAPI */
2390testcase TC_rll_est_ind_inval_sapi3() runs on test_CT {
2391 timer T := 2.0;
2392
Harald Welte89d42e82017-12-17 16:42:41 +01002393 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002394
2395 var RslChannelNr chan_nr := f_chreq_act_ack();
2396
2397 var octetstring l3 := '00010203040506'O;
2398 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(3)), l3));
2399
2400 T.start;
2401 alt {
2402 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2403 setverdict(fail, "MSC received COMPL L3 for invalid SAPI 3");
2404 }
2405 [] BSSAP.receive { repeat; }
2406 [] IPA_RSL[0].receive { repeat; }
2407 [] T.timeout {}
2408 }
2409
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002410 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002411}
2412
2413/* Test behavior if RSL EST IND for invalid SACCH */
2414testcase TC_rll_est_ind_inval_sacch() runs on test_CT {
2415 timer T := 2.0;
2416
Harald Welte89d42e82017-12-17 16:42:41 +01002417 f_init(1);
Harald Welte5cd20ed2017-12-13 21:03:20 +01002418
2419 var RslChannelNr chan_nr := f_chreq_act_ack();
2420
2421 var octetstring l3 := '00010203040506'O;
2422 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_SACCH(0)), l3));
2423
2424 T.start;
2425 alt {
2426 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) {
2427 setverdict(fail, "MSC received COMPL L3 for invalid Link SACCH");
2428 }
2429 [] BSSAP.receive { repeat; }
2430 [] IPA_RSL[0].receive { repeat; }
2431 [] T.timeout {}
2432 }
2433
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002434 f_shutdown_helper();
Harald Welte5cd20ed2017-12-13 21:03:20 +01002435}
2436
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002437/* Verify DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
2438private function f_TC_tch_dlci_link_id_sapi(charstring id) runs on MSC_ConnHdlr {
2439 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
2440 var PDU_BSSAP ass_cmd := f_gen_ass_req();
2441
2442 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
2443 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
2444
2445 f_establish_fully(ass_cmd, exp_compl);
2446
2447 /* SAPI0 has already been established by f_establish_fully(), establish SAPI3 */
2448 RSL.send(ts_RSL_EST_IND(g_chan_nr, ts_RslLinkID_SACCH(3), '0904'O));
2449 /* Expect BSSAP/DTAP on SAPI3 (DLCI IE) */
2450 BSSAP.receive(PDU_BSSAP:{
2451 discriminator := '1'B,
2452 spare := '0000000'B,
2453 dlci := 'C3'O,
2454 lengthIndicator := ?,
2455 pdu := { dtap := '0904'O }
2456 });
2457
2458 /* Send messages on DCCH/SAPI0 and ACCH/SAPI3 */
2459 for (var integer i := 0; i < 32; i := i + 1) {
2460 var octetstring l3 := '09'O & f_rnd_octstring(14);
2461 var template (value) RslLinkId link_id;
2462 var template (value) OCT1 dlci;
2463
2464 if (i mod 2 == 0) {
2465 /* SAPI0 on FACCH or SDCCH */
2466 link_id := ts_RslLinkID_DCCH(0);
2467 dlci := '80'O;
2468 } else {
2469 /* SAPI3 on SACCH */
2470 link_id := ts_RslLinkID_SACCH(3);
2471 dlci := 'C3'O;
2472 }
2473
2474 /* Send MO message: RSL -> BSSAP */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002475 f_mo_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002476 /* Send MT message: BSSAP -> RSL */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00002477 f_mt_l3_transceive(RSL, link_id, dlci, l3);
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002478 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01002479 f_perform_clear();
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +07002480}
2481testcase TC_tch_dlci_link_id_sapi() runs on test_CT {
2482 var TestHdlrParams pars := f_gen_test_hdlr_pars();
2483 var MSC_ConnHdlr vc_conn;
2484
2485 f_init(1, true);
2486 f_sleep(1.0);
2487
2488 vc_conn := f_start_handler(refers(f_TC_tch_dlci_link_id_sapi), pars);
2489 vc_conn.done;
2490
2491 f_shutdown_helper();
2492}
2493
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002494private function f_exp_sapi_n_reject(template (present) GsmSapi sapi := ?,
2495 template myBSSMAP_Cause cause := ?,
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002496 template (present) BIT2 cc := ?,
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002497 float T_val := 2.0)
2498runs on test_CT {
2499 var BSSAP_N_DATA_ind rx_di;
2500 timer T;
2501
2502 var template BSSMAP_IE_Cause tr_cause := tr_BSSMAP_IE_Cause(cause);
2503 var template PDU_BSSAP tr_pdu := tr_BSSMAP_SAPInReject(sapi);
2504
2505 T.start(T_val);
2506 alt {
2507 [] BSSAP.receive(tr_BSSAP_DATA_ind(?, tr_pdu)) -> value rx_di {
2508 var BSSMAP_IE_Cause rx_cause := rx_di.userData.pdu.bssmap.sAPInReject.cause;
2509 if (not match(rx_cause, tr_cause)) {
2510 setverdict(fail, "Rx unexpected Cause IE: ",
2511 rx_cause, " vs expected ", tr_cause);
2512 }
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002513
2514 /* Who ever on the earth decided to define this field as two separate bits?!? */
2515 var BIT2 rx_cc := rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c2
2516 & rx_di.userData.pdu.bssmap.sAPInReject.dLCI.c1;
2517 if (not match(rx_cc, cc)) {
2518 setverdict(fail, "Rx unexpected Control Channel type: ",
2519 rx_cc, " vs expected ", cc);
2520 }
2521
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002522 setverdict(pass);
2523 }
2524 [] BSSAP.receive(BSSAP_N_DATA_ind:?) -> value rx_di {
2525 setverdict(fail, "Rx unexpected BSSAP PDU: ", rx_di);
2526 }
2527 [] T.timeout {
2528 setverdict(fail, "Timeout waiting for BSSMAP SAPI N Reject");
2529 }
2530 }
2531}
2532
2533/* Check if we get SAPI N Reject on receipt of unexpected RLL RELease INDication */
2534testcase TC_rll_rel_ind_sapi_n_reject() runs on test_CT {
2535 var octetstring rnd_data := f_rnd_octstring(16);
2536 var RSL_Message rx_rsl;
2537 var DchanTuple dt;
2538
2539 f_init(1);
2540
2541 /* MS establishes a SAPI=0 link on DCCH */
2542 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2543
2544 /* MSC sends some data on (not yet established) SAPI=3 link */
2545 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2546 /* BSC attempts to establish a SAPI=3 link on DCCH */
2547 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2548
2549 /* MS sends unexpected RELease INDication on SAPI=3 */
2550 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3)));
2551 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2552 f_exp_sapi_n_reject(3, GSM0808_CAUSE_MS_NOT_EQUIPPED);
2553
2554 /* Clean up the connection */
2555 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2556 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2557
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002558 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002559}
2560
2561/* Check if we get SAPI N Reject on receipt of unexpected RLL ERROR INDication */
2562testcase TC_rll_err_ind_sapi_n_reject() runs on test_CT {
2563 var octetstring rnd_data := f_rnd_octstring(16);
2564 var RSL_Message rx_rsl;
2565 var DchanTuple dt;
2566
2567 f_init(1);
2568
2569 /* MS establishes a SAPI=0 link on DCCH */
2570 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2571
2572 /* MSC sends some data on (not yet established) SAPI=3 link */
2573 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2574 /* BSC attempts to establish a SAPI=3 link on DCCH */
2575 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2576
2577 /* BTS sends unexpected ERROR INDication on SAPI=3 */
2578 f_ipa_tx(0, ts_RSL_ERROR_IND(dt.rsl_chan_nr, ts_RslLinkID_DCCH(3), ''O));
2579 /* We expect to receive BSSMAP SAPI N Reject message from the BSC */
2580 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED);
2581
2582 /* Clean up the connection */
2583 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2584 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2585
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002586 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002587}
2588
2589/* Check if we get SAPI N Reject due to a SAPI=3 link establishment timeout */
2590testcase TC_rll_timeout_sapi_n_reject() runs on test_CT {
2591 var octetstring rnd_data := f_rnd_octstring(16);
2592 var RSL_Message rx_rsl;
2593 var DchanTuple dt;
2594
2595 f_init(1);
2596
2597 /* MS establishes a SAPI=0 link on DCCH */
2598 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2599
2600 /* MSC sends some data on (not yet established) SAPI=3 link */
2601 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2602 /* BSC attempts to establish a SAPI=3 link on DCCH */
2603 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2604
2605 /* MS does not respond, so the link establishment timeout triggers SAPI N Reject */
2606 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, T_val := 8.0);
2607
2608 /* Clean up the connection */
2609 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2610 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2611
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002612 f_shutdown_helper();
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +07002613}
2614
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002615/* Check DLCI CC (Control Channel type) bits in SAPI N Reject */
2616testcase TC_rll_sapi_n_reject_dlci_cc() runs on test_CT {
2617 var octetstring rnd_data := f_rnd_octstring(16);
2618 var RSL_Message rx_rsl;
2619 var DchanTuple dt;
2620
2621 f_init(1);
2622
2623 /* MS establishes a SAPI=0 link on DCCH */
2624 dt := f_est_dchan(f_rnd_ra_cs(), 23, rnd_data);
2625
2626 /* MSC sends some data on (not yet established) SAPI=3 link */
2627 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSAP_DTAP(rnd_data, '03'O)));
2628 /* BSC attempts to establish a SAPI=3 link on DCCH */
2629 rx_rsl := f_exp_ipa_rx(0, tr_RSL_EST_REQ(dt.rsl_chan_nr, tr_RslLinkID_DCCH(3)));
2630
2631 /* MS sends unexpected ERROR INDication on DCCH/ACCH SAPI=3 */
2632 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 +01002633 f_exp_sapi_n_reject(3, GSM0808_CAUSE_BSS_NOT_EQUIPPED, '10'B);
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +07002634
2635 /* Clean up the connection */
2636 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2637 f_expect_chan_rel(0, dt.rsl_chan_nr, expect_rll_rel_req := false);
2638
2639 f_shutdown_helper();
2640}
2641
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002642testcase TC_si_default() runs on test_CT {
2643 f_init(0);
2644 f_init_bts_and_check_sysinfo(0, expect_si := SystemInformationConfig_default);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002645 f_shutdown_helper();
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +02002646}
Harald Welte4003d112017-12-09 22:35:39 +01002647
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002648/* We're testing SI2quater with lists of EARFCNs. Instead of just incrementing EARFCNs, also pick some from the edges of
2649 * the entire value range. This function provides the same EARFCN numbers for the same earfcn_index */
2650private function f_test_si2quater_earfcn_by_idx(integer earfcn_index) return uint16_t
2651{
2652 select (earfcn_index) {
2653 case (0) {
2654 /* E-ARFCN 111 is already added in the osmo-bsc.cfg */
2655 return 111;
2656 }
2657 case (1) {
2658 return 1;
2659 }
2660 case (2) {
2661 return 0;
2662 }
2663 case (3) {
2664 return 65535;
2665 }
2666 case else {
2667 return 23 * (earfcn_index - 3);
2668 }
2669 }
2670}
2671
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002672function f_test_si2quater(integer total_earfcns, template SystemInformationConfig expect_si,
2673 template CellSelIndValue expect_cells := omit) runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002674
2675 f_init(0);
2676
2677 /* E-ARFCN 111 is already added in the osmo-bsc.cfg, so only add more arfcns if total_earfcns > 1 */
2678 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002679 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2680 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002681 }
2682
2683 f_init_bts_and_check_sysinfo(0, expect_si := expect_si);
2684
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002685 if (not istemplatekind(expect_cells, "omit")) {
2686 /* Also check that RR Channel Release contains these EARFCNs.
2687 * (copied code from TC_chan_rel_hard_clear_csfb) */
2688 var BSSAP_N_DATA_ind rx_di;
2689 var DchanTuple dt;
2690
2691 dt := f_est_dchan('23'O, 23, '00010203040506'O);
Pau Espin Pedrold0046312021-04-19 16:35:58 +02002692 /* Send CommonID with some random PLMN (BSC doesn't take it into account
2693 * yet when generating the EUTRAN neigh list in RR CHannel Release) */
2694 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_CommonId('001019876543210'H, '323454'O)));
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002695
2696 /* Instruct BSC to clear channel */
2697 var BssmapCause cause := 0;
2698 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommandCSFB(cause)));
2699
2700 /* expect Clear Complete from BSC on A */
2701 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearComplete)) {
2702 /* release the SCCP connection */
2703 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
2704 }
2705
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +02002706 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 +02002707 }
2708
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002709 for (var integer i := 1; i < total_earfcns; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002710 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 +02002711 }
2712}
2713
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002714private function f_tr_si2quater_earfcns(integer count) return template SI2quaterRestOctetsList
2715{
2716 var template SI2quaterRestOctetsList si2quater := {};
2717 var integer si2quater_count := (count + 2) / 3;
2718
2719 for (var integer i := 0; i < count; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002720 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002721 var integer index := i / 3;
2722 var integer earfcn_index := i mod 3;
2723 if (index >= lengthof(si2quater)) {
2724 si2quater[index] := tr_SI2quaterRestOctets_EUTRAN(index := index, count := si2quater_count - 1);
2725 }
2726 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);
2727 }
2728
2729 return si2quater;
2730}
2731
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002732private function f_tr_rr_chan_rel_earfcns(integer count) return template CellSelIndValue
2733{
2734 var template CellSelIndValue_EUTRAN_Descrs cells := {};
2735
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002736 /* the lte neighbors must match the config & vty to pass this test */
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002737 for (var integer i := 0; i < count; i := i + 1) {
2738 var integer earfcn := f_test_si2quater_earfcn_by_idx(i);
Alexander Couzensf74b5cb2020-09-10 22:28:40 +02002739 cells[i] := tr_CellSelIndValue_EUTRAN_Descr(earfcn, '1'B, 3);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002740 }
2741
2742 return tr_CellSelIndValue_EUTRAN(cells);
2743}
2744
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002745private function f_tc_si2quater_n_earfcns(integer n) runs on test_CT
2746{
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002747 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrol8ab62e42020-12-18 16:19:11 +01002748 sic.si2quater := f_tr_si2quater_earfcns(n);
Neels Hofmeyr0edf4ac2020-07-10 17:33:24 +02002749 var template CellSelIndValue cells := f_tr_rr_chan_rel_earfcns(n);
2750 f_test_si2quater(n, sic, cells);
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002751}
2752
2753testcase TC_si2quater_2_earfcns() runs on test_CT {
2754 f_tc_si2quater_n_earfcns(2);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002755 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002756}
2757
2758testcase TC_si2quater_3_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002759 f_tc_si2quater_n_earfcns(3);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002760 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002761}
2762
2763testcase TC_si2quater_4_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002764 f_tc_si2quater_n_earfcns(4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002765 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002766}
2767
2768testcase TC_si2quater_5_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002769 f_tc_si2quater_n_earfcns(5);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002770 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002771}
2772
2773testcase TC_si2quater_6_earfcns() runs on test_CT {
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002774 f_tc_si2quater_n_earfcns(6);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002775 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002776}
2777
2778testcase TC_si2quater_12_earfcns() runs on test_CT {
2779 f_tc_si2quater_n_earfcns(12);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002780 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002781}
2782
2783testcase TC_si2quater_23_earfcns() runs on test_CT {
2784 f_tc_si2quater_n_earfcns(23);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002785 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002786}
2787
2788testcase TC_si2quater_32_earfcns() runs on test_CT {
2789 f_tc_si2quater_n_earfcns(32);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002790 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002791}
2792
2793testcase TC_si2quater_33_earfcns() runs on test_CT {
2794 f_tc_si2quater_n_earfcns(33);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002795 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002796}
2797
2798testcase TC_si2quater_42_earfcns() runs on test_CT {
2799 f_tc_si2quater_n_earfcns(42);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002800 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002801}
2802
2803testcase TC_si2quater_48_earfcns() runs on test_CT {
2804 f_tc_si2quater_n_earfcns(48);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002805 f_shutdown_helper();
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002806}
2807
2808/* verify the VTY error response when adding too many EARFCNs, and showing that osmo-bsc still sends 16 SI2quater with
2809 * 48 EARFCNs. */
2810testcase TC_si2quater_49_earfcns() runs on test_CT {
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002811 var template SystemInformationConfig sic := SystemInformationConfig_default;
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002812 sic.si2quater := f_tr_si2quater_earfcns(48); /* 48, not 49! */
2813 f_init(0);
2814
2815 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002816 f_bts_0_cfg(BSCVTY, {"si2quater neighbor-list add earfcn " & int2str(f_test_si2quater_earfcn_by_idx(i))
2817 & " thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3"});
Neels Hofmeyrad132f22020-07-08 02:20:16 +02002818 }
2819
2820 /* The 49th EARFCN no longer fits, expect VTY error */
2821 f_vty_enter_cfg_bts(BSCVTY, 0);
2822 var charstring vty_error;
2823 vty_error := f_vty_transceive_ret(BSCVTY,
2824 "si2quater neighbor-list add earfcn 70 thresh-hi 20 thresh-lo 10 prio 3 qrxlv 22 meas 3")
2825 f_vty_transceive(BSCVTY, "end");
2826
2827 if (f_strstr(vty_error, "Unable to add ARFCN 70") >= 0) {
2828 log("Got expected VTY error: ", vty_error);
2829 setverdict(pass);
2830 } else {
2831 setverdict(fail, "Expected the 49th EUTRAN ARFCN to be rejected by vty config, got: ", vty_error);
2832 }
2833
2834 f_init_bts_and_check_sysinfo(0, expect_si := sic);
2835
2836 for (var integer i := 1; i < 48; i := i + 1) {
Neels Hofmeyr56f24782020-07-09 00:50:49 +02002837 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 +02002838 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002839 f_shutdown_helper();
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002840}
2841
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002842private function f_acc09_count_allowed(AccessControlClass acc) return uint8_t
2843{
2844 var uint8_t count := 0;
2845 for (var integer i := 5; i < 16; i := i + 1) {
2846 if (acc[i] == '0'B) { /* the list marks barred, we count allowed */
2847 count := count + 1;
2848 }
2849 }
2850 return count;
2851}
2852
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002853private function f_recv_next_si1(integer rsl_idx := 0) runs on test_CT return SystemInformationType1
2854{
2855 var ASP_RSL_Unitdata rx_rsl_ud;
2856 var SystemInformationType1 last_si1;
2857
2858 timer T := 30.0;
2859 T.start;
2860 alt {
2861 [] IPA_RSL[rsl_idx].receive(tr_ASP_RSL_UD((tr_RSL_NO_BCCH_INFO,
2862 tr_RSL_BCCH_INFO,
2863 tr_RSL_NO_SACCH_FILL,
2864 tr_RSL_SACCH_FILL))
2865 ) -> value rx_rsl_ud {
2866 f_sysinfo_seen(rsl_idx, rx_rsl_ud.rsl);
2867 if (g_system_information[rsl_idx].si1 == omit) {
2868 repeat;
2869 }
2870 last_si1 := g_system_information[rsl_idx].si1;
2871 g_system_information[rsl_idx].si1 := omit;
2872 T.stop;
2873 }
Vadim Yanitskiy79ebd5e2021-01-04 00:12:55 +01002874 [] IPA_RSL[rsl_idx].receive { repeat; }
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002875 [] T.timeout { setverdict(fail, "Timeout receiving next SI1"); }
2876 }
2877 return last_si1;
2878}
2879
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002880/* verify ACC rotate feature */
2881testcase TC_si_acc_rotate() runs on test_CT {
2882 var template SystemInformationConfig sic := SystemInformationConfig_default;
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002883 var SystemInformationType1 last_si1;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002884 var AccessControlClass acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002885 var uint8_t count;
2886 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2887
2888 f_init(0, guard_timeout := 60.0);
2889
2890 f_bts_0_cfg(BSCVTY, {"rach access-control-class 5 barred",
2891 "access-control-class-rotate 3",
2892 "access-control-class-rotate-quantum 1"});
2893
2894 /* Init and get first sysinfo */
2895 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2896
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002897 for (var integer i:= 0; i < 20; i := i + 1) {
2898 last_si1 := f_recv_next_si1(0);
2899 acc := last_si1.rach_control.acc;
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002900 count := f_acc09_count_allowed(acc);
2901 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2902
2903 if (count != 3) {
2904 log("RSL: EXPECTED SI ACC len=3");
2905 setverdict(fail, "received SI does not match expectations");
2906 break;
2907 }
2908
2909 for (var integer j := 0; j < 10; j := j + 1) {
2910 if (acc[16 - 1 - j] == '0'B) { /* the list marks barred, we count allowed */
2911 times_allowed[j] := times_allowed[j] + 1;
2912 }
2913 }
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002914 }
2915
2916 for (var integer j := 0; j < 10; j := j + 1) {
2917 log("ACC", j, " allowed ", times_allowed[j], " times" );
2918 if (j != 5 and times_allowed[j] < 3) {
2919 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " < 1 times");
2920 } else if (j == 5 and times_allowed[j] > 0) {
2921 setverdict(fail, "ACC", j, " ERROR: allowed ", times_allowed[j], " > 0 times");
2922 }
2923 }
2924
2925 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2926 "rach access-control-class 5 allowed"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002927 f_shutdown_helper();
Pau Espin Pedrol85a84432020-07-20 18:45:03 +02002928}
Neels Hofmeyr66aeba42020-07-06 02:21:21 +02002929
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002930/* verify ACC startup ramp+rotate feature */
2931testcase TC_si_acc_ramp_rotate() runs on test_CT {
2932 var template SystemInformationConfig sic := SystemInformationConfig_default;
2933 var SystemInformationType1 last_si1;
2934 var AccessControlClass acc;
2935 var ASP_RSL_Unitdata rx_rsl_ud;
2936 var uint8_t count;
2937 var uint8_t prev_count;
2938 var integer times_allowed[10] := { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2939
2940 f_init(0, guard_timeout := 80.0);
2941
2942 f_bts_0_cfg(BSCVTY, {"rach access-control-class 4 barred",
2943 "access-control-class-rotate 0",
2944 "access-control-class-rotate-quantum 1",
2945 "access-control-class-ramping",
2946 "access-control-class-ramping-step-interval 5",
2947 "access-control-class-ramping-step-size 5"});
2948
2949 /* Init and get first sysinfo */
2950 f_init_bts_and_check_sysinfo(0, expect_si := ?);
2951 last_si1 := g_system_information[0].si1;
2952 acc := last_si1.rach_control.acc;
2953 count := f_acc09_count_allowed(acc);
2954 /* Adm subset size was set to 0 above, so wait until all ACC are barred */
2955 while (count > 0) {
2956 last_si1 := f_recv_next_si1(0);
2957 acc := last_si1.rach_control.acc;
2958 count := f_acc09_count_allowed(acc);
2959 log("RSL: wait len()=0: GOT SI1 ACC len=", count, ": ", acc);
2960 }
2961
2962 /* Increase adm subset size, we should see ramping start up */
2963 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10"});
2964 prev_count := 0;
2965 while (true) {
2966 last_si1 := f_recv_next_si1(0);
2967 acc := last_si1.rach_control.acc;
2968 count := f_acc09_count_allowed(acc);
2969 log("RSL: GOT SI1 ACC len=", count, ": ", acc);
2970
2971 if (prev_count > count) {
2972 setverdict(fail, "ACC allowed count dropped while expecting grow: ", prev_count, " -> ", count);
2973 break;
2974 }
2975
2976 if (count == 9) {
2977 break; /* Maximum reached (10 - 1 perm barred), done here */
2978 }
2979
2980 prev_count := count;
2981 }
2982
2983 setverdict(pass);
2984
2985 f_bts_0_cfg(BSCVTY, {"access-control-class-rotate 10",
2986 "rach access-control-class 4 allowed",
2987 "no access-control-class-ramping"});
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002988 f_shutdown_helper();
Pau Espin Pedrolc6136cd2020-07-24 13:20:02 +02002989}
2990
Harald Welte4003d112017-12-09 22:35:39 +01002991testcase TC_ctrl_msc_connection_status() runs on test_CT {
2992 var charstring ctrl_resp;
2993
Harald Welte89d42e82017-12-17 16:42:41 +01002994 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01002995
2996 /* See https://osmocom.org/issues/2729 */
2997 f_ctrl_get_exp(IPA_CTRL, "msc_connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02002998 f_shutdown_helper();
Harald Welte4003d112017-12-09 22:35:39 +01002999}
3000
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003001testcase TC_ctrl_msc0_connection_status() runs on test_CT {
3002 var charstring ctrl_resp;
3003
3004 f_init(1);
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003005
3006 f_ctrl_get_exp(IPA_CTRL, "msc.0.connection_status", "connected");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003007 f_shutdown_helper();
Stefan Sperlingb041b3d2018-01-03 17:14:55 +01003008}
3009
Neels Hofmeyr0bc470d2021-08-21 13:37:13 +02003010/* Verify correct stats on the number of configured and connected MSCs */
3011private function f_tc_stat_num_msc_connected_msc_connhdlr(integer expect_num_msc_connected) runs on MSC_ConnHdlr {
3012 g_pars := f_gen_test_hdlr_pars();
3013 var StatsDExpects expect := {
3014 { name := "TTCN3.bsc.0.num_msc.connected", mtype := "g", min := expect_num_msc_connected, max := expect_num_msc_connected },
3015 { name := "TTCN3.bsc.0.num_msc.total", mtype := "g", min := NUM_MSC, max := NUM_MSC }
3016 };
3017 f_statsd_expect(expect);
3018}
3019
3020private function f_tc_stat_num_msc_connected_test_ct(void_fn tc_fn, integer nr_msc) runs on test_CT
3021{
3022 var MSC_ConnHdlr vc_conn;
3023
3024 f_init(nr_bts := 1, handler_mode := true, nr_msc := nr_msc);
3025 f_sleep(1.0);
3026 vc_conn := f_start_handler(tc_fn);
3027 vc_conn.done;
3028
3029 /* Also verify stat exposed on CTRL interface */
3030 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:connected", int2str(nr_msc));
3031 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_msc:total", int2str(NUM_MSC));
3032
3033 f_shutdown_helper();
3034}
3035
3036/* Verify that when 1 MSC is active, that num_msc:connected reports 1. */
3037private function f_tc_stat_num_msc_connected_1(charstring id) runs on MSC_ConnHdlr {
3038 f_tc_stat_num_msc_connected_msc_connhdlr(1);
3039}
3040testcase TC_stat_num_msc_connected_1() runs on test_CT {
3041 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_1), 1);
3042}
3043
3044/* Verify that when 2 MSCs are active, that num_msc:connected reports 2. */
3045private function f_tc_stat_num_msc_connected_2(charstring id) runs on MSC_ConnHdlr {
3046 f_tc_stat_num_msc_connected_msc_connhdlr(2);
3047}
3048testcase TC_stat_num_msc_connected_2() runs on test_CT {
3049 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_2), 2);
3050}
3051
3052/* Verify that when 3 MSCs are active, that num_msc:connected reports 3. */
3053private function f_tc_stat_num_msc_connected_3(charstring id) runs on MSC_ConnHdlr {
3054 f_tc_stat_num_msc_connected_msc_connhdlr(3);
3055}
3056testcase TC_stat_num_msc_connected_3() runs on test_CT {
3057 f_tc_stat_num_msc_connected_test_ct(refers(f_tc_stat_num_msc_connected_3), 3);
3058}
3059
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003060/* Verify correct stats on the number of configured and connected MSCs */
3061private function f_tc_stat_num_bts_connected_msc_connhdlr(integer expect_num_bts_connected) runs on MSC_ConnHdlr {
3062 g_pars := f_gen_test_hdlr_pars();
3063 var StatsDExpects expect := {
3064 { name := "TTCN3.bsc.0.num_bts.oml_connected", mtype := "g", min := expect_num_bts_connected, max := NUM_BTS_CFG },
3065 { name := "TTCN3.bsc.0.num_bts.all_trx_rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3066 { name := "TTCN3.bsc.0.num_bts.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG },
3067 { name := "TTCN3.bsc.0.num_trx.rsl_connected", mtype := "g", min := expect_num_bts_connected, max := expect_num_bts_connected },
3068 { name := "TTCN3.bsc.0.num_trx.total", mtype := "g", min := NUM_BTS_CFG, max := NUM_BTS_CFG }
3069 };
3070 f_statsd_expect(expect);
3071}
3072
3073private function f_tc_stat_num_bts_connected_test_ct(void_fn tc_fn, integer nr_bts) runs on test_CT {
3074 var MSC_ConnHdlr vc_conn;
3075
3076 f_init(nr_bts := nr_bts, handler_mode := true, nr_msc := 1);
3077 f_sleep(1.0);
3078 vc_conn := f_start_handler(tc_fn);
3079 vc_conn.done;
3080
3081 /* Also verify stat exposed on CTRL interface */
3082 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:all_trx_rsl_connected", int2str(nr_bts));
3083 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_bts:total", int2str(NUM_BTS_CFG));
3084 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:rsl_connected", int2str(nr_bts));
3085 f_ctrl_get_exp(IPA_CTRL, "stat_item.last.bsc.0.num_trx:total", int2str(NUM_BTS_CFG));
3086
Neels Hofmeyra41ae302021-09-06 22:06:02 +02003087 /* Verify rf_states exposed on CTRL interface */
3088 var charstring expect_net_rf_states := "";
3089 for (var integer i := 0; i < NUM_BTS_CFG; i := i + 1) {
3090 var charstring expect_bts_rf_states := int2str(i) & ",0,";
3091 if (i < NUM_BTS) {
3092 /* In these tests, OML for the first NUM_BTS are always connected via osmo-bts-omldummy */
3093 expect_bts_rf_states := expect_bts_rf_states & "operational,unlocked,";
3094 } else {
3095 /* For remaining i < NUM_BTS_CFG, OML is not connected, i.e. inoperational */
3096 expect_bts_rf_states := expect_bts_rf_states & "inoperational,locked,";
3097 }
3098 /* The RF policy is still global in osmo-bsc, i.e. always "on" */
3099 expect_bts_rf_states := expect_bts_rf_states & "on,";
3100 if (i < nr_bts) {
3101 /* For BTS where RSL is connected, the RSL state will be "up" */
3102 expect_bts_rf_states := expect_bts_rf_states & "rsl-up;";
3103 } else {
3104 expect_bts_rf_states := expect_bts_rf_states & "rsl-down;";
3105 }
3106
3107 f_ctrl_get_exp(IPA_CTRL, "bts." & int2str(i) & ".rf_states", expect_bts_rf_states);
3108 expect_net_rf_states := expect_net_rf_states & expect_bts_rf_states;
3109 }
3110 f_ctrl_get_exp(IPA_CTRL, "rf_states", expect_net_rf_states);
3111
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +02003112 f_shutdown_helper();
3113}
3114
3115/* Verify that when 1 BTS is connected, that num_{bts,trx}:*_connected reports 1. */
3116private function f_tc_stat_num_bts_connected_1(charstring id) runs on MSC_ConnHdlr {
3117 f_tc_stat_num_bts_connected_msc_connhdlr(1);
3118}
3119testcase TC_stat_num_bts_connected_1() runs on test_CT {
3120 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_1), 1);
3121}
3122
3123/* Verify that when 2 BTS is connected, that num_{bts,trx}:*_connected reports 2. */
3124private function f_tc_stat_num_bts_connected_2(charstring id) runs on MSC_ConnHdlr {
3125 f_tc_stat_num_bts_connected_msc_connhdlr(2);
3126}
3127testcase TC_stat_num_bts_connected_2() runs on test_CT {
3128 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_2), 2);
3129}
3130
3131/* Verify that when 3 BTS is connected, that num_{bts,trx}:*_connected reports 3. */
3132private function f_tc_stat_num_bts_connected_3(charstring id) runs on MSC_ConnHdlr {
3133 f_tc_stat_num_bts_connected_msc_connhdlr(3);
3134}
3135testcase TC_stat_num_bts_connected_3() runs on test_CT {
3136 f_tc_stat_num_bts_connected_test_ct(refers(f_tc_stat_num_bts_connected_3), 3);
3137}
3138
Harald Welte4003d112017-12-09 22:35:39 +01003139testcase TC_ctrl() runs on test_CT {
3140 var charstring ctrl_resp;
3141
Harald Welte89d42e82017-12-17 16:42:41 +01003142 f_init(1);
Harald Welte4003d112017-12-09 22:35:39 +01003143
3144 /* all below values must match the osmo-bsc.cfg config file used */
3145
Harald Welte6a129692018-03-17 17:30:14 +01003146 f_ctrl_get_exp(IPA_CTRL, "mcc", "001");
3147 f_ctrl_get_exp(IPA_CTRL, "mnc", "01");
Oliver Smith75aa0202019-08-19 14:17:50 +02003148 f_ctrl_get_exp(IPA_CTRL, "number-of-bts", "4");
Harald Welte4003d112017-12-09 22:35:39 +01003149
3150 var integer bts_nr := 0;
3151 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "location-area-code", "1");
3152 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "cell-identity", "0");
3153 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "oml-connection-state", "connected");
3154 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "gprs-mode", "gprs");
3155 f_ctrl_get_exp_bts(IPA_CTRL, bts_nr, "rf_state", "operational,unlocked,on");
3156 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "arfcn", "871");
3157 f_ctrl_get_exp_trx(IPA_CTRL, bts_nr, 0, "max-power-reduction", "20");
3158
3159 var integer uptime := str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime"));
3160 f_sleep(2.0);
3161 if (str2int(f_ctrl_get_bts(IPA_CTRL, bts_nr, "oml-uptime")) < uptime+1) {
3162 setverdict(fail, "oml-uptime not incrementing as expected");
3163 }
3164 /* TODO: Disconnect RSL, imply that OML is disconnected and check for uptime zero? */
3165
3166 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", 0);
3167
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003168 f_shutdown_helper();
Harald Welte96c94412017-12-09 03:12:45 +01003169}
3170
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003171/* Verify that Upon receival of SET "location", BSC forwards a TRAP
3172 "location-state" over the SCCPlite IPA conn */
3173testcase TC_ctrl_location() runs on test_CT {
3174 var MSC_ConnHdlr vc_conn;
3175 var integer bts_nr := 0;
3176
3177 f_init(1, true);
3178 f_sleep(1.0);
3179
3180 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234567,fix3d,0.340000,0.560000,0.780000");
3181 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3182 "1234567,fix3d,0.340000,0.560000,0.780000,operational,unlocked,on,001,01");
3183
3184 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "1");
3185 f_sleep(2.0);
3186
3187 f_ctrl_set_bts(IPA_CTRL, bts_nr, "location", "1234888,fix3d,0.350000,0.570000,0.790000");
3188 f_ctrl_exp_trap(SCCPLITE_IPA_CTRL, "bts." & int2str(bts_nr) & ".location-state",
3189 "1234888,fix3d,0.350000,0.570000,0.790000,operational,locked,off,001,01");
3190
3191 /* should match the one from config */
3192 f_ctrl_set(SCCPLITE_IPA_CTRL, "rf_locked", "0");
3193
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003194 f_shutdown_helper();
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +02003195}
3196
Harald Welte6f521d82017-12-11 19:52:02 +01003197
3198/***********************************************************************
3199 * Paging Testing
3200 ***********************************************************************/
3201
3202type record Cell_Identity {
3203 GsmMcc mcc,
3204 GsmMnc mnc,
3205 GsmLac lac,
3206 GsmCellId ci
3207};
Harald Welte24135bd2018-03-17 19:27:53 +01003208private const Cell_Identity cid := { '001'H, '01'H, 1, 0 };
Stefan Sperling049a86e2018-03-20 15:51:00 +01003209private const Cell_Identity unknown_cid := { '678'H, 'f90'H, 1, 0 };
Harald Welte6f521d82017-12-11 19:52:02 +01003210
Harald Welte5d1a2202017-12-13 19:51:29 +01003211type set of integer BtsIdList;
3212
3213private function f_bts_in_list(integer bts_id, BtsIdList bts_ids) return boolean {
3214 for (var integer j := 0; j < sizeof(bts_ids); j := j + 1) {
3215 if (bts_id == bts_ids[j]) {
3216 return true;
3217 }
3218 }
3219 return false;
3220}
Harald Welte6f521d82017-12-11 19:52:02 +01003221
3222/* core paging test helper function; used by most paging test cases */
3223private function f_pageing_helper(hexstring imsi,
3224 template BSSMAP_FIELD_CellIdentificationList cid_list,
Harald Welte5d1a2202017-12-13 19:51:29 +01003225 BtsIdList bts_ids := { 0 },
Harald Welte6f521d82017-12-11 19:52:02 +01003226 template RSL_ChanNeeded rsl_chneed := omit,
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003227 template (omit) OCT4 tmsi := omit) runs on test_CT
Harald Welte6f521d82017-12-11 19:52:02 +01003228{
3229 var template BSSMAP_IE_ChannelNeeded bssmap_chneed;
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003230 var template MobileIdentityV mi;
Harald Welte6f521d82017-12-11 19:52:02 +01003231 var RSL_Message rx_rsl;
3232 var integer paging_group := hex2int(imsi[lengthof(imsi)-1]);
Harald Welte5d1a2202017-12-13 19:51:29 +01003233 var integer i;
Harald Welte6f521d82017-12-11 19:52:02 +01003234
3235 f_init();
Harald Welte6f521d82017-12-11 19:52:02 +01003236
3237 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Harald Weltec3068592018-03-17 19:55:31 +01003238 for (i := 0; i < NUM_BTS; i := i + 1) {
3239 IPA_RSL[i].clear;
Harald Welte5d1a2202017-12-13 19:51:29 +01003240 }
Harald Welte6f521d82017-12-11 19:52:02 +01003241
3242 if (isvalue(rsl_chneed)) {
3243 /* The values of 08.08 3.2.2.36 and 08.58 9.3.40 are luckily identical */
3244 bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
3245 } else {
3246 bssmap_chneed := omit;
3247 }
3248
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003249 BSSAP.send(ts_BSSAP_UNITDATA_req(g_bssap[0].sccp_addr_peer, g_bssap[0].sccp_addr_own,
3250 ts_BSSMAP_Paging(imsi, cid_list, tmsi, bssmap_chneed)));
Harald Welte6f521d82017-12-11 19:52:02 +01003251
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003252 if (not istemplatekind(tmsi, "omit")) {
3253 mi := t_MI_TMSI(tmsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003254 } else {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003255 mi := tr_MI_IMSI(imsi);
Harald Welte6f521d82017-12-11 19:52:02 +01003256 }
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003257
Harald Welte5d1a2202017-12-13 19:51:29 +01003258 for (i := 0; i < sizeof(bts_ids); i := i + 1) {
Vadim Yanitskiycc4623d2020-03-28 06:14:06 +07003259 rx_rsl := f_exp_ipa_rx(bts_ids[i], tr_RSL_PAGING_CMD(mi));
Harald Welte5d1a2202017-12-13 19:51:29 +01003260 /* check channel type, paging group */
3261 if (rx_rsl.ies[1].body.paging_group != paging_group) {
3262 setverdict(fail, "Paging for wrong paging group");
3263 }
3264 if (ispresent(rsl_chneed) and
3265 rx_rsl.ies[3].body.chan_needed.chan_needed != valueof(rsl_chneed)) {
3266 setverdict(fail, "RSL Channel Needed != BSSMAP Channel Needed");
3267 }
Harald Welte6f521d82017-12-11 19:52:02 +01003268 }
Harald Welte2fccd982018-01-31 15:48:19 +01003269 f_sleep(2.0);
Harald Welte5d1a2202017-12-13 19:51:29 +01003270 /* do a quick check on all not-included BTSs if they received paging */
3271 for (i := 0; i < NUM_BTS; i := i + 1) {
3272 timer T := 0.1;
3273 if (f_bts_in_list(i, bts_ids)) {
3274 continue;
3275 }
3276 T.start;
3277 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003278 [] IPA_RSL[i].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(mi))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003279 setverdict(fail, "Paging on BTS ", i, " which is not part of ", bts_ids);
3280 }
3281 [] IPA_RSL[i].receive { repeat; }
3282 [] T.timeout { }
3283 }
Harald Welte6f521d82017-12-11 19:52:02 +01003284 }
3285
3286 setverdict(pass);
3287}
3288
Harald Welte5d1a2202017-12-13 19:51:29 +01003289const BtsIdList c_BtsId_all := { 0, 1, 2 };
Harald Welte751d3eb2018-01-31 15:51:06 +01003290const BtsIdList c_BtsId_none := { };
Harald Welte5d1a2202017-12-13 19:51:29 +01003291const BtsIdList c_BtsId_LAC1 := { 0, 1 };
3292const BtsIdList c_BtsId_LAC2 := { 2 };
3293
Harald Welte6f521d82017-12-11 19:52:02 +01003294/* PAGING by IMSI + TMSI */
3295testcase TC_paging_imsi_nochan() runs on test_CT {
3296 var BSSMAP_FIELD_CellIdentificationList cid_list;
3297 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Philipp Maier8c04b0a2018-02-23 13:48:48 +01003298 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, omit);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003299 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003300}
3301
3302/* PAGING by IMSI + TMSI */
3303testcase TC_paging_tmsi_nochan() runs on test_CT {
3304 var BSSMAP_FIELD_CellIdentificationList cid_list;
3305 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003306 f_pageing_helper('001010100000001'H, cid_list, c_BtsId_all, omit, 'A1B2C301'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003307 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003308}
3309
3310/* Paging with different "channel needed' values */
3311testcase TC_paging_tmsi_any() runs on test_CT {
3312 var BSSMAP_FIELD_CellIdentificationList cid_list;
3313 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003314 f_pageing_helper('001010100000002'H, cid_list, c_BtsId_all, RSL_CHANNEED_ANY, 'A1B2C302'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003315 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003316}
3317testcase TC_paging_tmsi_sdcch() runs on test_CT {
3318 var BSSMAP_FIELD_CellIdentificationList cid_list;
3319 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003320 f_pageing_helper('001010100000003'H, cid_list, c_BtsId_all, RSL_CHANNEED_SDCCH, 'A1B2C303'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003321 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003322}
3323testcase TC_paging_tmsi_tch_f() runs on test_CT {
3324 var BSSMAP_FIELD_CellIdentificationList cid_list;
3325 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003326 f_pageing_helper('001010000000004'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_F, 'A1B2C304'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003327 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003328}
3329testcase TC_paging_tmsi_tch_hf() runs on test_CT {
3330 var BSSMAP_FIELD_CellIdentificationList cid_list;
3331 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003332 f_pageing_helper('001010000000005'H, cid_list, c_BtsId_all, RSL_CHANNEED_TCH_ForH, 'A1B2C305'O);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003333 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003334}
3335
3336/* Paging by CGI */
3337testcase TC_paging_imsi_nochan_cgi() runs on test_CT {
3338 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3339 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(cid.mcc, cid.mnc, cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003340 f_pageing_helper('001010000000006'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003341 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003342}
3343
3344/* Paging by LAC+CI */
3345testcase TC_paging_imsi_nochan_lac_ci() runs on test_CT {
3346 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3347 cid_list := { cIl_LAC_CI := { ts_BSSMAP_CI_LAC_CI(cid.lac, cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003348 f_pageing_helper('001010000000007'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003349 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003350}
3351
3352/* Paging by CI */
3353testcase TC_paging_imsi_nochan_ci() runs on test_CT {
3354 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3355 cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(cid.ci) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003356 f_pageing_helper('001010000000008'H, cid_list, { 0 });
Philipp Maier282ca4b2018-02-27 17:17:00 +01003357 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003358}
3359
3360/* Paging by LAI */
3361testcase TC_paging_imsi_nochan_lai() runs on test_CT {
3362 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3363 cid_list := { cIl_LAI := { ts_BSSMAP_CI_LAI(cid.mcc, cid.mnc, cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003364 f_pageing_helper('001010000000009'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003365 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003366}
3367
3368/* Paging by LAC */
3369testcase TC_paging_imsi_nochan_lac() runs on test_CT {
3370 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3371 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(cid.lac) } };
Harald Welte5d1a2202017-12-13 19:51:29 +01003372 f_pageing_helper('001010000000010'H, cid_list, c_BtsId_LAC1);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003373 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003374}
3375
3376/* Paging by "all in BSS" */
3377testcase TC_paging_imsi_nochan_all() runs on test_CT {
3378 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3379 cid_list := { cIl_allInBSS := ''O };
Harald Welte5d1a2202017-12-13 19:51:29 +01003380 f_pageing_helper('001010000000011'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003381 f_shutdown_helper();
Harald Welte6f521d82017-12-11 19:52:02 +01003382}
3383
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003384/* Paging by PLMN+LAC+RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003385testcase TC_paging_imsi_nochan_plmn_lac_rnc() runs on test_CT {
3386 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3387 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 +01003388 f_pageing_helper('001010000000012'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003389 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003390}
Harald Welte6f521d82017-12-11 19:52:02 +01003391
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003392/* Paging by RNC; We do not implement this; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003393testcase TC_paging_imsi_nochan_rnc() runs on test_CT {
3394 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3395 cid_list := { cIl_RNC := { int2oct(13, 2) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003396 f_pageing_helper('001010000000013'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003397 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003398}
3399
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003400/* Paging by LAC+RNC; We do not implement; Verify nothing is paged */
Harald Welte751d3eb2018-01-31 15:51:06 +01003401testcase TC_paging_imsi_nochan_lac_rnc() runs on test_CT {
3402 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3403 cid_list := { cIl_LAC_RNC := { ts_BSSMAP_CI_LAC_RNC(cid.lac, 14) } };
Stefan Sperling7b5e1782018-03-20 19:32:43 +01003404 f_pageing_helper('001010000000014'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003405 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003406}
3407
Harald Welte6f521d82017-12-11 19:52:02 +01003408/* Paging on multiple cells (multiple entries in list): Verify all of them page */
Harald Welte751d3eb2018-01-31 15:51:06 +01003409testcase TC_paging_imsi_nochan_lacs() runs on test_CT {
3410 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3411 cid_list := { cIl_LAC := { ts_BSSMAP_CI_LAC(1), ts_BSSMAP_CI_LAC(2) } };
3412 f_pageing_helper('001010000000015'H, cid_list, c_BtsId_all);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003413 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003414}
3415
3416/* Paging on empty list: Verify none of them page */
3417testcase TC_paging_imsi_nochan_lacs_empty() runs on test_CT {
3418 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3419 cid_list := { cIl_LAC := { } };
3420 f_pageing_helper('001010000000016'H, cid_list, c_BtsId_none);
Philipp Maier282ca4b2018-02-27 17:17:00 +01003421 f_shutdown_helper();
Harald Welte751d3eb2018-01-31 15:51:06 +01003422}
3423
Stefan Sperling049a86e2018-03-20 15:51:00 +01003424/* Paging by CGI with unknown MCC/MNC: Verify nothing is paged. */
3425testcase TC_paging_imsi_nochan_cgi_unknown_cid() runs on test_CT {
3426 var template BSSMAP_FIELD_CellIdentificationList cid_list;
3427 cid_list := { cIl_CGI := { ts_BSSMAP_CI_CGI(unknown_cid.mcc, unknown_cid.mnc, unknown_cid.lac, unknown_cid.ci) } };
3428 f_pageing_helper('001010000000006'H, cid_list, c_BtsId_none);
3429 f_shutdown_helper();
3430}
3431
Harald Welte6f521d82017-12-11 19:52:02 +01003432/* Verify paging retransmission interval + count */
3433/* Verify paging stops after channel establishment */
Harald Welte6f521d82017-12-11 19:52:02 +01003434/* Test behavior under paging overload */
Harald Welteae026692017-12-09 01:03:01 +01003435
Harald Weltee65d40e2017-12-13 00:09:06 +01003436/* Verify PCH load */
3437testcase TC_paging_imsi_load() runs on test_CT {
3438 var BSSMAP_FIELD_CellIdentificationList cid_list;
3439 timer T := 4.0;
Harald Welte2caa1062018-03-17 18:19:05 +01003440 timer T_retrans := 1.0;
Harald Weltee65d40e2017-12-13 00:09:06 +01003441 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003442 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Weltee65d40e2017-12-13 00:09:06 +01003443
3444 /* tell BSC there is no paging space anymore */
3445 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
Harald Welte3b57ab52018-03-17 18:01:10 +01003446 f_sleep(0.2);
3447 IPA_RSL[0].clear;
Harald Weltee65d40e2017-12-13 00:09:06 +01003448
3449 /* Wait for 4 seconds if any more PAGING CMD are received on RSL. Normally,
3450 * there would be 8 retransmissions during 4 seconds */
3451 T.start;
Harald Welte2caa1062018-03-17 18:19:05 +01003452 T_retrans.start;
Harald Weltee65d40e2017-12-13 00:09:06 +01003453 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003454 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Weltee65d40e2017-12-13 00:09:06 +01003455 setverdict(fail, "Received PAGING after LOAD_IND(0)");
Daniel Willmannafce8662018-07-06 23:11:32 +02003456 mtc.stop;
Harald Weltee65d40e2017-12-13 00:09:06 +01003457 }
Harald Welte2caa1062018-03-17 18:19:05 +01003458 [] T_retrans.timeout {
3459 /* re-trnsmit the zero-space LOAD IND to avoid BSC 'auto credit' */
3460 f_ipa_tx(0, ts_RSL_PAGING_LOAD_IND(0));
3461 T_retrans.start;
3462 repeat;
3463 }
Harald Weltee65d40e2017-12-13 00:09:06 +01003464 [] T.timeout {
3465 setverdict(pass);
3466 }
3467 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003468
3469 f_shutdown_helper();
Harald Weltee65d40e2017-12-13 00:09:06 +01003470}
3471
Harald Welte235ebf12017-12-15 14:18:16 +01003472/* Verify Paging Counter */
Harald Welte1ff69992017-12-14 12:31:17 +01003473testcase TC_paging_counter() runs on test_CT {
3474 var BSSMAP_FIELD_CellIdentificationList cid_list;
3475 timer T := 4.0;
3476 var integer i;
3477 var integer paging_attempted_bsc;
3478 var integer paging_attempted_bts[NUM_BTS];
Oliver Smith8b343d32021-11-26 13:01:42 +01003479 var integer paging_expired_bsc;
Harald Welte1ff69992017-12-14 12:31:17 +01003480 var integer paging_expired_bts[NUM_BTS];
3481 cid_list := valueof(ts_BSSMAP_CIL_noCell);
3482
3483 f_init();
3484
3485 /* read counters before paging */
3486 paging_attempted_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted");
Oliver Smith8b343d32021-11-26 13:01:42 +01003487 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3488 paging_expired_bsc := f_ctrl_get_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired");
3489 }
Harald Welte1ff69992017-12-14 12:31:17 +01003490 for (i := 0; i < NUM_BTS; i := i+1) {
3491 paging_attempted_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted");
3492 paging_expired_bts[i] := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired");
3493 }
3494
3495 f_pageing_helper('001230000000001'H, cid_list, c_BtsId_all);
3496
3497 /* expect the attempted pages on BSC and each BTSs to have incremented by one */
3498 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:attempted", paging_attempted_bsc+1);
3499 for (i := 0; i < NUM_BTS; i := i+1) {
3500 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:attempted",
3501 paging_attempted_bts[i]+1);
3502 }
3503
3504 /* assume that 12s later the paging on all BTSs have expired and hence incremented by 1 */
3505 f_sleep(12.0);
Oliver Smith8b343d32021-11-26 13:01:42 +01003506 if (Misc_Helpers.f_osmo_repo_is("nightly")) { /* osmo-bsc > 1.8.0 */
3507 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bsc", 0, "paging:expired", paging_expired_bsc+1);
3508 }
Harald Welte1ff69992017-12-14 12:31:17 +01003509 for (i := 0; i < NUM_BTS; i := i+1) {
3510 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", i, "paging:expired",
3511 paging_expired_bts[i]+1);
3512 }
Harald Welte1ff69992017-12-14 12:31:17 +01003513
Philipp Maier282ca4b2018-02-27 17:17:00 +01003514 f_shutdown_helper();
Harald Welte1ff69992017-12-14 12:31:17 +01003515}
3516
3517
Harald Welte10985002017-12-12 09:29:15 +01003518/* Verify paging stops after A-RESET */
3519testcase TC_paging_imsi_a_reset() runs on test_CT {
3520 var BSSMAP_FIELD_CellIdentificationList cid_list;
3521 timer T := 3.0;
3522 cid_list := valueof(ts_BSSMAP_CIL_noCell);
Harald Welte5d1a2202017-12-13 19:51:29 +01003523 f_pageing_helper('001010123456789'H, cid_list, c_BtsId_all);
Harald Welte10985002017-12-12 09:29:15 +01003524
3525 /* Perform a BSSMAP Reset and wait for ACK */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003526 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 +01003527 alt {
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003528 [] 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 +01003529 [] BSSAP.receive { repeat; }
3530 }
3531
Daniel Willmanncbef3982018-07-30 09:22:40 +02003532 /* Wait to avoid a possible race condition if a paging message is
3533 * received right before the reset ACK. */
3534 f_sleep(0.2);
3535
Harald Welte10985002017-12-12 09:29:15 +01003536 /* Clear the queue, it might still contain stuff like BCCH FILLING */
Philipp Maier1e6b4422018-02-23 14:02:13 +01003537 for (var integer i := 0; i < sizeof(IPA_RSL); i := i+1) {
3538 IPA_RSL[i].clear;
3539 }
Harald Welte10985002017-12-12 09:29:15 +01003540
3541 /* Wait for 3 seconds if any more PAGING CMD are received on RSL */
3542 T.start;
3543 alt {
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003544 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte10985002017-12-12 09:29:15 +01003545 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003546 mtc.stop;
Harald Welte10985002017-12-12 09:29:15 +01003547 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003548 [] IPA_RSL[1].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003549 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003550 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003551 }
Vadim Yanitskiy9b4e3562020-05-25 21:40:52 +07003552 [] IPA_RSL[2].receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD(?))) {
Harald Welte5d1a2202017-12-13 19:51:29 +01003553 setverdict(fail, "Received PAGING after A-RESET");
Daniel Willmannafce8662018-07-06 23:11:32 +02003554 mtc.stop;
Harald Welte5d1a2202017-12-13 19:51:29 +01003555 }
Harald Welte10985002017-12-12 09:29:15 +01003556 [] T.timeout {
3557 setverdict(pass);
3558 }
3559 }
Philipp Maier282ca4b2018-02-27 17:17:00 +01003560
3561 f_shutdown_helper();
Harald Welte10985002017-12-12 09:29:15 +01003562}
Harald Welteae026692017-12-09 01:03:01 +01003563
Philipp Maierf45824a2019-08-14 14:44:10 +02003564/* Verify how we handle unsolicited Paging Response. In case of an unsolicit
3565 * paging response we can not know which MSC is in charge, so we will blindly
3566 * pick the first configured MSC. This behavior is required in order to make
3567 * MT-CSFB calls working because in those cases the BSC can not know that the
3568 * MSC has already paged the subscriver via SGs. So any MT-CSFB call will look
3569 * like an unsolicited Paging Response to the MSC.
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003570 */
3571testcase TC_paging_resp_unsol() runs on test_CT {
3572
3573 f_init(1);
Philipp Maierf45824a2019-08-14 14:44:10 +02003574 timer T := 5.0;
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003575
3576 var BSSAP_N_CONNECT_ind rx_c_ind;
3577 var DchanTuple dt;
3578 var PDU_ML3_MS_NW l3 := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010008880018'H))));
Philipp Maierf45824a2019-08-14 14:44:10 +02003579 var octetstring rr_pag_resp := enc_PDU_ML3_MS_NW(l3);
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003580
3581 /* Send CHAN RQD and wait for allocation; acknowledge it */
3582 dt.rsl_chan_nr := f_chreq_act_ack();
3583
3584 /* Send unsolicited Paging response (no matching Paging CMD stored in BSC) */
3585 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), enc_PDU_ML3_MS_NW(l3)));
3586
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003587
Philipp Maierf45824a2019-08-14 14:44:10 +02003588 /* Expevct a CR with a matching Paging response on the A-Interface */
3589 T.start;
3590 alt {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003591 [] BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(rr_pag_resp))) -> value rx_c_ind {
Philipp Maierf45824a2019-08-14 14:44:10 +02003592 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003593 dt.sccp_conn_id := rx_c_ind.connectionId;
3594 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
Philipp Maierf45824a2019-08-14 14:44:10 +02003595 }
3596 [] BSSAP.receive {
3597 setverdict(fail, "Received unexpected message on A-Interface!");
3598 }
3599 [] T.timeout {
3600 setverdict(fail, "Received nothing on A-Interface!");
3601 }
3602 }
3603
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003604 f_perform_clear_test_ct(dt);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003605 f_shutdown_helper();
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +01003606}
3607
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003608/* Test RSL link drop causes counter increment */
3609testcase TC_rsl_drop_counter() runs on test_CT {
3610 var integer rsl_fail;
3611
Harald Welte89d42e82017-12-17 16:42:41 +01003612 f_init(1);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003613
3614 rsl_fail := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail");
3615
Pau Espin Pedrolaf0c61e2022-01-11 12:48:34 +01003616 f_ipa_rsl_stop(bts[0].rsl);
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003617
3618 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "rsl_fail", rsl_fail+1);
3619
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003620 f_shutdown_helper();
Harald Welte4e9b9cc2017-12-14 18:31:02 +01003621}
3622
3623/* TODO: Test OML link drop causes counter increment */
3624
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003625/* The body of TC_rsl_unknown_unit_id() and TC_oml_unknown_unit_id() tests. */
3626function f_ipa_unknown_unit_id(integer mp_bsc_ipa_port) runs on test_CT return boolean {
3627 timer T := 10.0;
3628
3629 bts[0].rsl.id := "IPA-0-RSL";
Harald Welte71389132021-12-09 21:58:18 +01003630 bts[0].rsl.vc_IPA := IPA_Emulation_CT.create(bts[0].rsl.id & "-IPA") alive;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003631 bts[0].rsl.ccm_pars := c_IPA_default_ccm_pars;
3632 bts[0].rsl.ccm_pars.name := "Osmocom TTCN-3 BTS Simulator";
Oliver Smith92c2bdb2019-08-20 15:11:24 +02003633 bts[0].rsl.ccm_pars.unit_id := "99/0/0"; /* value which is unknown at BTS */
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003634
Pau Espin Pedrol9a5b8ff2021-01-04 19:01:31 +01003635 f_ipa_ctrl_start_client(mp_bsc_ip, mp_bsc_ctrl_port);
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003636
3637 f_init_mgcp("VirtMSC");
3638
3639 /* start RSL/OML connection (XXX re-uses RSL port/protocol definitions for OML) */
3640 map(bts[0].rsl.vc_IPA:IPA_PORT, system:IPA);
3641 connect(bts[0].rsl.vc_IPA:IPA_RSL_PORT, self:IPA_RSL[0]);
3642 bts[0].rsl.vc_IPA.start(IPA_Emulation.main_client(mp_bsc_ip, mp_bsc_ipa_port, "", 10000, bts[0].rsl.ccm_pars));
3643
3644 /* wait for IPA OML link to connect and then disconnect */
3645 T.start;
3646 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +07003647 [] IPA_RSL[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003648 T.stop;
3649 return true;
3650 }
3651 [] IPA_RSL[0].receive { repeat }
3652 [] T.timeout {
Daniel Willmannafce8662018-07-06 23:11:32 +02003653 return false;
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003654 }
3655 }
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003656 return false;
3657}
3658
3659/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3660testcase TC_rsl_unknown_unit_id() runs on test_CT {
3661 if (f_ipa_unknown_unit_id(mp_bsc_rsl_port)) {
3662 setverdict(pass);
3663 } else {
3664 setverdict(fail, "Timeout RSL waiting for connection to close");
3665 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003666 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003667}
3668
3669
3670/* BSC should close an RSL connection from a BTS with unknown unit ID (OS#2714). */
3671testcase TC_oml_unknown_unit_id() runs on test_CT {
3672 if (f_ipa_unknown_unit_id(mp_bsc_oml_port)) {
3673 setverdict(pass);
3674 } else {
3675 setverdict(fail, "Timeout OML waiting for connection to close");
3676 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003677 f_shutdown_helper();
Stefan Sperling830dc9d2018-02-12 21:08:28 +01003678}
3679
3680
Harald Weltec1a2fff2017-12-17 11:06:19 +01003681/***********************************************************************
Harald Welte6811d102019-04-14 22:23:14 +02003682 * "New world" test cases using RSL_Emulation + RAN_Emulation
Harald Weltec1a2fff2017-12-17 11:06:19 +01003683 ***********************************************************************/
3684
Harald Welte6811d102019-04-14 22:23:14 +02003685import from RAN_Emulation all;
Harald Welte47cd0e32020-08-21 12:39:11 +02003686import from BSSAP_LE_Emulation all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01003687import from RSL_Emulation all;
3688import from MSC_ConnectionHandler all;
3689
3690type function void_fn(charstring id) runs on MSC_ConnHdlr;
3691
Harald Welte336820c2018-05-31 20:34:52 +02003692/* helper function to create and connect a MSC_ConnHdlr component */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003693private function f_connect_handler(inout MSC_ConnHdlr vc_conn, integer bssap_idx := 0) runs on test_CT {
3694 connect(vc_conn:RAN, g_bssap[bssap_idx].vc_RAN:PROC);
Daniel Willmann191e0d92018-01-17 12:44:35 +01003695 connect(vc_conn:MGCP_PROC, vc_MGCP:MGCP_PROC);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003696 connect(vc_conn:RSL, bts[0].rsl.vc_RSL:CLIENT_PT);
Harald Weltef70df652018-01-29 22:00:23 +01003697 connect(vc_conn:RSL_PROC, bts[0].rsl.vc_RSL:RSL_PROC);
Philipp Maier88f4ae82018-03-01 14:00:58 +01003698 if (isvalue(bts[1])) {
Philipp Maier956a92f2018-02-16 10:58:07 +01003699 connect(vc_conn:RSL1, bts[1].rsl.vc_RSL:CLIENT_PT);
3700 connect(vc_conn:RSL1_PROC, bts[1].rsl.vc_RSL:RSL_PROC);
3701 }
Neels Hofmeyr91401012019-07-11 00:42:35 +02003702 if (isvalue(bts[2])) {
3703 connect(vc_conn:RSL2, bts[2].rsl.vc_RSL:CLIENT_PT);
3704 connect(vc_conn:RSL2_PROC, bts[2].rsl.vc_RSL:RSL_PROC);
3705 }
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003706 connect(vc_conn:BSSAP, g_bssap[bssap_idx].vc_RAN:CLIENT);
Neels Hofmeyrcfe44062020-10-15 02:28:08 +02003707 if (mp_enable_lcs_tests) {
3708 connect(vc_conn:BSSAP_LE, g_bssap_le.vc_BSSAP_LE:CLIENT);
3709 connect(vc_conn:BSSAP_LE_PROC, g_bssap_le.vc_BSSAP_LE:PROC);
3710 }
Daniel Willmann191e0d92018-01-17 12:44:35 +01003711 connect(vc_conn:MGCP, vc_MGCP:MGCP_CLIENT);
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02003712 connect(vc_conn:MGCP_MULTI, vc_MGCP:MGCP_CLIENT_MULTI);
Daniel Willmannebdecc02020-08-12 15:30:17 +02003713 connect(vc_conn:STATSD_PROC, vc_STATSD:STATSD_PROC);
Harald Welte336820c2018-05-31 20:34:52 +02003714}
3715
Neels Hofmeyrda436782021-07-20 22:09:06 +02003716function f_start_handler_create(template (omit) TestHdlrParams pars := omit)
Harald Welte336820c2018-05-31 20:34:52 +02003717runs on test_CT return MSC_ConnHdlr {
3718 var charstring id := testcasename();
3719 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003720 var integer bssap_idx := 0;
3721 if (isvalue(pars)) {
3722 bssap_idx := valueof(pars).mscpool.bssap_idx;
3723 }
Harald Welte336820c2018-05-31 20:34:52 +02003724 vc_conn := MSC_ConnHdlr.create(id);
Neels Hofmeyrf246a922020-05-13 02:27:10 +02003725 f_connect_handler(vc_conn, bssap_idx);
Neels Hofmeyrda436782021-07-20 22:09:06 +02003726 return vc_conn;
3727}
3728
3729function f_start_handler_run(MSC_ConnHdlr vc_conn, void_fn fn, template (omit) TestHdlrParams pars := omit)
3730runs on test_CT return MSC_ConnHdlr {
3731 var charstring id := testcasename();
Harald Weltea0630032018-03-20 21:09:55 +01003732 vc_conn.start(f_handler_init(fn, id, pars));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003733 return vc_conn;
3734}
3735
Neels Hofmeyrda436782021-07-20 22:09:06 +02003736function f_start_handler(void_fn fn, template (omit) TestHdlrParams pars := omit)
3737runs on test_CT return MSC_ConnHdlr {
3738 return f_start_handler_run(f_start_handler_create(pars), fn, pars);
3739}
3740
Harald Weltea0630032018-03-20 21:09:55 +01003741/* first function inside ConnHdlr component; sets g_pars + starts function */
3742private function f_handler_init(void_fn fn, charstring id, template (omit) TestHdlrParams pars := omit)
3743runs on MSC_ConnHdlr {
3744 if (isvalue(pars)) {
3745 g_pars := valueof(pars);
3746 }
3747 fn.apply(id);
3748}
3749
Oliver Smith26a3db72021-07-09 13:51:29 +02003750private function f_vty_encryption_a5(charstring options) runs on test_CT {
3751 f_vty_transceive(BSCVTY, "configure terminal");
3752 f_vty_transceive(BSCVTY, "network");
3753 f_vty_transceive(BSCVTY, "encryption a5 " & options);
3754 f_vty_transceive(BSCVTY, "exit");
3755 f_vty_transceive(BSCVTY, "exit");
3756}
3757
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003758const charstring VTY_A5_DEFAULT := "0 1 3";
3759
Oliver Smith26a3db72021-07-09 13:51:29 +02003760private function f_vty_encryption_a5_reset() runs on test_CT {
3761 /* keep in sync with docker-playground.git ttcn3-bsc-test/osmo-bsc.cfg */
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01003762 f_vty_encryption_a5(VTY_A5_DEFAULT);
Oliver Smith26a3db72021-07-09 13:51:29 +02003763}
3764
Harald Welte3c86ea02018-05-10 22:28:05 +02003765/* Establish signalling channel (non-assignment case) followed by cipher mode */
3766private function f_tc_ciph_mode_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003767 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3768 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte3c86ea02018-05-10 22:28:05 +02003769 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Philipp Maier23000732018-05-18 11:25:37 +02003770 ass_cmd.pdu.bssmap.assignmentRequest.circuitIdentityCode := omit;
3771 ass_cmd.pdu.bssmap.assignmentRequest.aoIPTransportLayer := omit;
3772 exp_compl.pdu.bssmap.assignmentComplete.circuitIdentityCode := omit;
3773 exp_compl.pdu.bssmap.assignmentComplete.aoIPTransportLayer := omit;
Harald Welte3c86ea02018-05-10 22:28:05 +02003774
Philipp Maier23000732018-05-18 11:25:37 +02003775 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003776 f_perform_clear();
Harald Welte3c86ea02018-05-10 22:28:05 +02003777}
3778testcase TC_ciph_mode_a5_0() runs on test_CT {
3779 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003780 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003781 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
3782
3783 f_init(1, true);
3784 f_sleep(1.0);
3785 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3786 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003787 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003788}
3789testcase TC_ciph_mode_a5_1() runs on test_CT {
3790 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003791 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003792 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
3793
3794 f_init(1, true);
3795 f_sleep(1.0);
3796 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3797 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003798 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003799}
Oliver Smith50b98122021-07-09 15:00:28 +02003800/* OS#4975: verify that A5/2 is preferred over A5/0 */
3801testcase TC_ciph_mode_a5_2_0() runs on test_CT {
3802 var MSC_ConnHdlr vc_conn;
3803 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3804
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003805 pars.encr := f_encr_params('05'O, '04'O); /* A5/0 and A5/2 (0x01|0x04)*/
Oliver Smith50b98122021-07-09 15:00:28 +02003806
3807 f_init(1, true);
3808 f_vty_encryption_a5("0 1 2 3");
3809 f_sleep(1.0);
3810 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3811 vc_conn.done;
3812 f_vty_encryption_a5_reset();
3813 f_shutdown_helper();
3814}
Oliver Smith1dff88d2021-07-09 08:45:51 +02003815/* OS#4975: verify that A5/1 is preferred over A5/2 */
3816testcase TC_ciph_mode_a5_2_1() runs on test_CT {
3817 var MSC_ConnHdlr vc_conn;
3818 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3819
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01003820 pars.encr := f_encr_params('06'O, '02'O); /* A5/1 and A5/2 (0x02|0x04)*/
Oliver Smith1dff88d2021-07-09 08:45:51 +02003821
3822 f_init(1, true);
3823 f_vty_encryption_a5("1 2");
3824 f_sleep(1.0);
3825 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3826 vc_conn.done;
3827 f_vty_encryption_a5_reset();
3828 f_shutdown_helper();
3829}
Harald Welte3c86ea02018-05-10 22:28:05 +02003830testcase TC_ciph_mode_a5_3() runs on test_CT {
3831 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003832 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte3c86ea02018-05-10 22:28:05 +02003833 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
3834
3835 f_init(1, true);
3836 f_sleep(1.0);
3837 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3838 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003839 f_shutdown_helper();
Harald Welte3c86ea02018-05-10 22:28:05 +02003840}
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003841/* Establish a Signalling channel with A5/4 encryption. */
3842testcase TC_ciph_mode_a5_4() runs on test_CT {
3843 var MSC_ConnHdlr vc_conn;
3844 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3845 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Harald Welte3c86ea02018-05-10 22:28:05 +02003846
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003847 f_init(1, true);
Oliver Smith26a3db72021-07-09 13:51:29 +02003848 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003849 f_sleep(1.0);
3850 vc_conn := f_start_handler(refers(f_tc_ciph_mode_a5), pars);
3851 vc_conn.done;
Oliver Smith26a3db72021-07-09 13:51:29 +02003852 f_vty_encryption_a5_reset();
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +02003853 f_shutdown_helper();
3854}
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003855/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
3856private function f_tc_assignment_aoip_tla_v6(charstring id) runs on MSC_ConnHdlr {
3857 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3858 var PDU_BSSAP ass_cmd := f_gen_ass_req(aoip_tla := "::3");
3859 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3860 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3861
3862 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003863 f_perform_clear();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003864}
3865testcase TC_assignment_aoip_tla_v6() runs on test_CT {
3866 var MSC_ConnHdlr vc_conn;
3867 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3868
3869 f_init(1, true);
3870 f_sleep(1.0);
3871 vc_conn := f_start_handler(refers(f_tc_assignment_aoip_tla_v6), pars);
3872 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003873 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02003874}
3875
Harald Welte3c86ea02018-05-10 22:28:05 +02003876
3877/* establish initial channel, enable ciphering followed by assignment to ciphered channel */
Harald Welte651fcdc2018-05-10 20:23:16 +02003878private function f_tc_assignment_fr_a5(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02003879 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
3880 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003881
Harald Welte552620d2017-12-16 23:21:36 +01003882 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3883 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte73cd2712017-12-17 00:44:52 +01003884
Harald Weltea0630032018-03-20 21:09:55 +01003885 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003886 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003887}
Harald Welte552620d2017-12-16 23:21:36 +01003888testcase TC_assignment_fr_a5_0() runs on test_CT {
3889 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003890 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003891 pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
Harald Welte552620d2017-12-16 23:21:36 +01003892
Harald Welte89d42e82017-12-17 16:42:41 +01003893 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003894 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003895 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Welte552620d2017-12-16 23:21:36 +01003896 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003897 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003898}
Harald Welte552620d2017-12-16 23:21:36 +01003899testcase TC_assignment_fr_a5_1() runs on test_CT {
Harald Weltec1a2fff2017-12-17 11:06:19 +01003900 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003901 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003902 pars.encr := valueof(t_EncrParams('02'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003903
Harald Welte89d42e82017-12-17 16:42:41 +01003904 f_init(1, true);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003905 f_sleep(1.0);
Harald Welte651fcdc2018-05-10 20:23:16 +02003906 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3907 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003908 f_shutdown_helper();
Harald Welte651fcdc2018-05-10 20:23:16 +02003909}
3910testcase TC_assignment_fr_a5_3() runs on test_CT {
3911 var MSC_ConnHdlr vc_conn;
Philipp Maier48604732018-10-09 15:00:37 +02003912 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte651fcdc2018-05-10 20:23:16 +02003913 pars.encr := valueof(t_EncrParams('08'O, f_rnd_octstring(8)));
Harald Weltec1a2fff2017-12-17 11:06:19 +01003914
Harald Welte651fcdc2018-05-10 20:23:16 +02003915 f_init(1, true);
3916 f_sleep(1.0);
3917 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
Harald Weltec1a2fff2017-12-17 11:06:19 +01003918 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003919 f_shutdown_helper();
Harald Weltec1a2fff2017-12-17 11:06:19 +01003920}
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003921/* Establish a Signalling channel and re-assign to TCH/F with A5/4 encryption. */
3922testcase TC_assignment_fr_a5_4() runs on test_CT {
3923 var MSC_ConnHdlr vc_conn;
3924 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3925 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8), f_rnd_octstring(16)));
3926
3927 f_init(1, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02003928 f_vty_encryption_a5("0 1 3 4");
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003929 f_sleep(1.0);
3930 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
3931 vc_conn.done;
Oliver Smith7eabd312021-07-12 14:18:56 +02003932 f_vty_encryption_a5_reset();
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +02003933 f_shutdown_helper();
3934}
Harald Weltec1a2fff2017-12-17 11:06:19 +01003935
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +02003936/* Allow only A5/4, but omit the Kc128 IE from MSC's msg. Expect Cipher Mode Reject. */
3937testcase TC_assignment_fr_a5_4_fail() runs on test_CT {
3938 var TestHdlrParams pars := f_gen_test_hdlr_pars();
3939 var MSC_ConnHdlr vc_conn;
3940
3941 f_init(1, true);
3942 f_sleep(1.0);
3943
3944 pars.encr := valueof(t_EncrParams('10'O, f_rnd_octstring(8))); // A5/4 support, but Kc128 missing!
3945 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
3946 vc_conn.done;
3947 f_shutdown_helper();
3948}
3949
Harald Welte552620d2017-12-16 23:21:36 +01003950/* Expect ASSIGNMENT FAIL if mandatory IE is missing */
3951private function f_tc_assignment_fr_a5_1_codec_missing(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02003952 g_pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003953 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
Harald Welteed848512018-05-24 22:27:58 +02003954 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003955
3956 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02003957 /* Omit: ass_cmd.pdu.bssmap.assignmentRequest.codecList */
3958
Harald Weltea0630032018-03-20 21:09:55 +01003959 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003960 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003961}
Harald Welte552620d2017-12-16 23:21:36 +01003962testcase TC_assignment_fr_a5_1_codec_missing() runs on test_CT {
3963 var MSC_ConnHdlr vc_conn;
3964
Harald Welte89d42e82017-12-17 16:42:41 +01003965 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003966 f_sleep(1.0);
3967
Harald Welte8863fa12018-05-10 20:15:27 +02003968 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5_1_codec_missing));
Harald Welte552620d2017-12-16 23:21:36 +01003969 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02003970 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01003971}
3972
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003973private function f_TC_assignment_a5_not_sup(charstring id) runs on MSC_ConnHdlr {
3974 var template PDU_BSSAP exp_ass_cpl := f_gen_exp_compl();
3975 var PDU_BSSAP exp_ass_req := f_gen_ass_req();
Harald Welte552620d2017-12-16 23:21:36 +01003976
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003977 exp_ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
3978 exp_ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
3979
3980 /* this is like the beginning of f_establish_fully(), but only up to ciphering reject */
3981
3982 var BSSMAP_FIELD_CodecType codecType;
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003983
3984 codecType := exp_ass_req.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType;
3985 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
3986
3987 f_create_chan_and_exp();
3988 /* we should now have a COMPL_L3 at the MSC */
3989
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003990 /* Start ciphering, expect Cipher Mode Reject */
Neels Hofmeyr6c388f22021-06-11 02:36:56 +02003991 f_cipher_mode(g_pars.encr, exp_fail := true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01003992 f_perform_clear();
Harald Welte552620d2017-12-16 23:21:36 +01003993}
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02003994testcase TC_assignment_fr_a5_not_sup() runs on test_CT {
3995 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte552620d2017-12-16 23:21:36 +01003996 var MSC_ConnHdlr vc_conn;
3997
Harald Welte89d42e82017-12-17 16:42:41 +01003998 f_init(1, true);
Harald Welte552620d2017-12-16 23:21:36 +01003999 f_sleep(1.0);
4000
Neels Hofmeyr0588cad2021-06-11 01:38:18 +02004001 pars.encr := valueof(t_EncrParams('20'O, f_rnd_octstring(8), f_rnd_octstring(16)));
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +02004002 vc_conn := f_start_handler(refers(f_TC_assignment_a5_not_sup), pars);
Harald Welte552620d2017-12-16 23:21:36 +01004003 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004004 f_shutdown_helper();
Harald Welte552620d2017-12-16 23:21:36 +01004005}
4006
4007
Harald Welte4532e0a2017-12-23 02:05:44 +01004008private function f_tc_assignment_sign(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02004009 g_pars := f_gen_test_hdlr_pars();
Harald Welte4532e0a2017-12-23 02:05:44 +01004010 var template PDU_BSSAP exp_compl := tr_BSSMAP_AssignmentComplete(omit, omit);
Philipp Maier48604732018-10-09 15:00:37 +02004011 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte4532e0a2017-12-23 02:05:44 +01004012 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelTypeSIGNAL);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004013
4014 f_statsd_reset();
Harald Weltea0630032018-03-20 21:09:55 +01004015 f_establish_fully(ass_cmd, exp_compl);
Daniel Willmannebdecc02020-08-12 15:30:17 +02004016
4017 var StatsDExpects expect := {
Daniel Willmannc5398f72020-09-21 10:41:35 +02004018 { name := "TTCN3.bts.0.chreq.total", mtype := "c", min := 1, max := 1},
4019 { name := "TTCN3.bts.0.chreq.successful", mtype := "c", min := 1, max := 1},
Daniel Willmannebdecc02020-08-12 15:30:17 +02004020 { name := "TTCN3.bsc.0.assignment.attempted", mtype := "c", min := 1, max := 1},
4021 { name := "TTCN3.bsc.0.assignment.completed", mtype := "c", min := 1, max := 1}
4022 };
4023 f_statsd_expect(expect);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004024 f_perform_clear();
Harald Welte4532e0a2017-12-23 02:05:44 +01004025}
4026
4027testcase TC_assignment_sign() runs on test_CT {
4028 var MSC_ConnHdlr vc_conn;
4029
4030 f_init(1, true);
4031 f_sleep(1.0);
4032
Harald Welte8863fa12018-05-10 20:15:27 +02004033 vc_conn := f_start_handler(refers(f_tc_assignment_sign));
Harald Welte4532e0a2017-12-23 02:05:44 +01004034 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004035 f_shutdown_helper();
Harald Welte4532e0a2017-12-23 02:05:44 +01004036}
4037
Harald Welte60aa5762018-03-21 19:33:13 +01004038/***********************************************************************
4039 * Codec (list) testing
4040 ***********************************************************************/
4041
4042/* check if the given rsl_mode is compatible with the a_elem */
4043private function f_match_codec(BSSMAP_FIELD_CodecElement a_elem, RSL_IE_ChannelMode rsl_mode)
4044return boolean {
4045 select (a_elem.codecType) {
4046 case (GSM_FR) {
4047 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM1))) {
4048 return true;
4049 }
4050 }
4051 case (GSM_HR) {
4052 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM1))) {
4053 return true;
4054 }
4055 }
4056 case (GSM_EFR) {
4057 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM2))) {
4058 return true;
4059 }
4060 }
4061 case (FR_AMR) {
4062 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_F, RSL_CMOD_SP_GSM3))) {
4063 return true;
4064 }
4065 }
4066 case (HR_AMR) {
4067 if (match(rsl_mode, tr_RSL_ChanMode(RSL_CHRT_TCH_H, RSL_CMOD_SP_GSM3))) {
4068 return true;
4069 }
4070 }
4071 case else { }
4072 }
4073 return false;
4074}
4075
4076/* check if the given rsl_mode is compatible with the a_list */
4077private function f_match_codecs(BSSMAP_IE_SpeechCodecList a_list, RSL_IE_ChannelMode rsl_mode)
4078return boolean {
4079 for (var integer i := 0; i < sizeof(a_list); i := i+1) {
4080 if (f_match_codec(a_list.codecElements[i], rsl_mode)) {
4081 return true;
4082 }
4083 }
4084 return false;
4085}
4086
4087/* determine BSSMAP_IE_ChannelType from *first* element of BSSMAP_FIELD_CodecElement */
Philipp Maier61f6b572018-07-06 14:03:38 +02004088function f_BSSMAP_chtype_from_codec(BSSMAP_FIELD_CodecElement a_elem)
Harald Welte60aa5762018-03-21 19:33:13 +01004089return BSSMAP_IE_ChannelType {
4090 /* FIXME: actually look at all elements of BSSMAP_IE_SpeechCodecList */
4091 var BSSMAP_IE_ChannelType ret := valueof(ts_BSSMAP_IE_ChannelType);
4092 select (a_elem.codecType) {
4093 case (GSM_FR) {
4094 ret.channelRateAndType := ChRate_TCHF;
4095 ret.speechId_DataIndicator := Spdi_TCHF_FR;
4096 }
4097 case (GSM_HR) {
4098 ret.channelRateAndType := ChRate_TCHH;
4099 ret.speechId_DataIndicator := Spdi_TCHH_HR;
4100 }
4101 case (GSM_EFR) {
4102 ret.channelRateAndType := ChRate_TCHF;
4103 ret.speechId_DataIndicator := Spdi_TCHF_EFR;
4104 }
4105 case (FR_AMR) {
4106 ret.channelRateAndType := ChRate_TCHF;
4107 ret.speechId_DataIndicator := Spdi_TCHF_AMR;
4108 }
4109 case (HR_AMR) {
4110 ret.channelRateAndType := ChRate_TCHH;
4111 ret.speechId_DataIndicator := Spdi_TCHH_AMR;
4112 }
4113 case else {
4114 setverdict(fail, "Unsupported codec ", a_elem);
Daniel Willmannafce8662018-07-06 23:11:32 +02004115 mtc.stop;
Harald Welte60aa5762018-03-21 19:33:13 +01004116 }
4117 }
4118 return ret;
4119}
4120
Harald Weltea63b9102018-03-22 20:36:16 +01004121private function f_rsl_chmod_tmpl_from_codec(BSSMAP_FIELD_CodecElement a_elem)
4122return template RSL_IE_Body {
4123 var template RSL_IE_Body mode_ie := {
4124 chan_mode := {
4125 len := ?,
4126 reserved := ?,
4127 dtx_d := ?,
4128 dtx_u := ?,
4129 spd_ind := RSL_SPDI_SPEECH,
4130 ch_rate_type := -,
4131 coding_alg_rate := -
4132 }
4133 }
4134
4135 select (a_elem.codecType) {
4136 case (GSM_FR) {
4137 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4138 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4139 }
4140 case (GSM_HR) {
4141 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4142 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM1;
4143 }
4144 case (GSM_EFR) {
4145 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4146 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM2;
4147 }
4148 case (FR_AMR) {
4149 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_F;
4150 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4151 }
4152 case (HR_AMR) {
4153 mode_ie.chan_mode.ch_rate_type := RSL_CHRT_TCH_H;
4154 mode_ie.chan_mode.coding_alg_rate := RSL_CMOD_SP_GSM3;
4155 }
4156 }
4157 return mode_ie;
4158}
4159
Harald Welte60aa5762018-03-21 19:33:13 +01004160type record CodecListTest {
4161 BSSMAP_IE_SpeechCodecList codec_list,
4162 charstring id
4163}
4164type record of CodecListTest CodecListTests
4165
4166private function f_TC_assignment_codec(charstring id) runs on MSC_ConnHdlr {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004167 f_assignment_codec(id);
4168}
4169
4170private function f_assignment_codec(charstring id, boolean do_perform_clear := true) runs on MSC_ConnHdlr {
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02004171 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
4172 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
Harald Welte60aa5762018-03-21 19:33:13 +01004173
4174 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004175 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte79f3f542018-05-25 20:02:37 +02004176 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4177 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
4178 g_pars.ass_codec_list.codecElements[0];
Philipp Maierd0e64b02019-03-13 14:15:23 +01004179 if (isvalue(g_pars.expect_mr_s0_s7)) {
4180 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
4181 g_pars.expect_mr_s0_s7;
4182 }
Harald Welte79f3f542018-05-25 20:02:37 +02004183 }
Harald Welte60aa5762018-03-21 19:33:13 +01004184 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4185 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
Harald Welte60aa5762018-03-21 19:33:13 +01004186 log("expecting ASS COMPL like this: ", exp_compl);
4187
4188 f_establish_fully(ass_cmd, exp_compl);
Harald Weltea63b9102018-03-22 20:36:16 +01004189
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004190 if (not g_pars.expect_channel_mode_modify) {
4191 /* Verify that the RSL-side activation actually matches our expectations */
4192 var RSL_Message rsl := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
Harald Weltea63b9102018-03-22 20:36:16 +01004193
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004194 var RSL_IE_Body mode_ie;
4195 if (f_rsl_find_ie(rsl, RSL_IE_CHAN_MODE, mode_ie) == false) {
4196 setverdict(fail, "Couldn't find CHAN_MODE IE");
Daniel Willmannafce8662018-07-06 23:11:32 +02004197 mtc.stop;
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004198 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004199 var template RSL_IE_Body t_mode_ie := f_rsl_chmod_tmpl_from_codec(g_pars.ass_codec_list.codecElements[0]);
4200 if (not match(mode_ie, t_mode_ie)) {
4201 log("mode_ie ", mode_ie, " != t_mode_ie ", t_mode_ie);
4202 setverdict(fail, "RSL Channel Mode IE doesn't match expectation");
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004203 }
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004204
4205 var RSL_IE_Body mr_conf;
4206 if (g_pars.expect_mr_conf_ie != omit) {
4207 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == false) {
4208 setverdict(fail, "Missing MR CONFIG IE in RSL Chan Activ");
4209 mtc.stop;
4210 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004211 log("found RSL MR CONFIG IE: ", mr_conf);
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004212
4213 if (not match(mr_conf, g_pars.expect_mr_conf_ie)) {
4214 setverdict(fail, "RSL MR CONFIG IE does not match expectation. Expected: ",
4215 g_pars.expect_mr_conf_ie);
4216 }
4217 } else {
4218 if (f_rsl_find_ie(rsl, RSL_IE_MR_CONFIG, mr_conf) == true) {
4219 log("found RSL MR CONFIG IE: ", mr_conf);
4220 setverdict(fail, "Found MR CONFIG IE in RSL Chan Activ, expecting omit");
4221 mtc.stop;
4222 }
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004223 }
4224 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004225
4226 if (do_perform_clear) {
4227 f_perform_clear();
4228 }
Harald Welte60aa5762018-03-21 19:33:13 +01004229}
4230
Philipp Maierd0e64b02019-03-13 14:15:23 +01004231private function f_TC_assignment_codec_fail(charstring id) runs on MSC_ConnHdlr {
4232
4233 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4234 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4235
4236 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
Neels Hofmeyrf246a922020-05-13 02:27:10 +02004237 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maierd0e64b02019-03-13 14:15:23 +01004238 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
4239 }
4240 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
4241 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
4242 log("expecting ASS FAIL like this: ", exp_fail);
4243
4244 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004245 f_perform_clear();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004246}
4247
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004248const CounterNameVals counternames_bsc_bts_assignment := {
4249 { "assignment:attempted", 0 },
4250 { "assignment:completed", 0 },
4251 { "assignment:stopped", 0 },
4252 { "assignment:no_channel", 0 },
4253 { "assignment:timeout", 0 },
4254 { "assignment:failed", 0 },
4255 { "assignment:error", 0 }
4256};
4257
4258const CounterNameVals counternames_bts_assignment := {
4259 { "assignment:attempted_sign", 0 },
4260 { "assignment:attempted_speech", 0 },
4261 { "assignment:completed_sign", 0 },
4262 { "assignment:completed_speech", 0 },
4263 { "assignment:stopped_sign", 0 },
4264 { "assignment:stopped_speech", 0 },
4265 { "assignment:no_channel_sign", 0 },
4266 { "assignment:no_channel_speech", 0 },
4267 { "assignment:timeout_sign", 0 },
4268 { "assignment:timeout_speech", 0 },
4269 { "assignment:failed_sign", 0 },
4270 { "assignment:failed_speech", 0 },
4271 { "assignment:error_sign", 0 },
4272 { "assignment:error_speech", 0 }
4273};
4274
4275function f_ctrs_bsc_and_bts_assignment_init(integer bts_count := NUM_BTS) runs on test_CT {
4276 var CounterNameVals bts_names := counternames_bsc_bts_assignment & counternames_bts_assignment;
4277 f_ctrs_bts_init(bts_count, bts_names);
4278 f_ctrs_bsc_init(counternames_bsc_bts_assignment);
4279}
4280
Harald Welte60aa5762018-03-21 19:33:13 +01004281testcase TC_assignment_codec_fr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004282 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004283 var MSC_ConnHdlr vc_conn;
4284
4285 f_init(1, true);
4286 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004287 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004288
4289 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004290 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004291 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004292
4293 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4294 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4295 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4296 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4297 f_ctrs_bts_verify();
4298
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004299 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004300}
4301
4302testcase TC_assignment_codec_hr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004303 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004304 var MSC_ConnHdlr vc_conn;
4305
4306 f_init(1, true);
4307 f_sleep(1.0);
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004308 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004309
4310 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004311 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004312 vc_conn.done;
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004313
4314 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4315 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4316 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4317 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4318 f_ctrs_bts_verify();
4319
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004320 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004321}
4322
4323testcase TC_assignment_codec_efr() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004324 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004325 var MSC_ConnHdlr vc_conn;
4326
4327 f_init(1, true);
4328 f_sleep(1.0);
4329
4330 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecEFR}));
Harald Welte8863fa12018-05-10 20:15:27 +02004331 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004332 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004333 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004334}
4335
Philipp Maierd0e64b02019-03-13 14:15:23 +01004336/* Allow 5,90k only (current default config) */
4337private function f_allow_amr_rate_5_90k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004338 f_vty_cfg_msc(BSCVTY, 0, {
4339 "amr-config 12_2k forbidden",
4340 "amr-config 10_2k forbidden",
4341 "amr-config 7_95k forbidden",
4342 "amr-config 7_40k forbidden",
4343 "amr-config 6_70k forbidden",
4344 "amr-config 5_90k allowed",
4345 "amr-config 5_15k forbidden",
4346 "amr-config 4_75k forbidden"
4347 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004348}
4349
4350/* Allow 4,75k, 5,90k, 4,70k and 12,2k, which are the most common rates
4351 * ("Config-NB-Code = 1") */
4352private function f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k() runs on test_CT {
Neels Hofmeyr2a5670b2020-11-25 23:39:57 +00004353 f_vty_cfg_msc(BSCVTY, 0, {
4354 "amr-config 12_2k allowed",
4355 "amr-config 10_2k forbidden",
4356 "amr-config 7_95k forbidden",
4357 "amr-config 7_40k allowed",
4358 "amr-config 6_70k forbidden",
4359 "amr-config 5_90k allowed",
4360 "amr-config 5_15k forbidden",
4361 "amr-config 4_75k allowed"
4362 });
Philipp Maierd0e64b02019-03-13 14:15:23 +01004363}
4364
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004365private function f_vty_amr_start_mode_set(boolean fr, charstring startmode) runs on test_CT {
4366 var charstring tch;
4367 if (fr) {
4368 tch := "tch-f";
4369 } else {
4370 tch := "tch-h";
4371 }
4372 f_vty_cfg_bts(BSCVTY, 0, { "amr " & tch & " start-mode " & startmode });
4373}
4374
4375/* Set the AMR start-mode for this TCH back to the default configuration. */
4376private function f_vty_amr_start_mode_restore(boolean fr) runs on test_CT {
4377 f_vty_amr_start_mode_set(fr, "auto");
4378}
4379
Harald Welte60aa5762018-03-21 19:33:13 +01004380testcase TC_assignment_codec_amr_f() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004381 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004382 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004383
4384 /* Note: This setups the codec configuration. The parameter payload in
4385 * mr_conf must be consistant with the parameter codecElements in pars
4386 * and also must match the amr-config in osmo-bsc.cfg! */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004387 var RSL_IE_Body mr_conf := {
4388 other := {
4389 len := 2,
4390 payload := '2804'O
4391 }
4392 };
Harald Welte60aa5762018-03-21 19:33:13 +01004393
Philipp Maier7695a0d2018-09-27 17:52:14 +02004394 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004395 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004396 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4397 pars.expect_mr_conf_ie := mr_conf;
4398
Harald Welte60aa5762018-03-21 19:33:13 +01004399 f_init(1, true);
4400 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004401 f_vty_amr_start_mode_set(true, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004402 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004403
Harald Welte8863fa12018-05-10 20:15:27 +02004404 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004405 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004406
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004407 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4408 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4409 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4410 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4411 f_ctrs_bts_verify();
4412
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004413 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004414 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004415}
4416
4417testcase TC_assignment_codec_amr_h() runs on test_CT {
Philipp Maier48604732018-10-09 15:00:37 +02004418 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte60aa5762018-03-21 19:33:13 +01004419 var MSC_ConnHdlr vc_conn;
Philipp Maier7695a0d2018-09-27 17:52:14 +02004420
4421 /* See note above */
Neels Hofmeyrbcf62bc2018-07-04 00:24:33 +02004422 var RSL_IE_Body mr_conf := {
4423 other := {
4424 len := 2,
4425 payload := '2804'O
4426 }
4427 };
Harald Welte60aa5762018-03-21 19:33:13 +01004428
Philipp Maier7695a0d2018-09-27 17:52:14 +02004429 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
Philipp Maier806f8f12019-03-12 12:13:41 +01004430 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
Philipp Maier7695a0d2018-09-27 17:52:14 +02004431 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4432 pars.expect_mr_conf_ie := mr_conf;
4433
Harald Welte60aa5762018-03-21 19:33:13 +01004434 f_init(1, true);
4435 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004436 f_vty_amr_start_mode_set(false, "1");
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004437 f_ctrs_bsc_and_bts_assignment_init(1);
Harald Welte60aa5762018-03-21 19:33:13 +01004438
Harald Welte8863fa12018-05-10 20:15:27 +02004439 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
Harald Welte60aa5762018-03-21 19:33:13 +01004440 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004441
Neels Hofmeyrbcfc9442021-11-29 16:44:08 +01004442 f_ctrs_bsc_and_bts_add(0, "assignment:attempted", 1);
4443 f_ctrs_bts_add(0, "assignment:attempted_speech", 1);
4444 f_ctrs_bsc_and_bts_add(0, "assignment:completed", 1);
4445 f_ctrs_bts_add(0, "assignment:completed_speech", 1);
4446 f_ctrs_bts_verify();
4447
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004448 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004449 f_shutdown_helper();
Harald Welte60aa5762018-03-21 19:33:13 +01004450}
4451
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004452/* Establish signalling on a TCH/F lchan, and then switch to speech mode without a new Assignment. */
4453testcase TC_assignment_codec_fr_by_mode_modify() runs on test_CT {
4454 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4455 var MSC_ConnHdlr vc_conn;
4456
4457 f_init(1, true);
4458 f_sleep(1.0);
4459
4460 /* By disabling all SDCCH, the MS should be given a TCH/F for signalling. Then activating an FR codec should
4461 * merely do a Channel Mode Modify, and not assign to a new lchan. f_establish_fully() already accounts for
4462 * expecting a Channel Mode Modify if the channel type is compatible. */
4463 f_disable_all_sdcch();
4464 f_disable_all_tch_h();
4465
4466 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4467 pars.expect_channel_mode_modify := true;
4468 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4469 vc_conn.done;
4470
4471 f_enable_all_sdcch();
4472 f_enable_all_tch();
4473 f_shutdown_helper();
4474}
4475
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004476/* 'amr start-mode auto' should not keep the (unused) 'smod' bits from previous configuration */
4477testcase TC_assignment_codec_amr_startmode_cruft() runs on test_CT {
4478 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4479 var MSC_ConnHdlr vc_conn;
4480
4481 var RSL_IE_Body mr_conf := {
4482 other := {
4483 len := 2,
4484 payload := '2004'O /* <- expect ICMI=0, smod=00 */
4485 }
4486 };
4487
4488 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4489 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
4490 pars.ass_codec_list.codecElements[0].s8_15 := '01010111'B;
4491 pars.expect_mr_conf_ie := mr_conf;
4492
4493 f_init(1, true);
4494 f_sleep(1.0);
4495
4496 /* First set nonzero start mode bits */
4497 f_vty_amr_start_mode_set(true, "4");
4498 /* Now set to auto, and expect the startmode bits to be zero in the message, i.e. ensure that osmo-bsc does not
4499 * let the startmode bits stick around and has deterministic MultiRate config for 'start-mode auto'; that is
4500 * ensured by above '2004'O, where 'x0xx'O indicates ICMI = 0, spare = 0, smod = 00. */
4501 f_vty_amr_start_mode_set(true, "auto");
4502
4503 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4504 vc_conn.done;
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004505
4506 /* Clear the startmode bits to not affect subsequent tests, in case the bits should indeed stick around. */
4507 f_vty_amr_start_mode_set(true, "1");
4508 f_vty_amr_start_mode_restore(true);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01004509 f_shutdown_helper();
Neels Hofmeyr454d7922020-11-26 02:24:57 +00004510}
4511
Neels Hofmeyr21863562020-11-26 00:34:33 +00004512function f_TC_assignment_codec_amr(boolean fr, octetstring mrconf, bitstring s8_s0, bitstring exp_s8_s0,
4513 charstring start_mode := "1")
Philipp Maierd0e64b02019-03-13 14:15:23 +01004514runs on test_CT {
4515
4516 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4517 var MSC_ConnHdlr vc_conn;
4518
4519 /* See note above */
4520 var RSL_IE_Body mr_conf := {
4521 other := {
4522 len := lengthof(mrconf),
4523 payload := mrconf
4524 }
4525 };
4526
4527 if (fr) {
4528 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4529 } else {
4530 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4531 }
4532 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4533 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4534 pars.expect_mr_conf_ie := mr_conf;
4535 pars.expect_mr_s0_s7 := exp_s8_s0;
4536
4537 f_init(1, true);
4538 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004539 f_vty_amr_start_mode_set(fr, start_mode);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004540 f_sleep(1.0);
4541
4542 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
4543 vc_conn.done;
4544 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004545 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004546}
4547
4548function f_TC_assignment_codec_amr_fail(boolean fr, bitstring s8_s0)
4549runs on test_CT {
4550
4551 var TestHdlrParams pars := f_gen_test_hdlr_pars();
4552 var MSC_ConnHdlr vc_conn;
4553
4554 if (fr) {
4555 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_F}));
4556 } else {
4557 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
4558 }
4559 pars.ass_codec_list.codecElements[0].s0_7 := s8_s0;
4560 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
4561
4562 f_init(1, true);
4563 f_allow_amr_rate_4_75k_5_90k_7_40k_12_20k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004564 f_vty_amr_start_mode_set(fr, "1");
Philipp Maierd0e64b02019-03-13 14:15:23 +01004565 f_sleep(1.0);
4566
4567 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fail), pars);
4568 vc_conn.done;
4569 f_allow_amr_rate_5_90k();
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00004570 f_vty_amr_start_mode_restore(fr);
Philipp Maierd0e64b02019-03-13 14:15:23 +01004571}
4572
4573
4574/* Set S1, we expect an AMR multirate configuration IE with all four rates
4575 * set. */
4576testcase TC_assignment_codec_amr_f_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004577 f_TC_assignment_codec_amr(true, '289520882208'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004578 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004579}
4580
4581/* Set S1, we expect an AMR multirate configuration IE with the lower three
4582 * rates set. */
4583testcase TC_assignment_codec_amr_h_S1() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004584 f_TC_assignment_codec_amr(false, '2815208820'O, '00000010'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004585 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004586}
4587
4588/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4589 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4590testcase TC_assignment_codec_amr_f_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004591 f_TC_assignment_codec_amr(true, '289520882208'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004592 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004593}
4594
4595/* Set S1 and two other rates, we expect an AMR MULTIRATE CONFIGURATION IE with
4596 * all four rates (and only S1 set in the ASSIGNMENT COMPLETE) */
4597testcase TC_assignment_codec_amr_h_S124() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004598 f_TC_assignment_codec_amr(false, '2815208820'O, '00010110'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004599 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004600}
4601
4602/* The following block of tests selects more and more rates until all four
4603 * possible rates are in the active set (full rate) */
4604testcase TC_assignment_codec_amr_f_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004605 f_TC_assignment_codec_amr(true, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004606 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004607}
4608
4609testcase TC_assignment_codec_amr_f_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004610 f_TC_assignment_codec_amr(true, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004611 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004612}
4613
4614testcase TC_assignment_codec_amr_f_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004615 f_TC_assignment_codec_amr(true, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004616 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004617}
4618
4619testcase TC_assignment_codec_amr_f_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004620 f_TC_assignment_codec_amr(true, '289520882208'O, '10010101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004621 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004622}
4623
4624/* The following block of tests selects more and more rates until all three
4625 * possible rates are in the active set (half rate) */
4626testcase TC_assignment_codec_amr_h_S0() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004627 f_TC_assignment_codec_amr(false, '2801'O, '00000001'B, '00000001'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004628 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004629}
4630
4631testcase TC_assignment_codec_amr_h_S02() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004632 f_TC_assignment_codec_amr(false, '28052080'O, '00000101'B, '00000101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004633 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004634}
4635
4636testcase TC_assignment_codec_amr_h_S024() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004637 f_TC_assignment_codec_amr(false, '2815208820'O, '00010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004638 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004639}
4640
4641/* The following block tests what happens when the MSC does offer rate
4642 * configurations that are not supported by the BSC. Normally such situations
4643 * should not happen because the MSC gets informed by the BSC in advance via
4644 * the L3 COMPLETE message which rates are applicable. The MSC should not try
4645 * to offer rates that are not applicable anyway. */
4646
4647testcase TC_assignment_codec_amr_h_S0247() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004648 /* Try to include 12,2k in into the active set even though the channel
4649 * is half rate only. The BSC is expected to remove the 12,0k */
4650 f_TC_assignment_codec_amr(false, '2815208820'O, '10010101'B, '00010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004651 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004652}
4653
4654testcase TC_assignment_codec_amr_f_S01234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004655 /* See what happens when all rates are selected at once. Since then
4656 * Also S1 is selected, this setting will be prefered and we should
4657 * get 12.2k, 7,40k, 5,90k, and 4,75k in the active set. */
4658 f_TC_assignment_codec_amr(true, '289520882208'O, '11111111'B, '00000010'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004659 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004660}
4661
4662testcase TC_assignment_codec_amr_f_S0234567() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004663 /* Same as above, but with S1 missing, the MSC is then expected to
4664 * select the currently supported rates, which are also 12.2k, 7,40k,
4665 * 5,90k, and 4,75k, into the active set. */
4666 f_TC_assignment_codec_amr(true, '289520882208'O, '11111101'B, '10010101'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004667 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004668}
4669
4670testcase TC_assignment_codec_amr_f_zero() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004671 /* Try to select no rates at all */
4672 f_TC_assignment_codec_amr_fail(true, '00000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004673 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004674}
4675
4676testcase TC_assignment_codec_amr_f_unsupp() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004677 /* Try to select only unsupported rates */
4678 f_TC_assignment_codec_amr_fail(true, '01101000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004679 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004680}
4681
4682testcase TC_assignment_codec_amr_h_S7() runs on test_CT {
Pau Espin Pedrol00f40e82020-09-23 14:16:04 +02004683 /* Try to select 12,2k for half rate */
4684 f_TC_assignment_codec_amr_fail(false, '10000000'B);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004685 f_shutdown_helper();
Philipp Maierd0e64b02019-03-13 14:15:23 +01004686}
4687
Neels Hofmeyr21863562020-11-26 00:34:33 +00004688testcase TC_assignment_codec_amr_f_start_mode_auto() runs on test_CT {
4689 f_TC_assignment_codec_amr(true, '209520882208'O, '11111111'B, '00000010'B,
4690 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004691 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004692}
4693
4694testcase TC_assignment_codec_amr_h_start_mode_auto() runs on test_CT {
4695 f_TC_assignment_codec_amr(false, '2015208820'O, '10010101'B, '00010101'B,
4696 start_mode := "auto");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004697 f_shutdown_helper();
Neels Hofmeyr21863562020-11-26 00:34:33 +00004698}
4699
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004700testcase TC_assignment_codec_amr_f_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004701 /* "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 +00004702 f_TC_assignment_codec_amr(true, '2b9520882208'O, '11111111'B, '00000010'B,
4703 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004704 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004705}
4706
4707testcase TC_assignment_codec_amr_h_start_mode_4() runs on test_CT {
Vadim Yanitskiy7815f482021-01-03 17:07:37 +01004708 /* "amr tch-h modes 0 2 4" => total 3 modes and start mode 4 => '10'B on the wire */
4709 f_TC_assignment_codec_amr(false, '2a15208820'O, '10010101'B, '00010101'B,
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004710 start_mode := "4");
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01004711 f_shutdown_helper();
Neels Hofmeyr3eb94562020-11-26 02:40:26 +00004712}
4713
Philipp Maierac09bfc2019-01-08 13:41:39 +01004714private function f_disable_all_tch_f() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004715 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 borken");
4716 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 borken");
4717 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 borken");
4718 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004719}
4720
4721private function f_disable_all_tch_h() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004722 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 borken");
4723 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 borken");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004724}
4725
4726private function f_enable_all_tch() runs on test_CT {
Philipp Maierc704a882019-01-29 15:58:52 +01004727 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 unused");
4728 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 2 sub-slot 0 unused");
4729 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 3 sub-slot 0 unused");
4730 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 4 sub-slot 0 unused");
4731 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 0 unused");
4732 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 5 sub-slot 1 unused");
Philipp Maierac09bfc2019-01-08 13:41:39 +01004733}
4734
Neels Hofmeyr559d5d02021-04-16 16:50:49 +02004735private function f_disable_all_sdcch() runs on test_CT {
4736 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 borken");
4737 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 borken");
4738 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 borken");
4739 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 borken");
4740}
4741
4742private function f_enable_all_sdcch() runs on test_CT {
4743 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 0 unused");
4744 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 1 unused");
4745 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 2 unused");
4746 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 0 sub-slot 3 unused");
4747}
4748
Philipp Maierac09bfc2019-01-08 13:41:39 +01004749/* Allow HR only */
4750private function f_TC_assignment_codec_xr_exhausted_req_hr(charstring id) runs on MSC_ConnHdlr {
4751 g_pars := f_gen_test_hdlr_pars();
4752 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4753 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4754 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4755 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4756 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4757 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4758 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004759 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004760}
4761
4762/* Allow FR only */
4763private function f_TC_assignment_codec_xr_exhausted_req_fr(charstring id) runs on MSC_ConnHdlr {
4764 g_pars := f_gen_test_hdlr_pars();
4765 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4766 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4767 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4768 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4769 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4770 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4771 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004772 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004773}
4774
4775/* Allow HR only (expect assignment failure) */
4776private function f_TC_assignment_codec_xr_exhausted_req_hr_fail(charstring id) runs on MSC_ConnHdlr {
4777 g_pars := f_gen_test_hdlr_pars();
4778 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4779 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4780 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4781 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '09'O;
4782 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '05'O;
4783 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR}));
4784 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004785 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004786}
4787
4788/* Allow FR only (expect assignment failure) */
4789private function f_TC_assignment_codec_xr_exhausted_req_fr_fail(charstring id) runs on MSC_ConnHdlr {
4790 g_pars := f_gen_test_hdlr_pars();
4791 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4792 var template PDU_BSSAP exp_fail := tr_BSSMAP_AssignmentFail;
4793 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4794 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '08'O;
4795 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '01'O;
4796 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
4797 f_establish_fully(ass_cmd, exp_fail);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004798 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004799}
4800
4801/* Allow FR and HR, but prefer FR */
4802private function f_TC_assignment_codec_fr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4803 g_pars := f_gen_test_hdlr_pars();
4804 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4805 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4806 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4807 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4808 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4809 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4810 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4811 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004812 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004813}
4814
4815/* Allow FR and HR, but prefer HR */
4816private function f_TC_assignment_codec_fr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4817 g_pars := f_gen_test_hdlr_pars();
4818 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4819 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4820 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4821 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4822 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4823 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4824 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4825 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004826 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004827}
4828
4829/* Allow FR and HR, but prefer FR */
4830private function f_TC_assignment_codec_hr_exhausted_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4831 g_pars := f_gen_test_hdlr_pars();
4832 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4833 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4834 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4835 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4836 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4837 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4838 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4839 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004840 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004841}
4842
4843/* Allow FR and HR, but prefer HR */
4844private function f_TC_assignment_codec_hr_exhausted_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4845 g_pars := f_gen_test_hdlr_pars();
4846 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4847 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4848 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4849 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4850 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4851 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4852 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4853 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004854 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004855}
4856
4857/* Request a HR channel while all FR channels are exhausted, this is expected
4858 * to work without conflicts */
4859testcase TC_assignment_codec_fr_exhausted_req_hr() runs on test_CT {
4860 var MSC_ConnHdlr vc_conn;
4861 f_init(1, true);
4862 f_sleep(1.0);
4863 f_enable_all_tch();
4864 f_disable_all_tch_f();
4865 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr));
4866 vc_conn.done;
4867 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004868 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004869}
4870
4871/* Request a FR channel while all FR channels are exhausted, this is expected
4872 * to fail. */
4873testcase TC_assignment_codec_fr_exhausted_req_fr() runs on test_CT {
4874 var MSC_ConnHdlr vc_conn;
4875 f_init(1, true);
4876 f_sleep(1.0);
4877 f_enable_all_tch();
4878 f_disable_all_tch_f();
4879 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr_fail));
4880 vc_conn.done;
4881 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004882 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004883}
4884
4885/* Request a FR (prefered) or alternatively a HR channel while all FR channels
4886 * are exhausted, this is expected to be resolved by selecting a HR channel. */
4887testcase TC_assignment_codec_fr_exhausted_req_fr_hr() runs on test_CT {
4888 var MSC_ConnHdlr vc_conn;
4889 f_init(1, true);
4890 f_sleep(1.0);
4891 f_enable_all_tch();
4892 f_disable_all_tch_f();
4893 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_fr_hr));
4894 vc_conn.done;
4895 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004896 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004897}
4898
4899/* Request a HR (prefered) or alternatively a FR channel while all FR channels
4900 * are exhausted, this is expected to work without conflicts. */
4901testcase TC_assignment_codec_fr_exhausted_req_hr_fr() runs on test_CT {
4902 var MSC_ConnHdlr vc_conn;
4903 f_init(1, true);
4904 f_sleep(1.0);
4905 f_enable_all_tch();
4906 f_disable_all_tch_f();
4907 vc_conn := f_start_handler(refers(f_TC_assignment_codec_fr_exhausted_req_hr_fr));
4908 vc_conn.done;
4909 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004910 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004911}
4912
4913/* Request a FR channel while all HR channels are exhausted, this is expected
4914 * to work without conflicts */
4915testcase TC_assignment_codec_hr_exhausted_req_fr() runs on test_CT {
4916 var MSC_ConnHdlr vc_conn;
4917 f_init(1, true);
4918 f_sleep(1.0);
4919 f_enable_all_tch();
4920 f_disable_all_tch_h();
4921 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_fr));
4922 vc_conn.done;
4923 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004924 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004925}
4926
4927/* Request a HR channel while all HR channels are exhausted, this is expected
4928 * to fail. */
4929testcase TC_assignment_codec_hr_exhausted_req_hr() runs on test_CT {
4930 var MSC_ConnHdlr vc_conn;
4931 f_init(1, true);
4932 f_sleep(1.0);
4933 f_enable_all_tch();
4934 f_disable_all_tch_h();
4935 vc_conn := f_start_handler(refers(f_TC_assignment_codec_xr_exhausted_req_hr_fail));
4936 vc_conn.done;
4937 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004938 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004939}
4940
4941/* Request a HR (prefered) or alternatively a FR channel while all HR channels
4942 * are exhausted, this is expected to be resolved by selecting a FR channel. */
4943testcase TC_assignment_codec_hr_exhausted_req_hr_fr() runs on test_CT {
4944 var MSC_ConnHdlr vc_conn;
4945 f_init(1, true);
4946 f_sleep(1.0);
4947 f_enable_all_tch();
4948 f_disable_all_tch_h();
4949 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_hr_fr));
4950 vc_conn.done;
4951 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004952 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004953}
4954
4955/* Request a FR (prefered) or alternatively a HR channel while all HR channels
4956 * are exhausted, this is expected to work without conflicts. */
4957testcase TC_assignment_codec_hr_exhausted_req_fr_hr() runs on test_CT {
4958 var MSC_ConnHdlr vc_conn;
4959 f_init(1, true);
4960 f_sleep(1.0);
4961 f_enable_all_tch();
4962 f_disable_all_tch_h();
4963 vc_conn := f_start_handler(refers(f_TC_assignment_codec_hr_exhausted_req_fr_hr));
4964 vc_conn.done;
4965 f_enable_all_tch();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02004966 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004967}
4968
4969/* Allow FR and HR, but prefer HR */
4970private function f_TC_assignment_codec_req_hr_fr(charstring id) runs on MSC_ConnHdlr {
4971 g_pars := f_gen_test_hdlr_pars();
4972 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4973 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4974 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4975 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0B'O; /* Prefer HR */
4976 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8501'O;
4977 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecHR, ts_CodecFR}));
4978 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000101'B; /* Expect HR */
4979 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004980 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004981}
4982
4983/* Allow FR and HR, but prefer FR */
4984private function f_TC_assignment_codec_req_fr_hr(charstring id) runs on MSC_ConnHdlr {
4985 g_pars := f_gen_test_hdlr_pars();
4986 var PDU_BSSAP ass_cmd := f_gen_ass_req();
4987 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
4988 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
4989 ass_cmd.pdu.bssmap.assignmentRequest.channelType.channelRateAndType := '0A'O; /* Prefer FR */
4990 ass_cmd.pdu.bssmap.assignmentRequest.channelType.speechId_DataIndicator := '8105'O;
4991 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR, ts_CodecHR}));
4992 exp_compl.pdu.bssmap.assignmentComplete.speechVersion.speechVersionIdentifier := '0000001'B; /* Expect FR */
4993 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01004994 f_perform_clear();
Philipp Maierac09bfc2019-01-08 13:41:39 +01004995}
4996
4997/* Request a HR (prefered) or alternatively a FR channel, it is expected that
4998 * HR, which is the prefered type, is selected. */
4999testcase TC_assignment_codec_req_hr_fr() runs on test_CT {
5000 var MSC_ConnHdlr vc_conn;
5001 f_init(1, true);
5002 f_sleep(1.0);
5003 f_enable_all_tch();
5004 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_hr_fr));
5005 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005006 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005007}
5008
5009/* Request a FR (prefered) or alternatively a HR channel, it is expected that
5010 * FR, which is the prefered type, is selected. */
5011testcase TC_assignment_codec_req_fr_hr() runs on test_CT {
5012 var MSC_ConnHdlr vc_conn;
5013 f_init(1, true);
5014 f_sleep(1.0);
5015 f_enable_all_tch();
5016 vc_conn := f_start_handler(refers(f_TC_assignment_codec_req_fr_hr));
5017 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005018 f_shutdown_helper();
Philipp Maierac09bfc2019-01-08 13:41:39 +01005019}
5020
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005021/* request a signalling channel with all SDCCH exhausted, it is expected that a TCH will be selected */
5022private function f_TC_assignment_sdcch_exhausted_req_signalling(charstring id) runs on MSC_ConnHdlr {
5023 g_pars := f_gen_test_hdlr_pars();
5024 g_pars.ra := '02'O; /* RA containing reason=LU */
5025
5026 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5027 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5028 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5029 var template uint3_t tsc := ?;
5030
5031 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5032 f_create_bssmap_exp(l3_enc);
5033 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5034 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5035
5036 /* we should now have a COMPL_L3 at the MSC */
5037 timer T := 10.0;
5038 T.start;
5039 alt {
5040 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5041 [] T.timeout {
5042 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5043 }
5044 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005045
5046 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005047}
5048testcase TC_assignment_sdcch_exhausted_req_signalling() runs on test_CT {
5049 var MSC_ConnHdlr vc_conn;
5050 f_init(1, true);
5051 f_sleep(1.0);
5052 f_disable_all_sdcch();
5053 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_signalling));
5054 vc_conn.done;
5055 f_enable_all_sdcch();
5056 f_shutdown_helper();
5057}
5058
5059/* Request a signalling channel with all SDCCH exhausted, it is
5060 expected that no TCH will be selected for signalling and assigment will fail
5061 because it's dictated by VTY config */
5062testcase TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() runs on test_CT {
5063 var RSL_Message rsl_unused, rsl_msg;
5064 var GsmRrMessage rr;
5065 f_init(1, false);
5066 f_sleep(1.0);
5067 f_vty_allow_tch_for_signalling(false, 0);
5068 f_disable_all_sdcch();
5069
5070 /* RA containing reason=LU */
5071 f_ipa_tx(0, ts_RSL_CHAN_RQD('02'O, 2342));
5072 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
5073 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
5074 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
5075 setverdict(fail, "Expected reject");
5076 }
5077
5078 f_vty_allow_tch_for_signalling(true, 0);
5079 f_enable_all_sdcch();
5080 f_shutdown_helper();
5081}
5082
5083/* Request a voice channel with all SDCCH exhausted, it is
5084 * expected that TCH channel will be allocated since the VTY option is only
5085 * aimed at signalling requests */
5086private function f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden(charstring id) runs on MSC_ConnHdlr {
5087 g_pars := f_gen_test_hdlr_pars();
5088 g_pars.ra := '43'O; /* RA containing reason=originating speech call*/
5089
5090 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
5091 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
5092 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
5093 var template uint3_t tsc := ?;
5094
5095 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
5096 f_create_bssmap_exp(l3_enc);
5097 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
5098 RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn, tsc);
5099
5100 /* we should now have a COMPL_L3 at the MSC */
5101 timer T := 10.0;
5102 T.start;
5103 alt {
5104 [] BSSAP.receive(tr_BSSMAP_ComplL3);
5105 [] T.timeout {
5106 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
5107 }
5108 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005109 f_perform_clear();
Pau Espin Pedrol14475352021-07-22 15:48:16 +02005110}
5111testcase TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() runs on test_CT {
5112 var MSC_ConnHdlr vc_conn;
5113 f_init(1, true);
5114 f_sleep(1.0);
5115 f_vty_allow_tch_for_signalling(false, 0);
5116 f_disable_all_sdcch();
5117
5118 vc_conn := f_start_handler(refers(f_TC_assignment_sdcch_exhausted_req_voice_tch_forbidden));
5119 vc_conn.done;
5120
5121 f_vty_allow_tch_for_signalling(true, 0);
5122 f_enable_all_sdcch();
5123 f_shutdown_helper();
5124}
5125
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005126testcase TC_assignment_osmux() runs on test_CT {
5127 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5128 var MSC_ConnHdlr vc_conn;
5129
5130 /* See note above */
5131 var RSL_IE_Body mr_conf := {
5132 other := {
5133 len := 2,
5134 payload := '2804'O
5135 }
5136 };
5137
5138 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecAMR_H}));
5139 pars.ass_codec_list.codecElements[0].s0_7 := '00000100'B; /* 5,90k */
5140 pars.ass_codec_list.codecElements[0].s8_15 := '00000111'B;
5141 pars.expect_mr_conf_ie := mr_conf;
5142 pars.use_osmux := true;
5143
5144 f_init(1, true, true);
5145 f_sleep(1.0);
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005146 f_vty_amr_start_mode_set(false, "1");
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005147
5148 vc_conn := f_start_handler(refers(f_TC_assignment_codec), pars);
5149 vc_conn.done;
Neels Hofmeyra6ab8212020-11-25 23:57:47 +00005150
5151 f_vty_amr_start_mode_restore(false);
Vadim Yanitskiy292e5962021-01-03 14:18:47 +01005152 f_shutdown_helper();
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +02005153}
5154
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005155/* test the procedure of the MSC requesting a Classmark Update:
5156 * a) BSSMAP Classmark Request should result in RR CLASSMARK ENQUIRY,
5157 * b) L3 RR CLASSMARK CHANGE should result in BSSMAP CLASSMARK UPDATE */
Harald Welte898113b2018-01-31 18:32:21 +01005158private function f_tc_classmark(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005159 g_pars := f_gen_test_hdlr_pars();
5160
Harald Weltea0630032018-03-20 21:09:55 +01005161 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005162 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005163
Neels Hofmeyr92b12b72018-09-18 14:30:23 +02005164 BSSAP.send(ts_BSSMAP_ClassmarkRequest);
5165 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_CM_ENQUIRY));
5166
Harald Welte898113b2018-01-31 18:32:21 +01005167 f_rsl_send_l3(ts_RRM_CM_CHG(valueof(ts_CM2)));
5168 BSSAP.receive(tr_BSSMAP_ClassmarkUpd(?, omit));
5169 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005170
5171 f_perform_clear();
Harald Welte898113b2018-01-31 18:32:21 +01005172}
5173testcase TC_classmark() runs on test_CT {
5174 var MSC_ConnHdlr vc_conn;
5175 f_init(1, true);
5176 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005177 vc_conn := f_start_handler(refers(f_tc_classmark));
Harald Welte898113b2018-01-31 18:32:21 +01005178 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005179 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005180}
5181
Harald Welteeddf0e92020-06-21 19:42:15 +02005182/* Send a CommonID from the simulated MSC and verify that the information is used to
5183 * fill BSC-internal data structures (specifically, bsc_subscr associated with subscr_conn) */
5184private function f_tc_common_id(charstring id) runs on MSC_ConnHdlr {
5185 g_pars := f_gen_test_hdlr_pars();
5186 f_MscConnHdlr_init_vty();
5187
5188 f_create_chan_and_exp();
5189 /* we should now have a COMPL_L3 at the MSC */
Harald Welteeddf0e92020-06-21 19:42:15 +02005190
5191 /* Send CommonID */
5192 BSSAP.send(ts_BSSMAP_CommonId(g_pars.imsi));
5193
5194 /* Use VTY to verify that the IMSI of the subscr_conn is set */
5195 var charstring regex := "*(IMSI: " & hex2str(g_pars.imsi) & ")*";
5196 f_vty_transceive_match_regexp_retry(BSCVTY, "show conns", regex, 0, 4, 1.0);
5197
5198 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005199
5200 f_perform_clear();
Harald Welteeddf0e92020-06-21 19:42:15 +02005201}
5202testcase TC_common_id() runs on test_CT {
5203 var MSC_ConnHdlr vc_conn;
5204 f_init(1, true);
5205 f_sleep(1.0);
5206 vc_conn := f_start_handler(refers(f_tc_common_id));
5207 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005208 f_shutdown_helper();
Harald Welteeddf0e92020-06-21 19:42:15 +02005209}
5210
Harald Weltee3bd6582018-01-31 22:51:25 +01005211private function f_est_single_l3(template PDU_ML3_MS_NW l3) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005212 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005213 f_create_chan_and_exp();
Harald Welte898113b2018-01-31 18:32:21 +01005214 /* we should now have a COMPL_L3 at the MSC */
Harald Welte898113b2018-01-31 18:32:21 +01005215
Harald Weltee3bd6582018-01-31 22:51:25 +01005216 /* send the single message we want to send */
5217 f_rsl_send_l3(l3);
5218}
5219
5220private function f_bssap_expect_nothing(float sec := 5.00) runs on MSC_ConnHdlr {
5221 timer T := sec;
5222 var PDU_BSSAP bssap;
Harald Welte898113b2018-01-31 18:32:21 +01005223 T.start;
5224 alt {
Harald Weltee3bd6582018-01-31 22:51:25 +01005225 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
5226 setverdict(fail, "Unexpected BSSMAP ", bssap);
Daniel Willmannafce8662018-07-06 23:11:32 +02005227 mtc.stop;
Harald Welte898113b2018-01-31 18:32:21 +01005228 }
5229 [] T.timeout {
5230 setverdict(pass);
5231 }
5232 }
5233}
5234
Harald Weltee3bd6582018-01-31 22:51:25 +01005235/* unsolicited ASSIGNMENT FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5236private function f_tc_unsol_ass_fail(charstring id) runs on MSC_ConnHdlr {
5237 f_est_single_l3(ts_RRM_AssignmentFailure('00'O));
5238 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005239 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005240}
Harald Welte898113b2018-01-31 18:32:21 +01005241testcase TC_unsol_ass_fail() runs on test_CT {
5242 var MSC_ConnHdlr vc_conn;
5243 f_init(1, true);
5244 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005245 vc_conn := f_start_handler(refers(f_tc_unsol_ass_fail));
Harald Welte898113b2018-01-31 18:32:21 +01005246 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005247 f_shutdown_helper();
Harald Welte898113b2018-01-31 18:32:21 +01005248}
Harald Welte552620d2017-12-16 23:21:36 +01005249
Harald Welteea99a002018-01-31 20:46:43 +01005250
5251/* unsolicited ASSIGNMENT COMPLETE (without ASSIGN) from MS shouldn't bring BSC down */
5252private function f_tc_unsol_ass_compl(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005253 f_est_single_l3(ts_RRM_AssignmentComplete('00'O));
5254 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005255 f_perform_clear();
Harald Welteea99a002018-01-31 20:46:43 +01005256}
5257testcase TC_unsol_ass_compl() runs on test_CT {
5258 var MSC_ConnHdlr vc_conn;
5259 f_init(1, true);
5260 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005261 vc_conn := f_start_handler(refers(f_tc_unsol_ass_compl));
Harald Welteea99a002018-01-31 20:46:43 +01005262 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005263 f_shutdown_helper();
Harald Welteea99a002018-01-31 20:46:43 +01005264}
5265
5266
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005267/* unsolicited HANDOVER FAIL (without ASSIGN) from MS shouldn't bring BSC down */
5268private function f_tc_unsol_ho_fail(charstring id) runs on MSC_ConnHdlr {
Harald Weltee3bd6582018-01-31 22:51:25 +01005269 f_est_single_l3(ts_RRM_HandoverFailure('00'O));
5270 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005271 f_perform_clear();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005272}
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005273testcase TC_unsol_ho_fail() runs on test_CT {
5274 var MSC_ConnHdlr vc_conn;
5275 f_init(1, true);
5276 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005277 vc_conn := f_start_handler(refers(f_tc_unsol_ho_fail));
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005278 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005279 f_shutdown_helper();
Harald Weltefbf9b5e2018-01-31 20:41:23 +01005280}
5281
5282
Harald Weltee3bd6582018-01-31 22:51:25 +01005283/* short message from MS should be ignored */
5284private function f_tc_err_82_short_msg(charstring id) runs on MSC_ConnHdlr {
Philipp Maier48604732018-10-09 15:00:37 +02005285 g_pars := f_gen_test_hdlr_pars();
Harald Weltea0630032018-03-20 21:09:55 +01005286 f_create_chan_and_exp();
Harald Weltee3bd6582018-01-31 22:51:25 +01005287 /* we should now have a COMPL_L3 at the MSC */
Harald Weltee3bd6582018-01-31 22:51:25 +01005288
5289 /* send short message */
5290 RSL.send(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), ''O));
5291 f_bssap_expect_nothing();
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005292 f_perform_clear();
Harald Weltee3bd6582018-01-31 22:51:25 +01005293}
5294testcase TC_err_82_short_msg() runs on test_CT {
5295 var MSC_ConnHdlr vc_conn;
5296 f_init(1, true);
5297 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005298 vc_conn := f_start_handler(refers(f_tc_err_82_short_msg));
Harald Weltee3bd6582018-01-31 22:51:25 +01005299 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005300 f_shutdown_helper();
Harald Weltee3bd6582018-01-31 22:51:25 +01005301}
5302
5303
Harald Weltee9e02e42018-01-31 23:36:25 +01005304/* 24.008 8.4 Unknown message must trigger RR STATUS */
5305private function f_tc_err_84_unknown_msg(charstring id) runs on MSC_ConnHdlr {
5306 f_est_single_l3(ts_RRM_UL_REL('00'O));
5307 timer T := 3.0
5308 alt {
5309 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_STATUS)) {
5310 setverdict(pass);
5311 }
5312 [] BSSAP.receive { setverdict(fail, "unexpected BSSAP"); }
Harald Welte458fd372018-03-21 11:26:23 +01005313 [] T.timeout { setverdict(fail, "Timeout waiting for RR STATUS"); }
Harald Weltee9e02e42018-01-31 23:36:25 +01005314 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005315 f_perform_clear();
Harald Weltee9e02e42018-01-31 23:36:25 +01005316}
5317testcase TC_err_84_unknown_msg() runs on test_CT {
5318 var MSC_ConnHdlr vc_conn;
5319 f_init(1, true);
5320 f_sleep(1.0);
Harald Welte8863fa12018-05-10 20:15:27 +02005321 vc_conn := f_start_handler(refers(f_tc_err_84_unknown_msg));
Harald Weltee9e02e42018-01-31 23:36:25 +01005322 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005323 f_shutdown_helper();
Harald Weltee9e02e42018-01-31 23:36:25 +01005324}
5325
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005326/***********************************************************************
5327 * Handover
5328 ***********************************************************************/
5329
Harald Welte94e0c342018-04-07 11:33:23 +02005330/* execute a "bts <0-255> trx <0-255> timeslot <0-7> " command on given Dchan */
5331private function f_vty_ts_action(charstring suffix, integer bts_nr, integer trx_nr, integer ts_nr)
5332runs on test_CT {
5333 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5334 " timeslot "&int2str(ts_nr)&" ";
5335 f_vty_transceive(BSCVTY, cmd & suffix);
5336}
5337
Harald Welte261af4b2018-02-12 21:20:39 +01005338/* 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 +07005339private function f_vty_ss_action(TELNETasp_PT pt, charstring suffix,
5340 uint8_t bts_nr, uint8_t trx_nr,
5341 in RslChannelNr chan_nr)
5342{
Harald Welte261af4b2018-02-12 21:20:39 +01005343 /* FIXME: resolve those from component-global state */
5344 var integer ts_nr := chan_nr.tn;
5345 var integer ss_nr;
5346 if (ischosen(chan_nr.u.ch0)) {
5347 ss_nr := 0;
5348 } else if (ischosen(chan_nr.u.lm)) {
5349 ss_nr := chan_nr.u.lm.sub_chan;
5350 } else if (ischosen(chan_nr.u.sdcch4)) {
5351 ss_nr := chan_nr.u.sdcch4.sub_chan;
5352 } else if (ischosen(chan_nr.u.sdcch8)) {
5353 ss_nr := chan_nr.u.sdcch8.sub_chan;
5354 } else {
5355 setverdict(fail, "Invalid ChanNr ", chan_nr);
Daniel Willmannafce8662018-07-06 23:11:32 +02005356 mtc.stop;
Harald Welte261af4b2018-02-12 21:20:39 +01005357 }
5358
5359 var charstring cmd := "bts "&int2str(bts_nr)&" trx "&int2str(trx_nr)&
5360 " timeslot "&int2str(ts_nr)&" sub-slot "&int2str(ss_nr)&" ";
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005361 f_vty_transceive(pt, cmd & suffix);
Harald Welte261af4b2018-02-12 21:20:39 +01005362}
5363
Neels Hofmeyr91401012019-07-11 00:42:35 +02005364/* Even though the VTY command to trigger handover takes a new BTS number as argument, behind the scenes osmo-bsc always
5365 * translates that to a target ARFCN+BSIC first. See bsc_vty.c trigger_ho_or_as(), which puts the selected BTS' neighbor
5366 * ident key (ARFCN + BSIC) in the struct passed on to handover_request(). handover_start() then resolves that to a
5367 * viable actual neighbor cell. So from the internal osmo-bsc perspective, we always request handover to an ARFCN + BSIC
5368 * pair, not really to a specific BTS number. */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005369private function f_vty_handover(TELNETasp_PT pt, uint8_t bts_nr, uint8_t trx_nr,
5370 in RslChannelNr chan_nr, uint8_t new_bts_nr)
5371{
5372 f_vty_ss_action(pt, "handover " & int2str(new_bts_nr), bts_nr, trx_nr, chan_nr);
Harald Welte261af4b2018-02-12 21:20:39 +01005373}
5374
5375/* intra-BSC hand-over between BTS0 and BTS1 */
5376private function f_tc_ho_int(charstring id) runs on MSC_ConnHdlr {
Harald Welteed848512018-05-24 22:27:58 +02005377 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5378 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Harald Welte261af4b2018-02-12 21:20:39 +01005379
5380 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5381 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5382
Harald Weltea0630032018-03-20 21:09:55 +01005383 f_establish_fully(ass_cmd, exp_compl);
Neels Hofmeyr666f0432020-07-04 00:53:07 +02005384 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Harald Welte261af4b2018-02-12 21:20:39 +01005385
5386 var HandoverState hs := {
5387 rr_ho_cmpl_seen := false,
5388 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005389 old_chan_nr := -,
5390 expect_target_tsc := BTS_TSC[1]
Harald Welte261af4b2018-02-12 21:20:39 +01005391 };
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005392 /* issue hand-over command on VTY, from BTS 0 to BTS 1 */
Vadim Yanitskiy00070722020-09-02 17:27:57 +07005393 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
Harald Welte261af4b2018-02-12 21:20:39 +01005394 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5395 f_rslem_suspend(RSL1_PROC);
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005396
5397 /* From the MGW perspective, a handover is is characterized by
5398 * performing one MDCX operation with the MGW. So we expect to see
5399 * one more MDCX during handover. */
5400 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5401
Harald Welte261af4b2018-02-12 21:20:39 +01005402 alt {
5403 [] as_handover(hs);
Harald Welte261af4b2018-02-12 21:20:39 +01005404 }
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005405
Philipp Maier4dae0652018-11-12 12:03:26 +01005406 /* Since this is an internal handover we expect the BSC to inform the
5407 * MSC about the event */
5408 BSSAP.receive(tr_BSSMAP_HandoverPerformed);
5409
Philipp Maier3e2af5d2018-07-11 17:01:05 +02005410 /* Check the amount of MGCP transactions is still consistant with the
5411 * test expectation */
5412 f_check_mgcp_expectations()
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005413
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005414 var RSL_Message chan_act := f_rslem_get_last_act(RSL1_PROC, 0, g_chan_nr);
5415
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005416 /* Ensure the Channel Activation for the new channel contained the right encryption params. as_handover() set
5417 * 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 +02005418 f_verify_encr_info(chan_act);
5419
5420 f_chan_act_verify_tsc(chan_act, BTS_TSC[1]);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005421
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005422 f_perform_clear(RSL1, RSL1_PROC);
5423
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005424 f_sleep(0.5);
Harald Welte261af4b2018-02-12 21:20:39 +01005425}
5426
5427testcase TC_ho_int() runs on test_CT {
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005428 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Harald Welte261af4b2018-02-12 21:20:39 +01005429 var MSC_ConnHdlr vc_conn;
5430 f_init(2, true);
5431 f_sleep(1.0);
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005432
Neels Hofmeyrc2cf4542021-10-02 12:26:38 +02005433 pars.expect_tsc := BTS_TSC[0];
5434
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005435 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005436
Neels Hofmeyr5f7a9df2021-06-21 01:30:43 +02005437 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
Harald Welte261af4b2018-02-12 21:20:39 +01005438 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005439
5440 /* from f_establish_fully() */
5441 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5442 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5443 /* from handover */
5444 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5445 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5446 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5447 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005448 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5449 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005450 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005451 f_shutdown_helper();
Harald Welte261af4b2018-02-12 21:20:39 +01005452}
Harald Weltee9e02e42018-01-31 23:36:25 +01005453
Oliver Smith7eabd312021-07-12 14:18:56 +02005454function 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 +02005455 var MSC_ConnHdlr vc_conn;
5456 var TestHdlrParams pars := f_gen_test_hdlr_pars();
5457 pars.encr := valueof(t_EncrParams(encr_alg, f_rnd_octstring(8), f_rnd_octstring(16)));
5458
5459 f_init(2, true);
Oliver Smith7eabd312021-07-12 14:18:56 +02005460 f_vty_encryption_a5(enc_a5);
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005461 f_sleep(1.0);
5462
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005463 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005464
5465 vc_conn := f_start_handler(refers(f_tc_ho_int), pars);
5466 vc_conn.done;
5467
5468 /* from f_establish_fully() */
5469 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5470 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5471 /* from handover */
5472 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5473 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5474 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5475 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:completed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005476 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5477 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:completed");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005478 f_ctrs_bsc_and_bts_verify();
Oliver Smith7eabd312021-07-12 14:18:56 +02005479 f_vty_encryption_a5_reset();
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005480 f_shutdown_helper();
5481}
5482
5483testcase TC_ho_int_a5_0() runs on test_CT {
5484 f_tc_ho_int_a5('01'O);
5485}
5486
5487testcase TC_ho_int_a5_1() runs on test_CT {
5488 f_tc_ho_int_a5('02'O);
5489}
5490
5491testcase TC_ho_int_a5_3() runs on test_CT {
5492 f_tc_ho_int_a5('08'O);
5493}
5494
5495testcase TC_ho_int_a5_4() runs on test_CT {
Oliver Smith7eabd312021-07-12 14:18:56 +02005496 f_tc_ho_int_a5('10'O, "0 1 3 4");
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +02005497}
5498
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005499/* intra-BSC hand-over with CONNection FAILure and cause Radio Link Failure: check RR release cause */
5500private function f_tc_ho_int_radio_link_failure(charstring id) runs on MSC_ConnHdlr {
5501 g_pars := f_gen_test_hdlr_pars();
5502 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5503 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005504
5505 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5506 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5507
5508 f_establish_fully(ass_cmd, exp_compl);
5509 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
5510
5511 var HandoverState hs := {
5512 rr_ho_cmpl_seen := false,
5513 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +02005514 old_chan_nr := -,
5515 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005516 };
5517 /* issue hand-over command on VTY */
5518 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
5519 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
5520 f_rslem_suspend(RSL1_PROC);
5521
5522 /* From the MGW perspective, a handover is is characterized by
5523 * performing one MDCX operation with the MGW. So we expect to see
5524 * one more MDCX during handover. */
5525 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
5526
5527 var RSL_Message rsl;
5528 var PDU_ML3_NW_MS l3;
5529 var RslChannelNr new_chan_nr;
5530 var GsmArfcn arfcn;
5531 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
5532 l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
5533 if (not ischosen(l3.msgs.rrm.handoverCommand)) {
5534 setverdict(fail, "Expected handoverCommand");
5535 mtc.stop;
5536 }
5537 }
5538 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
5539 new_chan_nr, arfcn);
5540
5541 f_rslem_register(0, new_chan_nr, RSL1_PROC);
5542
5543 /* resume processing of RSL DChan messages, which was temporarily suspended
5544 * before performing a hand-over */
5545 f_rslem_resume(RSL1_PROC);
5546 RSL1.receive(tr_RSL_IPA_CRCX(new_chan_nr));
5547
5548 f_sleep(1.0);
5549
5550 /* Handover fails because no HANDO DET appears on the new lchan,
5551 * and the old lchan reports a Radio Link Failure. */
5552 RSL.send(ts_RSL_CONN_FAIL_IND(g_chan_nr, RSL_ERR_RADIO_LINK_FAIL));
5553
5554 var PDU_BSSAP rx_clear_request;
5555 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5556 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5557 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5558
5559 var RR_Cause rr_cause := GSM48_RR_CAUSE_ABNORMAL_UNSPEC;
5560
5561 var MgcpCommand mgcp;
5562 interleave {
5563 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE(int2oct(enum2int(rr_cause), 1)))) {}
5564 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005565 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005566 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005567 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005568 }
5569 [] RSL1.receive(tr_RSL_DEACT_SACCH(new_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005570 [] RSL1.receive(tr_RSL_RF_CHAN_REL(new_chan_nr)) {
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005571 RSL1.send(ts_RSL_RF_CHAN_REL_ACK(new_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005572 f_rslem_unregister(0, g_chan_nr, PT := RSL1_PROC);
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005573 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005574 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5575 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5576 }
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005577 }
5578
5579 f_sleep(0.5);
5580 setverdict(pass);
5581}
5582testcase TC_ho_int_radio_link_failure() runs on test_CT {
5583 var MSC_ConnHdlr vc_conn;
5584 f_init(2, true);
5585 f_sleep(1.0);
5586
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005587 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005588
5589 vc_conn := f_start_handler(refers(f_tc_ho_int_radio_link_failure));
5590 vc_conn.done;
5591
5592 /* from f_establish_fully() */
5593 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5594 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5595 /* from handover */
5596 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5597 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
5598 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
5599 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:stopped");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005600 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
5601 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:stopped");
Neels Hofmeyr5f144212020-11-03 15:41:58 +00005602 f_ctrs_bsc_and_bts_verify();
5603 f_shutdown_helper();
5604}
5605
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005606/* Expecting MGCP to DLCX the endpoint's two connections: towards BTS and towards MSC */
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005607private function f_expect_dlcx_conns() runs on MSC_ConnHdlr {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005608 var MgcpCommand mgcp;
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005609 var template MgcpResponse mgcp_resp;
5610 var MGCP_RecvFrom mrf;
5611 var template MgcpMessage msg_resp;
5612 var template MgcpMessage msg_dlcx := {
5613 command := tr_DLCX()
5614 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005615
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005616 if (g_pars.aoip) {
5617 MGCP.receive(tr_DLCX()) -> value mgcp {
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005618 log("Got first DLCX: ", mgcp);
5619 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005620 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005621
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005622 MGCP.receive(tr_DLCX()) -> value mgcp {
5623 log("Got second DLCX: ", mgcp);
5624 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
5625 };
Pau Espin Pedrolfd02ad42019-06-18 17:45:20 +02005626 } else {
5627 /* For SCCPLite, BSC doesn't handle the MSC-side */
5628 MGCP_MULTI.receive(tr_MGCP_RecvFrom_any(msg_dlcx)) -> value mrf {
5629 log("Got first DLCX: ", mrf.msg.command);
5630 msg_resp := {
5631 response := ts_DLCX_ACK2(mrf.msg.command.line.trans_id)
5632 }
5633 MGCP_MULTI.send(t_MGCP_SendToMrf(mrf, msg_resp));
5634 };
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005635 }
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005636}
5637
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005638private 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 +01005639
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005640 var NcellReports neighbor_rep := {
5641 { rxlev := 20, bcch_freq := 0, bsic := 11 }
5642 };
5643 var octetstring l3_mr := enc_GsmRrL3Message(valueof(ts_MEAS_REP(true, 8, 8, reps := neighbor_rep)));
5644 RSL.send(ts_RSL_MEAS_RES(g_chan_nr, 0, ts_RSL_IE_UplinkMeas, ts_RSL_IE_BS_Power(0), ts_RSL_IE_L1Info,
5645 l3_mr, 0));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005646
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005647 BSSAP.receive(tr_BSSMAP_HandoverRequired(exp_oldToNewBSSIEs));
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005648
5649 f_sleep(0.5);
5650 /* The MSC negotiates Handover Request and Handover Request Ack with
5651 * the other BSS and comes back with a BSSMAP Handover Command
5652 * containing an RR Handover Command coming from the target BSS... */
5653
5654 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5655 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5656 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5657 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5658 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5659
5660 /* expect the Handover Command to go out on RR */
5661 var RSL_Message rsl_ho_cmd
5662 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5663 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5664 var RSL_IE_Body rsl_ho_cmd_l3;
5665 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5666 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5667 setverdict(fail);
5668 } else {
5669 log("Found L3 Info: ", rsl_ho_cmd_l3);
5670 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5671 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5672 setverdict(fail);
5673 } else {
5674 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5675 setverdict(pass);
5676 }
5677 }
5678
5679 /* When the other BSS has reported a completed handover, this side is
5680 * torn down. */
5681
5682 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_HANDOVER_SUCCESSFUL;
5683 var BssmapCause cause := enum2int(cause_val);
5684 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5685
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005686 f_expect_dlcx_conns();
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005687
5688 interleave {
5689 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE));
5690 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr));
5691 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005692 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
5693 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
5694 }
Pau Espin Pedrol06199952021-06-15 11:30:00 +02005695 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005696 setverdict(pass);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02005697}
5698
5699private function f_tc_ho_out_of_this_bsc(charstring id) runs on MSC_ConnHdlr {
5700 g_pars := f_gen_test_hdlr_pars();
5701 var PDU_BSSAP ass_req := f_gen_ass_req();
5702 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5703 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5704 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5705 f_establish_fully(ass_req, exp_compl);
5706
5707 f_ho_out_of_this_bsc();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005708}
5709testcase TC_ho_out_of_this_bsc() runs on test_CT {
5710 var MSC_ConnHdlr vc_conn;
5711
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005712 f_init_vty();
5713 f_bts_0_cfg(BSCVTY,
5714 {"neighbor-list mode automatic",
5715 "handover 1",
5716 "handover algorithm 2",
5717 "handover2 window rxlev averaging 1",
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005718 "no neighbors",
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +01005719 "neighbor lac 99 arfcn 123 bsic any"});
5720 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
5721
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005722 f_init(1, true);
5723 f_sleep(1.0);
5724
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005725 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005726
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005727 vc_conn := f_start_handler(refers(f_tc_ho_out_of_this_bsc));
5728 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005729
5730 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5731 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5732 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5733 f_ctrs_bsc_and_bts_add(0, "handover:completed");
5734 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5735 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed");
5736 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005737 f_shutdown_helper();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01005738}
5739
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005740private function f_mo_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5741 template (value) RslLinkId link_id := ts_RslLinkID_DCCH(0),
Vadim Yanitskiy2ef6a2f2020-10-08 23:17:32 +07005742 template (present) OCT1 dlci := ?,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005743 octetstring l3 := '0123456789'O)
5744runs on MSC_ConnHdlr {
Neels Hofmeyr43654812020-09-25 01:35:35 +02005745 /* The old lchan and conn should still be active. See that arbitrary L3
5746 * is still going through. */
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005747 rsl.send(ts_RSL_DATA_IND(g_chan_nr, link_id, l3));
Neels Hofmeyr43654812020-09-25 01:35:35 +02005748 var template PDU_BSSAP exp_data := {
5749 discriminator := '1'B,
5750 spare := '0000000'B,
Vadim Yanitskiyb93aa432020-10-01 14:23:11 +07005751 dlci := dlci,
5752 lengthIndicator := lengthof(l3),
Neels Hofmeyr43654812020-09-25 01:35:35 +02005753 pdu := {
5754 dtap := l3
5755 }
5756 };
5757 BSSAP.receive(exp_data);
5758 setverdict(pass);
5759}
5760
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005761private function f_mt_l3_transceive(RSL_DCHAN_PT rsl := RSL,
5762 template (present) RslLinkId link_id := tr_RslLinkID_DCCH(0),
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005763 template (value) OCT1 dlci := '00'O,
5764 octetstring l3 := '0123456789'O)
5765runs on MSC_ConnHdlr {
5766 BSSAP.send(PDU_BSSAP:{
5767 discriminator := '1'B,
5768 spare := '0000000'B,
5769 dlci := dlci,
5770 lengthIndicator := lengthof(l3),
5771 pdu := {
5772 dtap := l3
5773 }
5774 });
Neels Hofmeyr0aa719b2020-10-12 18:43:09 +00005775 rsl.receive(tr_RSL_DATA_REQ(g_chan_nr, link_id, l3));
Vadim Yanitskiy0033a3b2020-10-01 22:21:16 +07005776 setverdict(pass);
5777}
5778
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005779/* BSC asks for inter-BSC HO, but the MSC decides that it won't happen and
5780 * simply never sends a BSSMAP Handover Command. */
5781private function f_tc_ho_out_fail_no_msc_response(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005782 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005783
5784 var PDU_BSSAP ass_req := f_gen_ass_req();
5785 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5786 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5787 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5788 f_establish_fully(ass_req, exp_compl);
5789
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005790 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005791 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5792
5793 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5794
5795 /* osmo-bsc should time out 10 seconds after the handover started.
5796 * Let's give it a bit extra. */
5797 f_sleep(15.0);
5798
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005799 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005800 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005801 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005802}
5803testcase TC_ho_out_fail_no_msc_response() runs on test_CT {
5804 var MSC_ConnHdlr vc_conn;
5805
5806 f_init(1, true);
5807 f_sleep(1.0);
5808
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005809 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005810
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005811 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_msc_response));
5812 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005813
5814 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5815 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5816 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5817 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
5818 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5819 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
5820 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005821 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005822}
5823
5824/* BSC asks for inter-BSC HO, receives BSSMAP Handover Command, but MS reports
5825 * RR Handover Failure. */
5826private function f_tc_ho_out_fail_rr_ho_failure(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005827 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005828
5829 var PDU_BSSAP ass_req := f_gen_ass_req();
5830 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5831 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5832 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5833 f_establish_fully(ass_req, exp_compl);
5834
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005835 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005836 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5837
5838 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5839
5840 f_sleep(0.5);
5841 /* The MSC negotiates Handover Request and Handover Request Ack with
5842 * the other BSS and comes back with a BSSMAP Handover Command
5843 * containing an RR Handover Command coming from the target BSS... */
5844
5845 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5846 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5847 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5848 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5849 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5850
5851 /* expect the Handover Command to go out on RR */
5852 var RSL_Message rsl_ho_cmd
5853 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5854 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5855 var RSL_IE_Body rsl_ho_cmd_l3;
5856 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5857 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5858 setverdict(fail);
5859 } else {
5860 log("Found L3 Info: ", rsl_ho_cmd_l3);
5861 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5862 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5863 setverdict(fail);
5864 } else {
5865 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5866 setverdict(pass);
5867 }
5868 }
5869
5870 f_sleep(0.2);
5871 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
5872
5873 /* Should tell the MSC about the failure */
5874 BSSAP.receive(tr_BSSMAP_HandoverFailure);
5875
5876 f_sleep(1.0);
5877
Vadim Yanitskiy74ae5eb2020-10-01 22:13:29 +07005878 f_mo_l3_transceive();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005879 f_sleep(1.0);
5880
5881 setverdict(pass);
5882 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005883 f_perform_clear();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005884}
5885testcase TC_ho_out_fail_rr_ho_failure() runs on test_CT {
5886 var MSC_ConnHdlr vc_conn;
5887
5888 f_init(1, true);
5889 f_sleep(1.0);
5890
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005891 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005892
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005893 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_rr_ho_failure));
5894 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005895
5896 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5897 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5898 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
5899 f_ctrs_bsc_and_bts_add(0, "handover:failed");
5900 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
5901 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:failed");
5902 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02005903 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005904}
5905
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005906/* BSC asks for inter-BSC-out HO, receives BSSMAP Handover Command, but then no reply is received about HO outcome
5907 * (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 +02005908 * and the lchan is released. */
5909private function f_tc_ho_out_fail_no_result_after_ho_cmd(charstring id) runs on MSC_ConnHdlr {
Daniel Willmann3b59eb52018-10-29 15:40:55 +01005910 g_pars := f_gen_test_hdlr_pars();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005911
5912 var PDU_BSSAP ass_req := f_gen_ass_req();
5913 ass_req.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
5914 ass_req.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
5915 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
5916 f_establish_fully(ass_req, exp_compl);
5917
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01005918 f_bts_0_cfg(BSCVTY, {"no neighbor lac 99", "neighbor lac 99 arfcn 123 bsic any"});
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005919 f_vty_transceive(BSCVTY, "handover any to arfcn 123 bsic any");
5920
5921 BSSAP.receive(tr_BSSMAP_HandoverRequired);
5922
5923 f_sleep(0.5);
5924 /* The MSC negotiates Handover Request and Handover Request Ack with
5925 * the other BSS and comes back with a BSSMAP Handover Command
5926 * containing an RR Handover Command coming from the target BSS... */
5927
5928 var PDU_ML3_NW_MS rr_ho_cmd := valueof(ts_RR_HandoverCommand);
5929 log("Remote cell's RR Handover Command passed through as L3 Info: ", rr_ho_cmd);
5930 var octetstring rr_ho_cmd_enc := enc_PDU_ML3_NW_MS(rr_ho_cmd);
5931 log("Remote cell's RR Handover Command passed through as L3 Info, encoded: ", rr_ho_cmd_enc);
5932 BSSAP.send(ts_BSSMAP_HandoverCommand(rr_ho_cmd_enc));
5933
5934 /* expect the Handover Command to go out on RR */
5935 var RSL_Message rsl_ho_cmd
5936 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, ?)) -> value rsl_ho_cmd;
5937 log("RSL Data Req went out to first BTS: ", rsl_ho_cmd);
5938 var RSL_IE_Body rsl_ho_cmd_l3;
5939 if (not f_rsl_find_ie(rsl_ho_cmd, RSL_IE_L3_INFO, rsl_ho_cmd_l3)) {
5940 log("RSL message contains no L3 Info IE, expected RR Handover Command");
5941 setverdict(fail);
5942 } else {
5943 log("Found L3 Info: ", rsl_ho_cmd_l3);
5944 if (rsl_ho_cmd_l3.l3_info.payload != rr_ho_cmd_enc) {
5945 log("FAIL: the BSC sent out a different L3 Info, not matching the RR Handover Command the other BSS forwarded.");
5946 setverdict(fail);
5947 } else {
5948 log("Success: the BSC sent out the same RR Handover Command the other BSS forwarded.");
5949 setverdict(pass);
5950 }
5951 }
5952
Neels Hofmeyr10f2bfa2019-07-09 19:33:29 +02005953 /* We get neither success nor failure report from the remote BSS. Eventually T8 times out and we run into 3GPP
5954 * TS 48.008 3.1.5.3.3 "Abnormal Conditions": Clear Request should go to the MSC, and RR should be released
5955 * after Clear Command */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005956
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005957 var PDU_BSSAP rx_clear_request;
Neels Hofmeyre1797aa2019-07-09 19:34:04 +02005958 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request;
5959 log("Got BSSMAP Clear Request");
5960 /* Instruct BSC to clear channel */
5961 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
5962 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
5963
5964 var MgcpCommand mgcp;
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005965 interleave {
Neels Hofmeyr861a4c12018-11-07 01:23:17 +01005966 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
5967 log("Got Deact SACCH");
5968 }
Harald Welte924b6ea2019-02-04 01:05:34 +01005969 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
Neels Hofmeyr211169d2018-11-07 00:37:29 +01005970 log("Got RR Release");
5971 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02005972 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005973 log("Got RF Chan Rel");
5974 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +02005975 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005976 }
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005977 }
5978
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02005979 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02005980 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01005981 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02005982
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005983 setverdict(pass);
5984 f_sleep(1.0);
5985}
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005986testcase TC_ho_out_fail_no_result_after_ho_cmd() runs on test_CT {
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005987 var MSC_ConnHdlr vc_conn;
5988
5989 f_init(1, true);
5990 f_sleep(1.0);
5991
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01005992 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005993
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +02005994 vc_conn := f_start_handler(refers(f_tc_ho_out_fail_no_result_after_ho_cmd));
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02005995 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00005996
5997 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
5998 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
5999 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6000 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
6001 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
6002 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
6003 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006004 f_shutdown_helper();
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +02006005}
6006
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006007private 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 +01006008 var PDU_BSSAP rx_bssap;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006009 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6010 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6011 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6012 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6013 * before we get started. */
6014 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6015 f_rslem_register(0, new_chan_nr);
6016 g_chan_nr := new_chan_nr;
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006017 var uint3_t expect_target_tsc := BTS_TSC[0];
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006018 f_sleep(1.0);
6019
6020 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6021 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6022 activate(as_Media());
6023
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006024 var PDU_BSSAP ho_req := f_gen_handover_req(aoip_tla := g_pars.host_aoip_tla,
6025 cell_id_source := g_pars.cell_id_source,
6026 oldToNewBSSIEs := oldToNewBSSIEs,
6027 enc := g_pars.encr);
6028 if (g_pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr) {
6029 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, ho_req));
6030 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6031 } else {
6032 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc, omit));
6033 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
6034 BSSAP.send(ho_req);
6035 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006036
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006037 alt {
6038 [] BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap {
6039 if (g_pars.expect_ho_fail) {
6040 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6041 "Expected Handover Request to fail, but got Handover Request Ack")
6042 }
6043 }
6044 [] BSSAP.receive(tr_BSSMAP_HandoverFailure) -> value rx_bssap {
6045 if (not g_pars.expect_ho_fail) {
6046 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6047 "Expected Handover Request to succeed, but got Handover Failure")
6048 }
6049 // TODO: evaluate correct cause value. But osmo-bsc doesn't seem to send meaningful causes yet!
6050 // For now just accept any cause.
6051 BSSAP.receive(tr_BSSMAP_ClearRequest);
6052 setverdict(pass);
6053 return;
6054 }
6055 }
6056
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006057 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6058
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006059 /* we're sure that the channel activation is done now, verify the parameters in it */
6060 var RSL_Message chan_act := f_rslem_get_last_act(RSL_PROC, 0, g_chan_nr);
6061 f_verify_encr_info(chan_act);
6062 f_chan_act_verify_tsc(chan_act, expect_target_tsc);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006063
Neels Hofmeyr46e16e52022-02-23 17:04:00 +01006064 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.codecList)) {
6065 if (not g_pars.aoip) {
6066 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6067 "handoverRequestAck: Expected no Speech Codec List (BSS Supported), because this is not AoIP");
6068 }
6069 /* TODO: check actual codecs? */
6070 } else {
6071 if (g_pars.aoip) {
6072 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6073 "handoverRequestAck: Expected Speech Codec List (BSS Supported), but none found");
6074 }
6075 }
6076
6077 if (ispresent(rx_bssap.pdu.bssmap.handoverRequestAck.speechCodec)) {
6078 if (not g_pars.aoip) {
6079 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6080 "handoverRequestAck: Expected no Speech Codec (Chosen), because this is not AoIP");
6081 }
6082 /* TODO: check actual codec? */
6083 } else {
6084 if (g_pars.aoip) {
6085 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
6086 "handoverRequestAck: Expected Speech Codec (Chosen), but none found");
6087 }
6088 }
6089
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006090 var octetstring ho_command_str;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006091 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6092 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6093 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6094 log("L3 Info in HO Request Ack is ", ho_command);
6095
6096 var GsmArfcn arfcn;
6097 var RslChannelNr actual_new_chan_nr;
6098 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6099 actual_new_chan_nr, arfcn);
6100
6101 if (actual_new_chan_nr != new_chan_nr) {
6102 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6103 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6104 setverdict(fail);
6105 return;
6106 }
6107 log("Handover Command chan_nr is", actual_new_chan_nr);
6108
Neels Hofmeyr34174bd2021-10-02 14:52:57 +02006109 var uint3_t got_tsc := rr_chan_desc_tsc(ho_command.msgs.rrm.handoverCommand.channelDescription2);
6110 if (not match(got_tsc, expect_target_tsc)) {
6111 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6112 expect_target_tsc, " got ", got_tsc);
6113 mtc.stop;
6114 } else {
6115 log("handoverCommand: verified TSC = ", got_tsc);
6116 }
6117
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006118 /* Check the Cipher Mode Setting IE (shall be present during inter-RAT handover) */
6119 if (ispresent(ho_command.msgs.rrm.handoverCommand.cipherModeSetting)) {
6120 var CipherModeSetting_TV cms := ho_command.msgs.rrm.handoverCommand.cipherModeSetting;
6121 var template (present) CipherModeSetting_TV tr_cms := {
6122 sC := '0'B, /* no ciphering by default */
6123 algorithmIdentifier := '000'B,
6124 elementIdentifier := ?
6125 };
6126 if (ispresent(g_pars.encr) and g_pars.encr.enc_alg_expect != '01'O) { /* A5/N */
6127 tr_cms.algorithmIdentifier := f_cipher_mode_bssmap_to_rr(g_pars.encr.enc_alg_expect);
6128 tr_cms.sC := '1'B;
6129 }
6130 if (not match(cms, tr_cms)) {
6131 setverdict(fail, "RR Handover Command: unexpected Cipher Mode Setting IE: ",
6132 cms, ", expected: ", tr_cms);
6133 }
6134 } else {
6135 setverdict(fail, "RR Handover Command: Cipher Mode Setting IE is not present");
6136 }
6137
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006138 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6139 * tells the MS to handover to the new lchan. Here comes the new MS on
6140 * the new lchan with a Handover RACH: */
6141
6142 /* send handover detect */
6143
6144 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6145
6146 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6147
6148 /* send handover complete over the new channel */
6149
6150 var PDU_ML3_MS_NW l3_tx := valueof(ts_RRM_HandoverComplete('00'O));
6151 RSL.send(ts_RSL_EST_IND(new_chan_nr, valueof(ts_RslLinkID_DCCH(0)),
6152 enc_PDU_ML3_MS_NW(l3_tx)));
6153
6154 BSSAP.receive(tr_BSSMAP_HandoverComplete);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006155 setverdict(pass);
6156}
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006157
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006158private function f_tc_ho_into_this_bsc(charstring id) runs on MSC_ConnHdlr {
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006159 var template PDU_ML3_NW_MS exp_rr_rel_tmpl;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006160 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs := omit;
6161 if (not istemplatekind(g_pars.last_used_eutran_plmn, "omit")) {
6162 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006163 }
6164 if (g_pars.exp_fast_return) {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006165 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE_CellSelectInd;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006166 } else {
6167 exp_rr_rel_tmpl := tr_RRM_RR_RELEASE;
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006168 }
6169 f_ho_into_this_bsc(id, oldToNewBSSIEs);
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006170 if (g_pars.expect_ho_fail) {
6171 f_perform_clear_no_lchan();
6172 } else {
6173 f_perform_clear(exp_rr_rel_tmpl := exp_rr_rel_tmpl);
6174 }
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006175 setverdict(pass);
6176}
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006177function 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 +01006178 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006179
6180 f_init(1, true);
6181 f_sleep(1.0);
6182
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006183 f_vty_encryption_a5(vty_a5_cfg);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006184 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006185
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006186 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6187 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006188
6189 vc_conn := f_start_handler(refers(f_tc_ho_into_this_bsc), pars);
6190 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006191
6192 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006193 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006194 if (pars.expect_ho_fail) {
6195 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6196 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:failed");
6197 } else {
6198 f_ctrs_bsc_and_bts_add(0, "handover:completed");
6199 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed");
6200 }
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006201 f_ctrs_bsc_and_bts_verify();
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006202
6203 f_vty_encryption_a5_reset();
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006204}
6205
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006206testcase TC_ho_into_this_bsc() runs on test_CT {
6207 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6208 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006209 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006210}
6211
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006212function f_tc_ho_into_this_bsc_a5(TestHdlrEncrParams encr, charstring vty_a5_cfg := VTY_A5_DEFAULT,
6213 boolean expect_fail := false) runs on test_CT {
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006214 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006215 pars.encr := encr;
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006216 pars.expect_ho_fail := expect_fail;
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006217 f_tc_ho_into_this_bsc_main(pars, vty_a5_cfg);
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006218 f_shutdown_helper();
6219}
6220
6221testcase TC_ho_into_this_bsc_a5_0() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006222 f_tc_ho_into_this_bsc_a5(f_encr_params('01'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006223}
6224
6225testcase TC_ho_into_this_bsc_a5_1() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006226 f_tc_ho_into_this_bsc_a5(f_encr_params('02'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006227}
6228
6229testcase TC_ho_into_this_bsc_a5_3() runs on test_CT {
Neels Hofmeyrd23e8a02022-02-17 01:55:59 +01006230 f_tc_ho_into_this_bsc_a5(f_encr_params('08'O));
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006231}
6232
6233testcase TC_ho_into_this_bsc_a5_4() runs on test_CT {
Neels Hofmeyr731ddc52022-02-17 21:56:15 +01006234 f_tc_ho_into_this_bsc_a5(f_encr_params('10'O, kc128 := true), "3 4");
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +02006235}
6236
Neels Hofmeyr1951be22022-02-16 16:21:07 +01006237/* Report: in inter-BSC incoming handover, when the MSC omits the Chosen Encryption Algorithm IE in the Handover Request
6238 * message, then osmo-bsc starts an unencrypted lchan even if A5/0 is not permitted.
6239 *
6240 * This test verifies that the Encryption Information is present in the Channel Activation when the Chosen Enc Alg is
6241 * omitted.
6242 *
6243 * Related: SYS#5839
6244 */
6245testcase TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() runs on test_CT {
6246 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O, alg_chosen := omit));
6247}
6248
6249testcase TC_ho_into_this_bsc_a5_1_3() runs on test_CT {
6250 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '0a'O, alg_expect := '08'O));
6251}
6252
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01006253/* Send a permitted algo mask that does not intersect with osmo-bsc.cfg */
6254testcase TC_ho_into_this_bsc_a5_mismatch() runs on test_CT {
6255 f_tc_ho_into_this_bsc_a5(f_encr_params(alg_permitted := '18'O, alg_expect := '10'O), "0 1",
6256 expect_fail := true); // 0x18 = A5/3 and A5/4
6257}
6258
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006259testcase TC_ho_into_this_bsc_tla_v6() runs on test_CT {
6260 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6261 pars.host_aoip_tla := "::6";
6262 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006263 f_shutdown_helper();
Pau Espin Pedrol07866632020-09-03 19:10:55 +02006264}
6265
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006266/* Similar to TC_ho_into_this_bsc, but when in SRVCC, HO Req contains "Old BSS
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006267 to New BSS Information" IE with "Last Used E-UTRAN PLMN Id", which, when the
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006268 channel is later released (RR CHannel Release), should trigger inclusion of
6269 IE "Cell Selection Indicator after Release of all TCH and SDCCH" with E-UTRAN
6270 neighbors. */
6271testcase TC_srvcc_eutran_to_geran() runs on test_CT {
6272 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6273 pars.last_used_eutran_plmn := '323454'O;
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006274 pars.exp_fast_return := true;
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006275 f_tc_ho_into_this_bsc_main(pars);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006276
6277 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6278 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6279 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02006280 f_shutdown_helper();
6281}
6282
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +03006283/* Same as TC_srvcc_eutran_to_geran, but enables ciphering on the target channel. */
6284testcase TC_srvcc_eutran_to_geran_a5_3() runs on test_CT {
6285 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6286 pars.encr := f_encr_params('08'O); /* only A5/3 */
6287 pars.last_used_eutran_plmn := '323454'O;
6288 pars.exp_fast_return := true;
6289 f_tc_ho_into_this_bsc_main(pars);
6290
6291 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6292 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6293 f_ctrs_bsc_and_bts_verify();
6294 f_shutdown_helper();
6295}
6296
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006297/* Same as TC_srvcc_eutran_to_geran, but test explicitly forbiding fast return
6298 on the BTS. As a result, RR Release shouldn't contain the EUTRAN neighbor
6299 list when the channel is released. */
6300testcase TC_srvcc_eutran_to_geran_forbid_fast_return() runs on test_CT {
6301 f_init_vty();
6302 f_vty_allow_srvcc_fast_return(true, 0)
6303
6304 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6305 pars.last_used_eutran_plmn := '323454'O;
6306 pars.exp_fast_return := false;
6307 f_tc_ho_into_this_bsc_main(pars);
6308 f_vty_allow_srvcc_fast_return(false, 0);
6309 f_shutdown_helper();
6310}
6311
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +01006312/* Same as TC_srvcc_eutran_to_geran, but using SAI as serving Cell Identifier. SYS#5838 */
6313testcase TC_srvcc_eutran_to_geran_src_sai() runs on test_CT {
6314 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6315 pars.last_used_eutran_plmn := '323454'O;
6316 pars.cell_id_source := valueof(ts_CellID_SAI('123456'O, 300, 444));
6317 f_tc_ho_into_this_bsc_main(pars);
6318
6319 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted");
6320 f_ctrs_bsc_and_bts_add(0, "srvcc:completed");
6321 f_ctrs_bsc_and_bts_verify();
6322 f_shutdown_helper();
6323}
6324
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006325private function f_tc_srvcc_eutran_to_geran_ho_out(charstring id) runs on MSC_ConnHdlr {
6326 var template (omit) BSSMAP_oldToNewBSSIEs oldToNewBSSIEs;
6327 oldToNewBSSIEs := f_ts_BSSMAP_oldToNewBSSIEs(ts_BSSMAP_LastUsedEUTRANPLMNId(g_pars.last_used_eutran_plmn));
6328 f_ho_into_this_bsc(id, oldToNewBSSIEs);
6329 f_ho_out_of_this_bsc(oldToNewBSSIEs);
6330 setverdict(pass);
6331}
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006332
6333private function f_tc_srvcc_eutran_to_geran_ho_out_main(boolean disable_fast_return)
6334 runs on test_CT {
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006335 var MSC_ConnHdlr vc_conn;
6336 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6337
Neels Hofmeyr6cc90eb2021-12-15 12:49:39 +01006338 f_init_vty();
6339 f_bts_0_cfg(BSCVTY,
6340 {"neighbor-list mode automatic",
6341 "handover 1",
6342 "handover algorithm 2",
6343 "handover2 window rxlev averaging 1",
6344 "no neighbors",
6345 "neighbor lac 99 arfcn 123 bsic any"});
6346 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
6347
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006348 f_init(1, true);
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006349 if (disable_fast_return) {
6350 f_vty_allow_srvcc_fast_return(true, 0);
6351 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006352 f_sleep(1.0);
6353
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006354 f_ctrs_bsc_and_bts_handover_init();
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006355
6356 pars.last_used_eutran_plmn := '323454'O;
6357 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6358 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
6359
6360 vc_conn := f_start_handler(refers(f_tc_srvcc_eutran_to_geran_ho_out), pars);
6361 vc_conn.done;
6362
6363 f_ctrs_bsc_and_bts_add(0, "handover:attempted", 2);
6364 f_ctrs_bsc_and_bts_add(0, "handover:completed", 2);
6365 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted", 1);
6366 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:completed", 1);
6367 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted", 1);
6368 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:completed", 1);
Pau Espin Pedrol211a7142021-06-15 16:43:03 +02006369
6370 f_ctrs_bsc_and_bts_add(0, "srvcc:attempted", 1);
6371 f_ctrs_bsc_and_bts_add(0, "srvcc:completed", 1);
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006372 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006373
6374 if (disable_fast_return) {
6375 f_vty_allow_srvcc_fast_return(false, 0);
6376 }
Pau Espin Pedrol35801c32021-04-19 13:03:20 +02006377 f_shutdown_helper();
6378}
6379
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02006380/* First, HO into BSC from EUTRAN (SRVCC): HO Request contains "Old BSS to New
6381 BSS Information" IE with "Last Used E-UTRAN PLMN Id".
6382 Second, HO to another BSC: HO Required contains "Old BSS to New BSS Information"
6383 IE with "Last Used E-UTRAN PLMN Id" from first step. */
6384testcase TC_srvcc_eutran_to_geran_ho_out() runs on test_CT {
6385 f_tc_srvcc_eutran_to_geran_ho_out_main(false);
6386}
6387/* Validate subsequent intra-GSM-HO works the same (with OldBSSToNewBSSInfo IE)
6388 * independently of fast-reture allowed/forbidden in local BTS */
6389testcase TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() runs on test_CT {
6390 f_tc_srvcc_eutran_to_geran_ho_out_main(true);
6391}
6392
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006393private function f_tc_ho_in_fail_msc_clears(charstring id) runs on MSC_ConnHdlr {
6394 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6395 f_rslem_register(0, new_chan_nr);
6396 g_chan_nr := new_chan_nr;
6397 f_sleep(1.0);
6398
6399 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6400 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6401 activate(as_Media());
6402
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006403 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006404 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006405 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006406
6407 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6408
6409 var PDU_BSSAP rx_bssap;
6410 var octetstring ho_command_str;
6411
6412 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6413
6414 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6415 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6416 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6417 log("L3 Info in HO Request Ack is ", ho_command);
6418
6419 var GsmArfcn arfcn;
6420 var RslChannelNr actual_new_chan_nr;
6421 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6422 actual_new_chan_nr, arfcn);
6423
6424 if (actual_new_chan_nr != new_chan_nr) {
6425 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6426 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6427 setverdict(fail);
6428 return;
6429 }
6430 log("Handover Command chan_nr is", actual_new_chan_nr);
6431
Neels Hofmeyr61ca08d2019-05-06 23:52:22 +02006432 /* For deterministic test results, give some time for the MGW endpoint to be configured */
6433 f_sleep(1.0);
6434
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006435 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6436 * tells the MS to handover to the new lchan. In this case, the MS
6437 * reports a Handover Failure to the old BSS, which forwards a BSSMAP
6438 * Handover Failure to the MSC. The procedure according to 3GPP TS
6439 * 48.008 3.1.5.3.2 "Handover Failure" is then that the MSC sends a
6440 * BSSMAP Clear Command: */
6441
6442 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6443 var BssmapCause cause := enum2int(cause_val);
6444 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6445
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006446 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006447 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006448 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006449
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006450 setverdict(pass);
6451 f_sleep(1.0);
6452
6453 setverdict(pass);
6454}
6455testcase TC_ho_in_fail_msc_clears() runs on test_CT {
6456 var MSC_ConnHdlr vc_conn;
6457 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6458
6459 f_init(1, true);
6460 f_sleep(1.0);
6461
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006462 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006463
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006464 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6465 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006466
6467 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears), pars);
6468 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006469
6470 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6471 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6472 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6473 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6474 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006475 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006476}
6477
6478private function f_tc_ho_in_fail_msc_clears_after_ho_detect(charstring id) runs on MSC_ConnHdlr {
6479 /* Hack: the proper way would be to wait for the BSSMAP Handover Request ACK and extract the
6480 * actual assigned chan_nr from its L3 (RR Handover Command) message. But osmo-bsc starts acting
6481 * on the lchan even before we get a chance to evaluate the BSSMAP Handover Request ACK. So we
6482 * need to assume that osmo-bsc will activate TS 1 and already set up this lchan's RSL emulation
6483 * before we get started. */
6484 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6485 f_rslem_register(0, new_chan_nr);
6486 g_chan_nr := new_chan_nr;
6487 f_sleep(1.0);
6488
6489 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6490 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6491 activate(as_Media());
6492
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006493 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006494 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006495 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006496
6497 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6498
6499 var PDU_BSSAP rx_bssap;
6500 var octetstring ho_command_str;
6501
6502 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6503
6504 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6505 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6506 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6507 log("L3 Info in HO Request Ack is ", ho_command);
6508
6509 var GsmArfcn arfcn;
6510 var RslChannelNr actual_new_chan_nr;
6511 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6512 actual_new_chan_nr, arfcn);
6513
6514 if (actual_new_chan_nr != new_chan_nr) {
6515 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6516 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6517 setverdict(fail);
6518 return;
6519 }
6520 log("Handover Command chan_nr is", actual_new_chan_nr);
6521
6522 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6523 * tells the MS to handover to the new lchan. Here comes the new MS on
6524 * the new lchan with a Handover RACH: */
6525
6526 /* send handover detect */
6527
6528 RSL.send(ts_RSL_HANDO_DET(new_chan_nr));
6529
6530 BSSAP.receive(tr_BSSMAP_HandoverDetect);
6531
6532 /* The MSC chooses to clear the connection now, maybe we got the
6533 * Handover RACH on the new cell but the MS still signaled Handover
6534 * Failure to the old BSS? */
6535
6536 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6537 var BssmapCause cause := enum2int(cause_val);
6538 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6539
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006540 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006541 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006542 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006543
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006544 f_sleep(1.0);
6545}
6546testcase TC_ho_in_fail_msc_clears_after_ho_detect() runs on test_CT {
6547 var MSC_ConnHdlr vc_conn;
6548 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6549
6550 f_init(1, true);
6551 f_sleep(1.0);
6552
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006553 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006554
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006555 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6556 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006557
6558 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_msc_clears_after_ho_detect), pars);
6559 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006560
6561 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6562 f_ctrs_bsc_and_bts_add(0, "handover:stopped");
6563 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6564 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:stopped");
6565 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006566 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006567}
6568
6569/* The new BSS's lchan times out before the MSC decides that handover failed. */
6570private function f_tc_ho_in_fail_no_detect(charstring id) runs on MSC_ConnHdlr {
6571 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6572 f_rslem_register(0, new_chan_nr);
6573 g_chan_nr := new_chan_nr;
6574 f_sleep(1.0);
6575
6576 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6577 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6578 activate(as_Media());
6579
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006580 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006581 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006582 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006583
6584 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6585
6586 var PDU_BSSAP rx_bssap;
6587 var octetstring ho_command_str;
6588
6589 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6590
6591 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6592 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6593 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6594 log("L3 Info in HO Request Ack is ", ho_command);
6595
6596 var GsmArfcn arfcn;
6597 var RslChannelNr actual_new_chan_nr;
6598 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6599 actual_new_chan_nr, arfcn);
6600
6601 if (actual_new_chan_nr != new_chan_nr) {
6602 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6603 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6604 setverdict(fail);
6605 return;
6606 }
6607 log("Handover Command chan_nr is", actual_new_chan_nr);
6608
6609 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6610 * tells the MS to handover to the new lchan. But the MS never shows up
6611 * on the new lchan. */
6612
6613 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6614
6615 /* Did osmo-bsc also send a Clear Request? */
6616 timer T := 0.5;
6617 T.start;
6618 alt {
6619 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
6620 [] T.timeout { }
6621 }
6622
6623 /* MSC plays along with a Clear Command (no matter whether osmo-bsc
6624 * asked for it, this is a Handover Failure after all). */
6625
6626 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_RADIO_INTERFACE_FAILURE_REVERSION;
6627 var BssmapCause cause := enum2int(cause_val);
6628 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6629
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006630 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006631 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006632 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006633
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006634 f_sleep(1.0);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006635}
6636testcase TC_ho_in_fail_no_detect() runs on test_CT {
6637 var MSC_ConnHdlr vc_conn;
6638 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6639
6640 f_init(1, true);
6641 f_sleep(1.0);
6642
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006643 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006644
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006645 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6646 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006647
6648 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect), pars);
6649 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006650
6651 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6652 f_ctrs_bsc_and_bts_add(0, "handover:error");
6653 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6654 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6655 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006656 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006657}
6658
6659/* Same as f_tc_ho_in_fail_no_detect, but MSC fails to send a Clear Command */
6660private function f_tc_ho_in_fail_no_detect2(charstring id) runs on MSC_ConnHdlr {
6661 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
6662 f_rslem_register(0, new_chan_nr);
6663 g_chan_nr := new_chan_nr;
6664 f_sleep(1.0);
6665
6666 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
6667 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
6668 activate(as_Media());
6669
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006670 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006671 f_gen_handover_req()));
Harald Welte6811d102019-04-14 22:23:14 +02006672 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006673
6674 /* The RSL Emulation magically accepts the Chan Activ behind the scenes. */
6675
6676 var PDU_BSSAP rx_bssap;
6677 var octetstring ho_command_str;
6678
6679 BSSAP.receive(tr_BSSMAP_HandoverRequestAcknowledge(?)) -> value rx_bssap;
6680
6681 ho_command_str := rx_bssap.pdu.bssmap.handoverRequestAck.layer3Information.layer3info;
6682 log("Received L3 Info in HO Request Ack: ", ho_command_str);
6683 var PDU_ML3_NW_MS ho_command := dec_PDU_ML3_NW_MS(ho_command_str);
6684 log("L3 Info in HO Request Ack is ", ho_command);
6685
6686 var GsmArfcn arfcn;
6687 var RslChannelNr actual_new_chan_nr;
6688 f_ChDesc2RslChanNr(ho_command.msgs.rrm.handoverCommand.channelDescription2,
6689 actual_new_chan_nr, arfcn);
6690
6691 if (actual_new_chan_nr != new_chan_nr) {
6692 log("ERROR: osmo-bsc assigned a different lchan than we assumed above -- this test will fail now.",
6693 " Assumed: ", new_chan_nr, " Assigned: ", actual_new_chan_nr);
6694 setverdict(fail);
6695 return;
6696 }
6697 log("Handover Command chan_nr is", actual_new_chan_nr);
6698
6699 /* Now the MSC forwards the RR Handover Command to the other BSC, which
6700 * tells the MS to handover to the new lchan. But the MS never shows up
6701 * on the new lchan. */
6702
6703 BSSAP.receive(tr_BSSMAP_HandoverFailure);
6704
6705 /* MSC plays dumb and sends no Clear Command */
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006706 var PDU_BSSAP rx_clear_request;
Pau Espin Pedrol1fc30b92019-06-18 13:08:22 +02006707
6708 BSSAP.receive(tr_BSSMAP_ClearRequest) -> value rx_clear_request {
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006709 var BssmapCause cause := bit2int(rx_clear_request.pdu.bssmap.clearRequest.cause.causeValue);
6710 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
6711 };
Pau Espin Pedrol7aa02742019-06-26 16:30:14 +02006712 f_expect_dlcx_conns();
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006713 BSSAP.receive(tr_BSSMAP_ClearComplete);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006714 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
Neels Hofmeyr8fcd8772021-07-22 16:12:57 +02006715
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006716 f_sleep(1.0);
6717}
6718testcase TC_ho_in_fail_no_detect2() runs on test_CT {
6719 var MSC_ConnHdlr vc_conn;
6720 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6721
6722 f_init(1, true);
6723 f_sleep(1.0);
6724
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006725 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006726
Neels Hofmeyr90f80962020-06-12 16:16:55 +02006727 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
6728 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006729
6730 vc_conn := f_start_handler(refers(f_tc_ho_in_fail_no_detect2), pars);
6731 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006732
6733 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6734 f_ctrs_bsc_and_bts_add(0, "handover:error");
6735 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:attempted");
6736 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_in:error");
6737 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006738 f_shutdown_helper();
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +01006739}
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +01006740
Neels Hofmeyra23f3b12022-03-02 19:57:12 +01006741/* An incoming inter-BSC HO can either issue the Handover Request message attached to the initial SCCP N-Connect (as in
6742 * the other tests we have so far), or the first CR can be "empty" with the BSSAP request following later. Test the
6743 * empty N-Connect case. */
6744testcase TC_ho_into_this_bsc_sccp_cr_without_bssap() runs on test_CT {
6745 var TestHdlrParams pars := f_gen_test_hdlr_pars();
6746 pars.inter_bsc_ho_in__ho_req_in_initial_sccp_cr := false;
6747 f_tc_ho_into_this_bsc_main(pars);
6748 f_shutdown_helper();
6749}
6750
Neels Hofmeyr91401012019-07-11 00:42:35 +02006751type record of charstring Commands;
6752
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006753private function f_bts_0_cfg(TELNETasp_PT pt, Commands cmds := {})
Neels Hofmeyr91401012019-07-11 00:42:35 +02006754{
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006755 f_vty_enter_cfg_bts(pt, 0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006756 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006757 f_vty_transceive(pt, cmds[i]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006758 }
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006759 f_vty_transceive(pt, "end");
Neels Hofmeyr91401012019-07-11 00:42:35 +02006760}
6761
Pau Espin Pedrolc675b612020-01-09 19:55:40 +01006762private function f_cs7_inst_0_cfg(TELNETasp_PT pt, Commands cmds := {})
6763{
6764 f_vty_enter_cfg_cs7_inst(pt, 0);
6765 for (var integer i := 0; i < sizeof(cmds); i := i+1) {
6766 f_vty_transceive(pt, cmds[i]);
6767 }
6768 f_vty_transceive(pt, "end");
6769}
6770
Neels Hofmeyr91401012019-07-11 00:42:35 +02006771private function f_probe_for_handover(charstring log_label,
6772 charstring log_descr,
6773 charstring handover_vty_cmd,
6774 boolean expect_handover,
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006775 boolean is_inter_bsc_handover := false,
6776 template uint3_t expect_target_tsc := ?)
Neels Hofmeyr91401012019-07-11 00:42:35 +02006777runs on MSC_ConnHdlr
6778{
Neels Hofmeyrb3fc8982020-05-11 00:16:42 +02006779 /* We're going to thwart any and all handover attempts, just be ready to handle (and ignore) handover target
6780 * lchans to be established on bts 1 or bts 2. */
6781 f_rslem_suspend(RSL1_PROC);
6782 f_rslem_suspend(RSL2_PROC);
6783
Neels Hofmeyr91401012019-07-11 00:42:35 +02006784 var RSL_Message rsl;
6785
6786 var charstring log_msg := " (expecting handover)"
6787 if (not expect_handover) {
6788 log_msg := " (expecting NO handover)";
6789 }
6790 log("f_probe_for_handover starting: " & log_label & ": " & log_descr & log_msg);
6791 f_vty_transceive(BSCVTY, handover_vty_cmd);
6792
Neels Hofmeyr91401012019-07-11 00:42:35 +02006793 timer T := 2.0;
6794 T.start;
6795
6796 alt {
6797 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
6798 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
6799 log("Rx L3 from net: ", l3);
6800 if (ischosen(l3.msgs.rrm.handoverCommand)) {
6801 var RslChannelNr new_chan_nr;
6802 var GsmArfcn arfcn;
6803 f_ChDesc2RslChanNr(l3.msgs.rrm.handoverCommand.channelDescription2,
6804 new_chan_nr, arfcn);
6805 log("Handover to new chan ", new_chan_nr, " on ARFCN ", arfcn);
6806 log(l3.msgs.rrm.handoverCommand);
6807
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006808 /* Verify correct TSC in handoverCommand */
6809 var uint3_t got_tsc := rr_chan_desc_tsc(l3.msgs.rrm.handoverCommand.channelDescription2);
6810 if (not match(got_tsc, expect_target_tsc)) {
6811 setverdict(fail, "RR Handover Command: unexpected TSC in Channel Description: expected ",
6812 expect_target_tsc, " got ", got_tsc);
6813 mtc.stop;
6814 } else {
6815 log("handoverCommand: verified TSC = ", got_tsc, " (matches ",
6816 expect_target_tsc, ")");
6817 }
6818
Neels Hofmeyr91401012019-07-11 00:42:35 +02006819 /* Need to register for new lchan on new BTS -- it's either bts 1 or bts 2. It doesn't really
6820 * matter on which BTS it really is, we're not going to follow through an entire handover
6821 * anyway. */
6822 f_rslem_register(0, new_chan_nr, RSL1_PROC);
6823 f_rslem_resume(RSL1_PROC);
6824 f_rslem_register(0, new_chan_nr, RSL2_PROC);
6825 f_rslem_resume(RSL2_PROC);
6826
6827 if (expect_handover and not is_inter_bsc_handover) {
6828 setverdict(pass);
6829 log("f_probe_for_handover(" & log_label & "): Got RSL Handover Command as expected.");
6830 } else {
6831 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got RSL Handover Command. "
6832 & log_label & ": " & log_descr);
6833 }
6834
6835 log("f_probe_for_handover(" & log_label & "): Ending the test: Handover Failure stops the procedure.");
6836 /* osmo-bsc has triggered Handover. That's all we need to know for this test, reply with
6837 * Handover Failure. */
6838 f_rsl_send_l3(ts_RRM_HandoverFailure('00'O));
6839
6840 /* target BTS is told to release lchan again; don't care which BTS nor what messages. */
6841 f_sleep(0.5);
6842 RSL1.clear;
6843 RSL2.clear;
6844 log("f_probe_for_handover(" & log_label & "): done (got RSL Handover Command)");
6845 break;
6846 } else {
6847 repeat;
6848 }
6849 }
6850 [] BSSAP.receive(tr_BSSMAP_HandoverRequired) {
6851 if (expect_handover and is_inter_bsc_handover) {
6852 setverdict(pass);
6853 log("f_probe_for_handover(" & log_label & "): Got BSSMAP Handover Required as expected.");
6854 } else {
6855 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected none, but got BSSMAP Handover Required. "
6856 & log_label & ": " & log_descr);
6857 }
6858
6859 log("f_probe_for_handover(" & log_label & "): done (got BSSMAP Handover Required)");
6860
6861 /* Note: f_tc_ho_neighbor_config_start() sets T7, the timeout for BSSMAP Handover Required, to
6862 * 1 second. There is no legal way to quickly abort a handover after a BSSMAP Handover Required,
6863 * setting a short timeout and waiting is the only way. */
6864 log("f_probe_for_handover(" & log_label & "): waiting for inter-BSC HO to time out...");
6865 f_sleep(1.5);
6866 log("f_probe_for_handover(" & log_label & "): ...done");
6867
6868 break;
6869 }
6870 [] T.timeout {
6871 if (expect_handover) {
6872 setverdict(fail, "f_probe_for_handover(" & log_label & "): Expected Handover, but got none. "
6873 & log_label & ": " & log_descr);
6874 } else {
6875 setverdict(pass);
6876 log("f_probe_for_handover(" & log_label & "): Got no Handover, as expected.");
6877 }
6878 log("f_probe_for_handover(" & log_label & "): done (got no Handover)");
6879 break;
6880 }
6881 }
6882
6883 f_rslem_resume(RSL1_PROC);
6884 f_rslem_resume(RSL2_PROC);
6885 f_sleep(3.0);
6886 RSL.clear;
6887
6888 log("f_probe_for_handover(" & log_label & "): done clearing");
6889}
6890
6891/* Test the effect of various neighbor configuration scenarios:
6892 *
6893 * To avoid complexity, block off any actual handover operation, and always remain on the lchan at bts 0.
6894 * Reconfigure the neighbors for bts 0, trigger a Handover, and probe whether osmo-bsc does or doesn't start HO.
6895 */
6896private function f_tc_ho_neighbor_config_start() runs on MSC_ConnHdlr {
6897 g_pars := f_gen_test_hdlr_pars();
6898 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
6899 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006900
6901 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
6902 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
6903
6904 /* Establish lchan at bts 0 */
6905 f_establish_fully(ass_cmd, exp_compl);
6906
6907 /* Shorten the inter-BSC Handover timeout, to not wait so long for inter-BSC Handovers */
6908 f_vty_enter_cfg_network(BSCVTY);
6909 f_vty_transceive(BSCVTY, "timer T7 1");
6910 f_vty_transceive(BSCVTY, "end");
6911}
6912
6913private function f_tc_ho_neighbor_config_1(charstring id) runs on MSC_ConnHdlr {
6914 f_tc_ho_neighbor_config_start();
6915
6916 /*
6917 * bts 0 ARFCN 871 BSIC 10
6918 * bts 1 ARFCN 871 BSIC 11
6919 * bts 2 ARFCN 871 BSIC 12
6920 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6921 */
6922
6923 log("f_tc_ho_neighbor_config: 1. No 'neighbor' config");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006924 f_bts_0_cfg(BSCVTY, {"no neighbors"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006925 f_probe_for_handover("1.a", "HO to bts 1 works, implicitly listed as neighbor (legacy behavior when none are configured)",
6926 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006927 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02006928
6929 f_probe_for_handover("1.b", "HO to unknown cell does not start",
6930 "handover any to arfcn 13 bsic 39",
6931 false);
6932
6933 f_probe_for_handover("1.c", "HO to 871-12 is ambiguous = error",
6934 "handover any to arfcn 871 bsic 12",
6935 false);
6936
6937 f_probe_for_handover("1.d", "HO to 871-11 still works (verify that this test properly cleans up)",
6938 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02006939 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01006940
6941 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02006942}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006943testcase TC_ho_neighbor_config_1() runs on test_CT {
6944 var MSC_ConnHdlr vc_conn;
6945 f_init(3, true, guard_timeout := 60.0);
6946 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006947 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006948 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_1));
6949 vc_conn.done;
6950
6951 /* f_tc_ho_neighbor_config_start() */
6952 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
6953 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
6954
6955 /* 1.a */
6956 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
6957 * handover quickly by sending a Handover Failure message. */
6958 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6959 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6960 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6961 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006962 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6963 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006964
6965 /* 1.b */
6966 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6967 f_ctrs_bsc_and_bts_add(0, "handover:error");
6968
6969 /* 1.c */
6970 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6971 f_ctrs_bsc_and_bts_add(0, "handover:error");
6972
6973 /* 1.d */
6974 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
6975 f_ctrs_bsc_and_bts_add(0, "handover:failed");
6976 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
6977 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01006978 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
6979 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006980
6981 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02006982 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00006983}
6984
Neels Hofmeyr91401012019-07-11 00:42:35 +02006985private function f_tc_ho_neighbor_config_2(charstring id) runs on MSC_ConnHdlr {
6986 f_tc_ho_neighbor_config_start();
6987
6988 /*
6989 * bts 0 ARFCN 871 BSIC 10
6990 * bts 1 ARFCN 871 BSIC 11
6991 * bts 2 ARFCN 871 BSIC 12
6992 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
6993 */
6994
6995 log("f_tc_ho_neighbor_config: 2. explicit local neighbor: 'neighbor bts 1'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02006996 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02006997 f_sleep(0.5);
6998
6999 f_probe_for_handover("2.a", "HO to bts 1 works, explicitly listed as neighbor",
7000 "handover any to arfcn 871 bsic 11",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007001 true, expect_target_tsc := BTS_TSC[1]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007002
7003 f_probe_for_handover("2.b", "HO to bts 2 doesn't work, not listed as neighbor",
7004 "handover any to arfcn 871 bsic 12",
7005 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007006 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007007}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007008testcase TC_ho_neighbor_config_2() runs on test_CT {
7009 var MSC_ConnHdlr vc_conn;
7010 f_init(3, true, guard_timeout := 50.0);
7011 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007012 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007013 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_2));
7014 vc_conn.done;
7015
7016 /* f_tc_ho_neighbor_config_start() */
7017 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7018 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7019
7020 /* 2.a */
7021 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7022 * handover quickly by sending a Handover Failure message. */
7023 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7024 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7025 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7026 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007027 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:attempted");
7028 f_ctrs_bts_add(1, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007029
7030 /* 2.b */
7031 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7032 f_ctrs_bsc_and_bts_add(0, "handover:error");
7033
7034 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007035 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007036}
7037
Neels Hofmeyr91401012019-07-11 00:42:35 +02007038private function f_tc_ho_neighbor_config_3(charstring id) runs on MSC_ConnHdlr {
7039 f_tc_ho_neighbor_config_start();
7040
7041 /*
7042 * bts 0 ARFCN 871 BSIC 10
7043 * bts 1 ARFCN 871 BSIC 11
7044 * bts 2 ARFCN 871 BSIC 12
7045 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7046 */
7047
7048 log("f_tc_ho_neighbor_config: 3. explicit local neighbor: 'neighbor bts 2'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007049 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007050 f_sleep(0.5);
7051
7052 f_probe_for_handover("3.a", "HO to bts 1 doesn't work, not listed as neighbor",
7053 "handover any to arfcn 871 bsic 11",
7054 false);
7055 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",
7056 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007057 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007058 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007059}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007060testcase TC_ho_neighbor_config_3() runs on test_CT {
7061 var MSC_ConnHdlr vc_conn;
7062 f_init(3, true, guard_timeout := 50.0);
7063 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007064 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007065 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_3));
7066 vc_conn.done;
7067
7068 /* f_tc_ho_neighbor_config_start() */
7069 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7070 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7071
7072 /* 3.a */
7073 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7074 f_ctrs_bsc_and_bts_add(0, "handover:error");
7075
7076 /* 3.b */
7077 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7078 * handover quickly by sending a Handover Failure message. */
7079 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7080 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7081 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7082 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007083 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7084 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007085
7086 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007087 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007088}
7089
Neels Hofmeyr91401012019-07-11 00:42:35 +02007090private function f_tc_ho_neighbor_config_4(charstring id) runs on MSC_ConnHdlr {
7091 f_tc_ho_neighbor_config_start();
7092
7093 /*
7094 * bts 0 ARFCN 871 BSIC 10
7095 * bts 1 ARFCN 871 BSIC 11
7096 * bts 2 ARFCN 871 BSIC 12
7097 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7098 */
7099
7100 log("f_tc_ho_neighbor_config: 4. explicit remote neighbor: 'neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007101 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007102 f_sleep(0.5);
7103
7104 f_probe_for_handover("4.a", "HO to bts 1 doesn't work, not listed as neighbor",
7105 "handover any to arfcn 871 bsic 11",
7106 false);
7107 f_probe_for_handover("4.b", "HO to bts 2 doesn't work, not listed as neighbor",
7108 "handover any to arfcn 871 bsic 12",
7109 false);
7110 f_probe_for_handover("4.c", "HO to 123-45 triggers inter-BSC HO",
7111 "handover any to arfcn 123 bsic 45",
7112 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007113 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007114}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007115testcase TC_ho_neighbor_config_4() runs on test_CT {
7116 var MSC_ConnHdlr vc_conn;
7117 f_init(3, true, guard_timeout := 50.0);
7118 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007119 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007120 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_4));
7121 vc_conn.done;
7122
7123 /* f_tc_ho_neighbor_config_start() */
7124 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7125 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7126
7127 /* 4.a */
7128 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7129 f_ctrs_bsc_and_bts_add(0, "handover:error");
7130
7131 /* 4.b */
7132 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7133 f_ctrs_bsc_and_bts_add(0, "handover:error");
7134
7135 /* 4.c */
7136 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7137 * handover quickly by timing out after the Handover Required message */
7138 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7139 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7140 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7141 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7142
7143 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007144 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007145}
7146
Neels Hofmeyr91401012019-07-11 00:42:35 +02007147private function f_tc_ho_neighbor_config_5(charstring id) runs on MSC_ConnHdlr {
7148 f_tc_ho_neighbor_config_start();
7149
7150 /*
7151 * bts 0 ARFCN 871 BSIC 10
7152 * bts 1 ARFCN 871 BSIC 11
7153 * bts 2 ARFCN 871 BSIC 12
7154 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7155 */
7156
7157 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 +02007158 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007159 f_sleep(0.5);
7160
7161 f_probe_for_handover("5.a", "HO to 871-12 triggers inter-BSC HO (ignoring local cells with same ARFCN+BSIC)",
7162 "handover any to arfcn 871 bsic 12",
7163 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007164 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007165}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007166testcase TC_ho_neighbor_config_5() runs on test_CT {
7167 var MSC_ConnHdlr vc_conn;
7168 f_init(3, true);
7169 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007170 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007171 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_5));
7172 vc_conn.done;
7173
7174 /* f_tc_ho_neighbor_config_start() */
7175 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7176 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7177
7178 /* 5 */
7179 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7180 * handover quickly by timing out after the Handover Required message */
7181 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7182 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7183 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7184 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7185
7186 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007187 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007188}
7189
Neels Hofmeyr91401012019-07-11 00:42:35 +02007190private function f_tc_ho_neighbor_config_6(charstring id) runs on MSC_ConnHdlr {
7191 f_tc_ho_neighbor_config_start();
7192
7193 /*
7194 * bts 0 ARFCN 871 BSIC 10
7195 * bts 1 ARFCN 871 BSIC 11
7196 * bts 2 ARFCN 871 BSIC 12
7197 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7198 */
7199
7200 log("f_tc_ho_neighbor_config: 6. config error: explicit local and remote neighbors with ambiguous ARFCN+BSIC:"
7201 & " 'neighbor bts 2; neighbor lac 99 arfcn 871 bsic 12'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007202 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 871 bsic 12"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007203 f_sleep(0.5);
7204
7205 f_probe_for_handover("6.a", "HO to 871-12 is ambiguous = error",
7206 "handover any to arfcn 871 bsic 12",
7207 false);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007208 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007209}
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007210testcase TC_ho_neighbor_config_6() runs on test_CT {
7211 var MSC_ConnHdlr vc_conn;
7212 f_init(3, true);
7213 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007214 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007215 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_6));
7216 vc_conn.done;
7217
7218 /* f_tc_ho_neighbor_config_start() */
7219 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7220 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7221
7222 /* 6.a */
7223 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7224 * handover quickly by timing out after the Handover Required message */
7225 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7226 f_ctrs_bsc_and_bts_add(0, "handover:error");
7227
7228 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007229 f_shutdown_helper();
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007230}
7231
Neels Hofmeyr91401012019-07-11 00:42:35 +02007232private function f_tc_ho_neighbor_config_7(charstring id) runs on MSC_ConnHdlr {
7233 f_tc_ho_neighbor_config_start();
7234
7235 /*
7236 * bts 0 ARFCN 871 BSIC 10
7237 * bts 1 ARFCN 871 BSIC 11
7238 * bts 2 ARFCN 871 BSIC 12
7239 * bts 3 ARFCN 871 BSIC 12 serves as ambiguity for bts 2, re-using the ARFCN+BSIC
7240 */
7241
7242 log("f_tc_ho_neighbor_config: 7. explicit local and remote neighbors:"
7243 & " 'neighbor bts 2; neighbor lac 99 arfcn 123 bsic 45'");
Neels Hofmeyr666f0432020-07-04 00:53:07 +02007244 f_bts_0_cfg(BSCVTY, {"no neighbors", "neighbor bts 2", "neighbor lac 99 arfcn 123 bsic 45"});
Neels Hofmeyr91401012019-07-11 00:42:35 +02007245 f_sleep(0.5);
7246
7247 f_probe_for_handover("7.a", "HO to 871-12 does HO to bts 2",
7248 "handover any to arfcn 871 bsic 12",
Neels Hofmeyr6a955cc2021-10-02 14:53:48 +02007249 true, expect_target_tsc := BTS_TSC[2]);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007250 f_probe_for_handover("7.b", "HO to 123-45 triggers inter-BSC HO",
7251 "handover any to arfcn 123 bsic 45",
7252 true, true);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007253 f_perform_clear();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007254}
Neels Hofmeyr91401012019-07-11 00:42:35 +02007255testcase TC_ho_neighbor_config_7() runs on test_CT {
7256 var MSC_ConnHdlr vc_conn;
Neels Hofmeyrf2b88032020-06-16 00:35:04 +02007257 f_init(3, true, guard_timeout := 50.0);
Neels Hofmeyr91401012019-07-11 00:42:35 +02007258 f_sleep(1.0);
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007259 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007260 vc_conn := f_start_handler(refers(f_tc_ho_neighbor_config_7));
7261 vc_conn.done;
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007262
7263 /* f_tc_ho_neighbor_config_start() */
7264 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
7265 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
7266
7267 /* 7.a */
7268 /* "failed" means a handover was triggered and started (which is all this test aims for) and the test ended the
7269 * handover quickly by sending a Handover Failure message. */
7270 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7271 f_ctrs_bsc_and_bts_add(0, "handover:failed");
7272 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:attempted");
7273 f_ctrs_bsc_and_bts_add(0, "intra_bsc_ho:failed");
Neels Hofmeyrac432fa2021-11-02 16:45:56 +01007274 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:attempted");
7275 f_ctrs_bts_add(2, "incoming_intra_bsc_ho:failed");
Neels Hofmeyr12941bd2020-08-29 03:21:26 +00007276
7277 /* 7.b */
7278 /* "timeout" means a handover was triggered and started (which is all this test aims for) and the test ended the
7279 * handover quickly by timing out after the Handover Required message */
7280 f_ctrs_bsc_and_bts_add(0, "handover:attempted");
7281 f_ctrs_bsc_and_bts_add(0, "handover:timeout");
7282 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:attempted");
7283 f_ctrs_bsc_and_bts_add(0, "interbsc_ho_out:timeout");
7284
7285 f_ctrs_bsc_and_bts_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007286 f_shutdown_helper();
Neels Hofmeyr91401012019-07-11 00:42:35 +02007287}
7288
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007289/* OS#3041: Open and close N connections in a normal fashion, and expect no
7290 * BSSMAP Reset just because of that. */
7291testcase TC_bssap_rlsd_does_not_cause_bssmap_reset() runs on test_CT {
7292 var default d;
7293 var integer i;
7294 var DchanTuple dt;
7295
7296 f_init();
7297
7298 /* Wait for initial BSSMAP Reset to pass */
7299 f_sleep(4.0);
7300
7301 d := activate(no_bssmap_reset());
7302
7303 /* Setup up a number of connections and RLSD them again from the MSC
7304 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7305 * Let's do it some more times for good measure. */
Harald Weltec3260d92018-06-11 17:48:16 +02007306 for (i := 0; i < 4; i := i+1) {
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007307 /* Since we're doing a lot of runs, give each one a fresh
7308 * T_guard from the top. */
7309 T_guard.start;
7310
7311 /* Setup a BSSAP connection and clear it right away. This is
7312 * the MSC telling the BSC about a planned release, it's not an
7313 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007314 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +01007315
7316 /* MSC disconnects (RLSD). */
7317 BSSAP.send(ts_BSSAP_DISC_req(dt.sccp_conn_id, 0));
7318 }
7319
7320 /* In the buggy behavior, a timeout of 2 seconds happens between above
7321 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7322 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7323 f_sleep(4.0);
7324
7325 deactivate(d);
7326 f_shutdown_helper();
7327}
Harald Welte552620d2017-12-16 23:21:36 +01007328
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007329/* OS#3041: Open and close N connections in a normal fashion, and expect no
7330 * BSSMAP Reset just because of that. Invoke the release by a BSSMAP Clear from
7331 * the MSC. */
7332testcase TC_bssmap_clear_does_not_cause_bssmap_reset() runs on test_CT {
7333 var default d;
7334 var integer i;
7335 var DchanTuple dt;
7336 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007337 var myBSSMAP_Cause cause_val := GSM0808_CAUSE_CALL_CONTROL;
7338 var BssmapCause cause := enum2int(cause_val);
7339
7340 f_init();
7341
7342 /* Wait for initial BSSMAP Reset to pass */
7343 f_sleep(4.0);
7344
7345 d := activate(no_bssmap_reset());
7346
7347 /* Setup up a number of connections and RLSD them again from the MSC
7348 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7349 * Let's do it some more times for good measure. */
7350 for (i := 0; i < 8; i := i+1) {
7351 /* Since we're doing a lot of runs, give each one a fresh
7352 * T_guard from the top. */
7353 T_guard.start;
7354
7355 /* Setup a BSSAP connection and clear it right away. This is
7356 * the MSC telling the BSC about a planned release, it's not an
7357 * erratic loss of a connection. */
Harald Weltea1897182018-06-11 13:53:09 +02007358 dt := f_est_dchan(int2oct(i,1), 23+i, '00010203040506'O);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007359
7360 /* Instruct BSC to clear channel */
7361 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7362
7363 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007364 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyr4ff93282018-03-12 04:25:35 +01007365 }
7366
7367 /* In the buggy behavior, a timeout of 2 seconds happens between above
7368 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7369 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7370 f_sleep(4.0);
7371
7372 deactivate(d);
7373 f_shutdown_helper();
7374}
7375
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007376/* OS#3041: Open and close N connections in a normal fashion, and expect no
7377 * BSSMAP Reset just because of that. Close connections from the MS side with a
7378 * Release Ind on RSL. */
7379testcase TC_ms_rel_ind_does_not_cause_bssmap_reset() runs on test_CT {
7380 var default d;
7381 var integer i;
7382 var DchanTuple dt;
7383 var BSSAP_N_DATA_ind rx_di;
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007384 var integer j;
7385
7386 f_init();
7387
7388 /* Wait for initial BSSMAP Reset to pass */
7389 f_sleep(4.0);
7390
7391 d := activate(no_bssmap_reset());
7392
7393 /* Setup up a number of connections and RLSD them again from the MSC
7394 * side. In the buggy behavior, the fourth one triggers BSSMAP Reset.
7395 * Let's do it some more times for good measure. */
7396 for (i := 0; i < 8; i := i+1) {
7397 /* Since we're doing a lot of runs, give each one a fresh
7398 * T_guard from the top. */
7399 T_guard.start;
7400
7401 /* Setup a BSSAP connection and clear it right away. This is
7402 * the MSC telling the BSC about a planned release, it's not an
7403 * erratic loss of a connection. */
7404 dt := f_est_dchan('23'O, 23, '00010203040506'O);
7405
7406 /* simulate RLL REL IND */
7407 f_ipa_tx(0, ts_RSL_REL_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
7408
7409 /* expect Clear Request on MSC side */
7410 BSSAP.receive(tr_BSSAP_DATA_ind(dt.sccp_conn_id, tr_BSSMAP_ClearRequest)) -> value rx_di;
7411
7412 /* Instruct BSC to clear channel */
7413 var BssmapCause cause := bit2int(rx_di.userData.pdu.bssmap.clearRequest.cause.causeValue);
7414 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7415
7416 /* expect BSC to disable the channel */
Harald Welte641fcbe2018-06-14 10:58:35 +02007417 f_exp_chan_rel_and_clear(dt, 0);
Neels Hofmeyrfd445c32018-03-09 15:39:31 +01007418 }
7419
7420 /* In the buggy behavior, a timeout of 2 seconds happens between above
7421 * trigger (logs "SIGTRAN connection down, reconnecting...") and the
7422 * actual BSSMAP Reset. Wait a bit longer just to make sure. */
7423 f_sleep(4.0);
7424
7425 deactivate(d);
7426 f_shutdown_helper();
7427}
7428
Harald Welte94e0c342018-04-07 11:33:23 +02007429/***********************************************************************
7430 * IPA style dynamic PDCH
7431 ***********************************************************************/
7432
7433private function f_dyn_ipa_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7434 template (omit) RSL_Cause nack := omit)
7435runs on test_CT {
7436 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7437 var RSL_Message rsl_unused;
7438 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7439 f_vty_ts_action("pdch activate", bts_nr, trx_nr, ts_nr);
7440 /* expect the BSC to issue the related RSL command */
7441 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7442 if (istemplatekind(nack, "omit")) {
7443 /* respond with a related acknowledgement */
7444 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7445 } else {
7446 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_NACK(chan_nr, valueof(nack)));
7447 }
7448}
7449
7450private function f_dyn_ipa_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7451 template (omit) RSL_Cause nack := omit)
7452runs on test_CT {
7453 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(ts_nr));
7454 var RSL_Message rsl_unused;
7455 /* ask BSC via VTY to activate a given IPA style chan as PDCH */
7456 f_vty_ts_action("pdch deactivate", bts_nr, trx_nr, ts_nr);
7457 /* expect the BSC to issue the related RSL command */
7458 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_DEACT(chan_nr));
7459 if (istemplatekind(nack, "omit")) {
7460 /* respond with a related acknowledgement */
7461 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_ACK(chan_nr));
7462 } else {
7463 f_ipa_tx(0, ts_RSL_IPA_PDCH_DEACT_NACK(chan_nr, valueof(nack)));
7464 }
7465}
7466
7467private function f_ts_dyn_mode_get(integer bts_nr, integer trx_nr, integer ts_nr)
7468runs on test_CT return charstring {
7469 var charstring cmd, resp;
7470 cmd := "show timeslot "&int2str(bts_nr)&" "&int2str(trx_nr)&" "&int2str(ts_nr);
Stefan Sperlingcff13562018-11-13 15:24:06 +01007471 return f_vty_transceive_match_regexp_retry(BSCVTY, cmd, "*\((*)\)*", 0, 4, 1.0);
Harald Welte94e0c342018-04-07 11:33:23 +02007472}
7473
7474private function f_ts_dyn_mode_assert(integer bts_nr, integer trx_nr, integer ts_nr,
7475 template charstring exp)
7476runs on test_CT {
7477 var charstring mode := f_ts_dyn_mode_get(bts_nr, trx_nr, ts_nr);
7478 if (not match(mode, exp)) {
7479 setverdict(fail, "Unexpected TS Mode: ", mode);
Daniel Willmannafce8662018-07-06 23:11:32 +02007480 mtc.stop;
Harald Welte94e0c342018-04-07 11:33:23 +02007481 }
7482}
7483
7484private function f_ts_set_chcomb(integer bts_nr, integer trx_nr, integer ts_nr, charstring chcomb)
7485runs on test_CT {
7486 f_vty_enter_cfg_ts(BSCVTY, bts_nr, trx_nr, ts_nr);
7487 f_vty_transceive(BSCVTY, "phys_chan_config " & chcomb);
7488 f_vty_transceive(BSCVTY, "end");
7489}
7490
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007491
7492private function f_ts_reset_chcomb(integer bts_nr) runs on test_CT {
7493 var integer i;
7494 for (i := 0; i < 8; i := i + 1) {
7495 f_ts_set_chcomb(bts_nr, 0, i, phys_chan_config[i]);
7496 }
7497}
7498
Harald Welte94e0c342018-04-07 11:33:23 +02007499private const charstring TCHF_MODE := "TCH/F mode";
7500private const charstring TCHH_MODE := "TCH/H mode";
7501private const charstring PDCH_MODE := "PDCH mode";
7502private const charstring NONE_MODE := "NONE mode";
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007503private const charstring SDCCH8_MODE := "SDCCH8 mode";
Harald Welte94e0c342018-04-07 11:33:23 +02007504
7505/* Test IPA PDCH activation / deactivation triggered by VTY */
7506testcase TC_dyn_pdch_ipa_act_deact() runs on test_CT {
7507 var RSL_Message rsl_unused;
7508
7509 /* change Timeslot 6 before f_init() starts RSL */
7510 f_init_vty();
7511 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7512 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7513
7514 f_init(1, false);
7515 f_sleep(1.0);
7516
7517 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7518
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007519 log("TCH/F_PDCH pchan starts out in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007520 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7521 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7522 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7523 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7524 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007525 log("TCH/F_PDCH pchan, PDCH ACT was ACKed, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007526 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7527
7528 /* De-activate it via VTY */
7529 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7530 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007531 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007532 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7533
7534 /* re-activate it via VTY */
7535 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn);
7536 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007537 log("TCH/F_PDCH pchan, PDCH ACT via VTY, so now in PDCH mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007538 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7539
7540 /* and finally de-activate it again */
7541 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7542 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007543 log("TCH/F_PDCH pchan, PDCH DEACT via VTY, so now back in TCH/F mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007544 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7545
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007546 /* clean up config */
7547 f_ts_set_chcomb(0, 0, 6, "PDCH");
7548
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007549 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007550}
7551
7552/* Test IPA PDCH activation NACK */
7553testcase TC_dyn_pdch_ipa_act_nack() runs on test_CT {
7554 var RSL_Message rsl_unused;
7555
7556 /* change Timeslot 6 before f_init() starts RSL */
7557 f_init_vty();
7558 f_ts_set_chcomb(0, 0, 6, "TCH/F_PDCH");
7559 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7560
7561 f_init(1, false);
7562 f_sleep(1.0);
7563
7564 var RslChannelNr chan_nr := valueof(t_RslChanNr_Bm(6));
7565
7566 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7567 /* The BSC will activate the dynamic PDCH by default, so confirm that */
7568 rsl_unused := f_exp_ipa_rx(0, tr_RSL_IPA_PDCH_ACT(chan_nr));
7569 f_ipa_tx(0, ts_RSL_IPA_PDCH_ACT_ACK(chan_nr, ts_RSL_IE_FrameNumber(2342)));
7570 f_sleep(1.0);
7571 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7572
7573 /* De-activate it via VTY */
7574 f_dyn_ipa_pdch_deact(0, 0, chan_nr.tn);
7575 f_sleep(1.0);
7576 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7577
7578 /* re-activate it via VTY, but fail that; check BSC still assumes TCH/F mode */
7579 f_dyn_ipa_pdch_act(0, 0, chan_nr.tn, RSL_ERR_EQUIPMENT_FAIL);
7580 f_sleep(1.0);
7581 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, TCHF_MODE);
7582
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007583 /* clean up config */
7584 f_ts_set_chcomb(0, 0, 6, "PDCH");
7585
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007586 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007587}
7588
7589
7590/***********************************************************************
7591 * Osmocom style dynamic PDCH
7592 ***********************************************************************/
7593
7594private function f_dyn_osmo_pdch_act(integer bts_nr, integer trx_nr, integer ts_nr,
7595 template (omit) RSL_Cause nack := omit)
7596runs on test_CT {
7597 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7598 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007599 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007600 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7601 /* expect the BSC to issue the related RSL command */
7602 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT(chan_nr, ?));
7603 if (istemplatekind(nack, "omit")) {
7604 /* respond with a related acknowledgement */
7605 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7606 } else {
7607 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, valueof(nack)));
7608 }
7609}
7610
7611private function f_dyn_osmo_pdch_deact(integer bts_nr, integer trx_nr, integer ts_nr,
7612 template (omit) RSL_Cause nack := omit)
7613runs on test_CT {
7614 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(ts_nr));
7615 var RSL_Message rsl_unused;
Pau Espin Pedrol64adf372021-06-28 16:25:47 +02007616 /* ask BSC via VTY to activate a given OSMO style chan as PDCH */
Harald Welte94e0c342018-04-07 11:33:23 +02007617 /* FIXME: no VTY command to activate Osmocom PDCH !! */
7618 /* expect the BSC to issue the related RSL command */
7619 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
7620 if (istemplatekind(nack, "omit")) {
7621 /* respond with a related acknowledgement */
7622 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
7623 } else {
7624 //f_ipa_tx(0, ts_RSL_RF_CHAN_REL_NACK(chan_nr, valueof(nack)));
7625 }
7626}
7627
7628/* Test Osmocom dyn PDCH activation / deactivation triggered by VTY */
7629testcase TC_dyn_pdch_osmo_act_deact() runs on test_CT {
7630 var RSL_Message rsl_unused;
7631
7632 /* change Timeslot 6 before f_init() starts RSL */
7633 f_init_vty();
7634 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7635 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7636
7637 f_init(1, false);
7638 f_sleep(1.0);
7639
7640 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7641
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007642 log("TCH/F_TCH/H_PDCH pchan starts out in disabled mode:");
Harald Welte94e0c342018-04-07 11:33:23 +02007643 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7644 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007645 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007646
7647 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7648 f_sleep(1.0);
Neels Hofmeyrda4a6952018-06-14 04:02:49 +02007649 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 +02007650 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, PDCH_MODE);
7651
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007652 /* clean up config */
7653 f_ts_set_chcomb(0, 0, 6, "PDCH");
7654
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007655 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007656}
7657
7658/* Test Osmocom dyn PDCH activation NACK behavior */
7659testcase TC_dyn_pdch_osmo_act_nack() runs on test_CT {
7660 var RSL_Message rsl_unused;
7661
7662 /* change Timeslot 6 before f_init() starts RSL */
7663 f_init_vty();
7664 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
7665 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7666
7667 f_init(1, false);
7668 f_sleep(1.0);
7669
7670 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
7671
7672 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7673 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007674 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Harald Welte94e0c342018-04-07 11:33:23 +02007675
7676 /* NACK this activation and expect the "show timeslot" mode still to be NONE */
7677 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7678 f_sleep(1.0);
7679 f_ts_dyn_mode_assert(0, 0, chan_nr.tn, NONE_MODE);
7680
Neels Hofmeyr887e8f12018-06-27 01:01:55 +02007681 /* clean up config */
7682 f_ts_set_chcomb(0, 0, 6, "PDCH");
7683
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007684 f_shutdown_helper();
Harald Welte94e0c342018-04-07 11:33:23 +02007685}
7686
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007687/* Test Osmocom dyn TS SDCCH8 activation / deactivation */
7688testcase TC_dyn_ts_sdcch8_act_deact() runs on test_CT {
7689 var RSL_Message rsl_unused, rsl_msg;
7690 var DchanTuple dt;
7691 var BSSAP_N_CONNECT_ind rx_c_ind;
7692
7693 /* change Timeslot 6 before f_init() starts RSL */
7694 f_init_vty();
7695 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7696 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7697
7698 f_init(1, false);
7699 f_sleep(1.0);
7700
7701 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7702
7703 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7704 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7705 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007706 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007707
7708 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7709 f_sleep(1.0);
7710 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7711 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7712
7713 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7714 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007715 var DchanTuples sdcch_cleanup := {};
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007716 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007717 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007718 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007719 sdcch_cleanup := sdcch_cleanup & { dt };
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007720 }
7721
7722 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7723 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7724 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7725 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7726
7727 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7728 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7729
7730 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7731 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7732 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7733 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7734
7735 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7736 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7737 dt.sccp_conn_id := rx_c_ind.connectionId;
7738 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7739
7740 /* Instruct BSC to clear channel */
7741 var BssmapCause cause := 0;
7742 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7743 f_exp_chan_rel_and_clear(dt, 0);
7744
7745 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007746 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007747 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7748 f_sleep(1.0);
7749 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7750
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007751 /* Clean up SDCCH lchans */
7752 for (i := 0; i < lengthof(sdcch_cleanup); i := i + 1) {
7753 f_perform_clear_test_ct(sdcch_cleanup[i]);
7754 }
7755
Pau Espin Pedrol5b381082021-06-28 17:14:03 +02007756 /* clean up config */
7757 f_ts_set_chcomb(0, 0, 6, "PDCH");
7758
7759 f_shutdown_helper();
7760}
7761
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007762/* Validate all 8 subslots of a dynamics TS configured as SDCCH8 are used */
7763testcase TC_dyn_ts_sdcch8_all_subslots_used() runs on test_CT {
7764 var ASP_RSL_Unitdata rsl_ud;
7765 var integer i;
7766 var integer chreq_total, chreq_nochan;
7767
7768 f_init_vty();
7769 for (i := 1; i < 8; i := i + 1) {
7770 if (i == 2) {
7771 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7772 } else {
7773 f_ts_set_chcomb(0, 0, i, "PDCH");
7774 }
7775 }
7776 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7777
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007778 f_init(1, guard_timeout := 60.0);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007779
7780 /* The dyn TS want to activate PDCH mode, ACK that. */
7781 var RslChannelNr chan_nr;
7782 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007783 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007784 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
7785
7786 f_sleep(1.0);
7787
7788 /* Exhaust all dedicated SDCCH lchans.
7789 /* GSM 44.018 Table 9.1.8.2:
7790 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
7791 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007792 var DchanTuples chan_cleanup := {};
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007793 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007794 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007795 }
7796
7797 /* Only the dyn TS is still available. Its first lchan gets converted to SDCCH8 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007798 chan_cleanup := chan_cleanup & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007799 /* Also occupy the seven other SDCCH of the dyn TS */
7800 for (i := 0; i < 7; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007801 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
7802 }
7803
7804 /* Clean up SDCCH lchans */
7805 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7806 f_perform_clear_test_ct(chan_cleanup[i]);
Neels Hofmeyre1a7c4d2021-10-23 23:13:01 +02007807 }
7808
7809 /* clean up config */
7810 f_ts_reset_chcomb(0);
7811
7812 f_shutdown_helper();
7813}
7814
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007815/* Test Osmocom dyn TS SDCCH8 activation / deactivation: If activating dyn TS as
7816 SDCCH8 would end up in having no free TCH, then BSC should decide to activate
7817 it as TCH directly instead. SYS#5309. */
7818testcase TC_dyn_ts_sdcch8_tch_call_act_deact() runs on test_CT {
7819 var RSL_Message rsl_unused, rsl_msg;
7820 var DchanTuple dt;
7821 var BSSAP_N_CONNECT_ind rx_c_ind;
7822 var integer i;
7823
7824 /* change Timeslot 6 before f_init() starts RSL */
7825 f_init_vty();
7826 for (i := 1; i < 8; i := i + 1) {
7827 if (i == 6) {
7828 f_ts_set_chcomb(0, 0, i, "TCH/F_TCH/H_SDCCH8_PDCH");
7829 } else {
7830 f_ts_set_chcomb(0, 0, i, "PDCH");
7831 }
7832 }
7833 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7834
7835 f_init(1, false);
7836 f_sleep(1.0);
7837
7838 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7839
7840 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7841 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7842 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007843 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007844
7845 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7846 f_sleep(1.0);
7847 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7848 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7849
7850 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7851 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007852 var DchanTuples chan_cleanup := {};
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007853 var OCT1 ra := '43'O; /* RA containing reason=originating speech call*/
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007854 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007855 dt := f_est_dchan(ra, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007856 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007857 }
7858
7859 /* Now the dyn ts is selected. First PDCH is released, then TCH chan is activated */
Pau Espin Pedrol2ebbe7c2021-07-23 16:17:09 +02007860 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int(ra) + i, 1), 2342));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007861 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7862 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7863
7864 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7865 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7866
7867 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7868 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(dt.rsl_chan_nr, 2342));
7869 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7870 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, TCHH_MODE);
7871
7872 f_ipa_tx(0, ts_RSL_EST_IND(dt.rsl_chan_nr, valueof(ts_RslLinkID_DCCH(0)), '1234'O));
7873 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3('1234'O))) -> value rx_c_ind;
7874 dt.sccp_conn_id := rx_c_ind.connectionId;
7875 BSSAP.send(ts_BSSAP_CONNECT_res(dt.sccp_conn_id));
7876
7877 /* Instruct BSC to clear channel */
7878 var BssmapCause cause := 0;
7879 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
7880 f_exp_chan_rel_and_clear(dt, 0);
7881
7882 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007883 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007884 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7885 f_sleep(1.0);
7886 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7887
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007888 /* Clean up SDCCH lchans */
7889 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7890 f_perform_clear_test_ct(chan_cleanup[i]);
7891 }
7892
Pau Espin Pedrol0953bf82021-07-09 13:20:19 +02007893 /* clean up config */
7894 f_ts_reset_chcomb(0);
7895 /* TODO: clean up other channels? */
7896
7897 f_shutdown_helper();
7898}
7899
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007900/* Test Osmocom dyn TS SDCCH8 activation / deactivation when SDCCH fails at BTS */
7901testcase TC_dyn_ts_sdcch8_act_nack() runs on test_CT {
7902 var RSL_Message rsl_unused, rsl_msg;
7903 var DchanTuple dt;
7904 var BSSAP_N_CONNECT_ind rx_c_ind;
7905 var GsmRrMessage rr;
7906
7907 /* change Timeslot 6 before f_init() starts RSL */
7908 f_init_vty();
7909 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_SDCCH8_PDCH");
7910 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
7911
7912 f_init(1, false);
7913 f_sleep(1.0);
7914
7915 var RslChannelNr pdch_chan_nr := valueof(t_RslChanNr_PDCH(6));
7916
7917 log("TCH/F_TCH/H_SDCCH8_PDCH pchan starts out in disabled mode:");
7918 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, NONE_MODE);
7919 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007920 rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007921
7922 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7923 f_sleep(1.0);
7924 log("TCH/F_TCH/H_SDCCH8_PDC requested to PDCH ACT on startup, which was ACKed, so now in PDCH:");
7925 f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE);
7926
7927 /* Fill TS0 SDCCH channels (NOTE: only 3 SDCCH/4 channels are available
7928 * on CCCH+SDCCH4+CBCH) */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007929 var DchanTuples chan_cleanup := {};
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007930 var integer i;
Pau Espin Pedrolce4d5bb2021-10-25 13:31:25 +02007931 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i + 1) {
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007932 dt := f_est_dchan('23'O, i, '00010203040506'O);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007933 chan_cleanup := chan_cleanup & { dt };
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007934 }
7935
7936 /* Now the dyn ts is selected. First PDCH is released, then sdcch chan is activated */
7937 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(oct2int('23'O) + i, 1), 2342));
7938 rsl_unused := f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(pdch_chan_nr));
7939 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(pdch_chan_nr));
7940
7941 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
7942 dt.rsl_chan_nr := rsl_msg.ies[0].body.chan_nr;
7943
7944 f_ts_dyn_mode_assert(0, 0, dt.rsl_chan_nr.tn, SDCCH8_MODE);
7945 f_ipa_tx(0, ts_RSL_CHAN_ACT_NACK(dt.rsl_chan_nr, RSL_ERR_EQUIPMENT_FAIL));
7946 rsl_msg := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
7947 rr := dec_GsmRrMessage(rsl_msg.ies[1].body.full_imm_ass_info.payload);
7948 if (rr.header.message_type != IMMEDIATE_ASSIGNMENT_REJECT) {
7949 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Expected reject");
7950 }
7951
7952 /* FIXME? Currently the TS stays in state BORKEN: */
7953
7954 /* The BSC will switch the TS back to PDCH once the only lchan using it is released: */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +06007955 /* rsl_unused := f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(pdch_chan_nr));
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007956 * f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(pdch_chan_nr, 2342));
7957 * f_sleep(1.0);
7958 * f_ts_dyn_mode_assert(0, 0, pdch_chan_nr.tn, PDCH_MODE)
7959 */
7960
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01007961 /* Clean up SDCCH lchans */
7962 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
7963 f_perform_clear_test_ct(chan_cleanup[i]);
7964 }
7965
Pau Espin Pedrolcdf26142021-06-28 17:14:03 +02007966 /* clean up config */
7967 f_ts_set_chcomb(0, 0, 6, "PDCH");
7968
7969 f_shutdown_helper();
7970}
7971
Stefan Sperling0796a822018-10-05 13:01:39 +02007972testcase TC_chopped_ipa_ping() runs on test_CT {
Stefan Sperling554123f2018-10-09 14:12:30 +02007973 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port, mp_bsc_ctrl_port};
Stefan Sperling0796a822018-10-05 13:01:39 +02007974 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7975 IPA_Testing.f_run_TC_chopped_ipa_ping(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7976 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007977 f_shutdown_helper();
Stefan Sperling0796a822018-10-05 13:01:39 +02007978}
7979
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007980testcase TC_chopped_ipa_payload() runs on test_CT {
7981 const Integers bsc_ipa_ports := {mp_bsc_rsl_port, mp_bsc_oml_port
7982 /* TODO: mp_bsc_ctrl_port does not work yet */};
7983 for (var integer i := 0; i < lengthof(bsc_ipa_ports); i := i + 1) {
7984 IPA_Testing.f_run_TC_chopped_ipa_payload(mp_bsc_ip, bsc_ipa_ports[i], CONNECT_TO_SERVER);
7985 }
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02007986 f_shutdown_helper();
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02007987}
7988
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01007989/* Verify the BSC sends the MS Power Parameters IE during CHAN ACT to make sure
7990 the BTS does autonomous MS power control loop */
7991testcase TC_assignment_verify_ms_power_params_ie() runs on test_CT {
7992 var MSC_ConnHdlr vc_conn;
7993 var TestHdlrParams pars := f_gen_test_hdlr_pars();
7994 //pars.encr := valueof(t_EncrParams('01'O, f_rnd_octstring(8)));
7995 pars.exp_ms_power_params := true;
7996
7997 f_init(1, true);
7998 f_sleep(1.0);
7999 vc_conn := f_start_handler(refers(f_tc_assignment_fr_a5), pars);
8000 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008001 f_shutdown_helper();
Pau Espin Pedrol8f773632019-11-05 11:46:53 +01008002}
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +02008003
Vadim Yanitskiy4b233042021-06-30 00:58:43 +02008004/* Verify activation and deactivation of the BCCH carrier power reduction mode */
8005testcase TC_c0_power_red_mode() runs on test_CT {
8006 f_init(1);
8007
8008 for (var integer red := 6; red >= 0; red := red - 2) {
8009 /* Configure BCCH carrier power reduction mode via the VTY */
8010 f_vty_transceive(BSCVTY, "bts 0 c0-power-reduction " & int2str(red));
8011
8012 /* Expect Osmocom specific BS Power Control message on the RSL */
8013 var template RSL_Message tr_rsl_pdu := tr_RSL_BS_PWR_CTRL(
8014 chan_nr := t_RslChanNr_BCCH(0),
8015 bs_power := tr_RSL_IE_BS_Power(red / 2));
8016 tr_rsl_pdu.msg_disc := tr_RSL_MsgDisc(RSL_MDISC_CCHAN, false);
8017 var RSL_Message unused := f_exp_ipa_rx(0, tr_rsl_pdu);
8018
8019 /* Additionally verify the applied value over the CTRL interface */
8020 var CtrlValue cred := f_ctrl_get_bts(IPA_CTRL, 0, "c0-power-reduction");
8021 if (cred != int2str(red)) {
8022 setverdict(fail, "Unexpected BCCH carrier power reduction value ",
8023 cred, " (expected ", red, ")");
8024 }
8025 }
8026
8027 f_shutdown_helper();
8028}
8029
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008030/***********************************************************************
8031 * MSC Pooling
8032 ***********************************************************************/
8033
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008034template MobileIdentityLV ts_MI_TMSI_NRI_LV(integer nri_v, integer nri_bitlen := 10) :=
Harald Weltebf397612021-01-14 20:39:46 +01008035 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 +02008036
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008037private 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 +02008038runs on MSC_ConnHdlr {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008039 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008040 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008041 f_logp(BSCVTY, "Got RSL RR Release");
8042 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008043 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008044 f_logp(BSCVTY, "Got RSL Deact SACCH");
8045 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008046 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008047 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008048 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8049 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02008050 break;
8051 }
8052 }
8053}
8054
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008055private altstep as_mgcp_ack_all_dlcx() runs on MSC_ConnHdlr {
8056 var MgcpCommand mgcp_cmd;
8057 [] MGCP.receive(tr_DLCX(?)) -> value mgcp_cmd {
8058 MGCP.send(ts_DLCX_ACK2(mgcp_cmd.line.trans_id));
8059 repeat;
8060 }
8061}
8062
8063private altstep as_rsl_ack_all_rel_req() runs on MSC_ConnHdlr {
8064 var RslLinkId main_dcch := valueof(ts_RslLinkID_DCCH(0));
8065 [] RSL.receive(tr_RSL_REL_REQ(g_chan_nr, ?)) {
8066 RSL.send(ts_RSL_REL_CONF(g_chan_nr, main_dcch));
8067 repeat;
8068 }
8069}
8070
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008071friend function f_perform_clear(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC,
8072 template PDU_ML3_NW_MS exp_rr_rel_tmpl := tr_RRM_RR_RELEASE)
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +02008073runs on MSC_ConnHdlr {
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008074 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8075 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008076 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008077 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8078 interleave {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008079 [] rsl_pt.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch exp_rr_rel_tmpl)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008080 f_logp(BSCVTY, "Got RSL RR Release");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008081 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008082 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008083 f_logp(BSCVTY, "Got RSL Deact SACCH");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008084 }
8085 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008086 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008087 /* Also drop the SCCP connection */
8088 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8089 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +02008090 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008091 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008092 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8093 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008094 }
8095 }
Neels Hofmeyr6289af12021-12-16 18:17:49 +01008096 deactivate(ack_dlcx);
8097 deactivate(ack_rel_req);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008098}
8099
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008100friend function f_perform_clear_no_rr_rel(RSL_DCHAN_PT rsl_pt := RSL, RSLEM_PROC_PT rsl_proc_pt := RSL_PROC)
8101runs on MSC_ConnHdlr {
8102 var default ack_dlcx := activate(as_mgcp_ack_all_dlcx());
8103 var default ack_rel_req := activate(as_rsl_ack_all_rel_req());
8104 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8105 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8106 interleave {
8107 [] rsl_pt.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
8108 f_logp(BSCVTY, "Got RSL Deact SACCH");
8109 }
8110 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
8111 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8112 /* Also drop the SCCP connection */
8113 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8114 }
8115 [] rsl_pt.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
8116 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
8117 rsl_pt.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
8118 f_rslem_unregister(0, g_chan_nr, PT := rsl_proc_pt);
8119 }
8120 }
8121 deactivate(ack_dlcx);
8122 deactivate(ack_rel_req);
8123}
8124
Neels Hofmeyr907b23b2022-02-17 21:58:47 +01008125friend function f_perform_clear_no_lchan()
8126runs on MSC_ConnHdlr {
8127 f_logp(BSCVTY, "MSC instructs BSC to clear channel");
8128 BSSAP.send(ts_BSSMAP_ClearCommand(0));
8129 BSSAP.receive(tr_BSSMAP_ClearComplete);
8130 f_logp(BSCVTY, "Got BSSMAP Clear Complete");
8131 /* Also drop the SCCP connection */
8132 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
8133}
8134
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008135private function f_perform_clear_test_ct(DchanTuple dt)
8136 runs on test_CT
8137{
8138 /* Instruct BSC to clear channel */
8139 var BssmapCause cause := 0;
8140 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
8141 f_exp_chan_rel_and_clear(dt, 0);
8142}
8143
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008144private function f_perform_compl_l3(RSL_DCHAN_PT rsl_pt, RSLEM_PROC_PT rsl_proc_pt,
8145 template PDU_ML3_MS_NW l3_info, boolean do_clear := true, boolean expect_bssmap_l3 := true)
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008146runs on MSC_ConnHdlr {
8147 timer T := 10.0;
8148 var octetstring l3_enc := enc_PDU_ML3_MS_NW(valueof(l3_info));
8149
Neels Hofmeyr767548a2020-08-09 20:26:07 +00008150 f_logp(BSCVTY, "establish channel, send Complete Layer 3 Info");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008151 f_create_bssmap_exp(l3_enc);
8152
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008153 /* RSL_Emulation.f_chan_est() on rsl_pt:
8154 * This is basically code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008155 * RSL_Emulation.f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
8156 */
8157 var RSL_Message rx_rsl;
8158 var GsmRrMessage rr;
8159
8160 /* request a channel to be established */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008161 rsl_pt.send(ts_RSLDC_ChanRqd(g_pars.ra, g_pars.fn));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008162 /* expect immediate assignment.
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008163 * Code dup with s/RSL/rsl_pt from:
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008164 * rx_rsl := f_rx_or_fail(tr_RSL_IMM_ASSIGN);
8165 */
8166 timer Tt := 10.0;
8167
8168 /* request a channel to be established */
8169 Tt.start;
8170 alt {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008171 [] rsl_pt.receive(tr_RSL_IMM_ASSIGN) -> value rx_rsl {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008172 Tt.stop;
8173 }
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008174 [] rsl_pt.receive {
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008175 setverdict(fail, "Unexpected RSL message on DCHAN");
8176 mtc.stop;
8177 }
8178 [] Tt.timeout {
8179 setverdict(fail, "Timeout waiting for RSL on DCHAN");
8180 mtc.stop;
8181 }
8182 }
8183 rr := dec_GsmRrMessage(rx_rsl.ies[1].body.full_imm_ass_info.payload);
8184 g_chan_nr := rr.payload.imm_ass.chan_desc.chan_nr;
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008185 rsl_pt.send(ts_RSL_EST_IND(g_chan_nr, valueof(g_pars.link_id), l3_enc));
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008186
8187
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008188 if (expect_bssmap_l3) {
8189 f_logp(BSCVTY, "expect BSSAP Complete Layer 3 Info at MSC");
8190 var template PDU_BSSAP exp_l3_compl;
8191 exp_l3_compl := tr_BSSMAP_ComplL3()
8192 if (g_pars.aoip == false) {
8193 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := omit;
8194 } else {
8195 exp_l3_compl.pdu.bssmap.completeLayer3Information.codecList := ?;
8196 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008197
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008198 var PDU_BSSAP bssap;
8199 T.start;
8200 alt {
8201 [] BSSAP.receive(exp_l3_compl) -> value bssap {
8202 f_logp(BSCVTY, "received expected Complete Layer 3 Info at MSC");
8203 log("rx exp_l3_compl = ", bssap);
8204 }
8205 [] BSSAP.receive(tr_BSSMAP_ComplL3) {
8206 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Received non-matching COMPLETE LAYER 3 INFORMATION");
8207 }
8208 [] T.timeout {
8209 Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, "Timeout waiting for COMPLETE LAYER 3 INFORMATION");
8210 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008211 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008212
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008213 /* start ciphering, if requested */
8214 if (ispresent(g_pars.encr)) {
8215 f_logp(BSCVTY, "start ciphering");
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008216 f_cipher_mode(g_pars.encr, rsl_pt := rsl_pt, rsl_proc_pt := rsl_proc_pt);
Neels Hofmeyr66e15092020-10-12 18:44:41 +00008217 }
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008218 }
8219
8220 if (do_clear) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008221 f_perform_clear(rsl_pt, rsl_proc_pt);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008222 }
8223 setverdict(pass);
8224 f_sleep(1.0);
8225}
8226
8227private function f_tc_mscpool_compl_l3(charstring id) runs on MSC_ConnHdlr {
8228 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8229 if (g_pars.mscpool.rsl_idx == 0) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008230 f_perform_compl_l3(RSL, RSL_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008231 } else if (g_pars.mscpool.rsl_idx == 1) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008232 f_perform_compl_l3(RSL1, RSL1_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008233 } else if (g_pars.mscpool.rsl_idx == 2) {
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008234 f_perform_compl_l3(RSL2, RSL2_PROC, g_pars.mscpool.l3_info);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008235 }
8236}
8237
8238/* Various Complete Layer 3 by IMSI all end up with the first MSC, because the other MSCs are not connected. */
8239private function f_tc_mscpool_L3Compl_on_1_msc(charstring id) runs on MSC_ConnHdlr {
8240 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008241 f_perform_compl_l3(RSL, RSL_PROC, ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O) );
8242 f_perform_compl_l3(RSL, RSL_PROC, ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_IMSI_LV('001010000000002'H))) );
8243 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))) );
8244 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 +02008245}
8246testcase TC_mscpool_L3Compl_on_1_msc() runs on test_CT {
8247
8248 f_init(1, true);
8249 f_sleep(1.0);
8250 var MSC_ConnHdlr vc_conn;
8251 var TestHdlrParams pars := f_gen_test_hdlr_pars();
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008252
8253 f_ctrs_msc_init();
8254
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008255 vc_conn := f_start_handler(refers(f_tc_mscpool_L3Compl_on_1_msc), pars);
8256 vc_conn.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008257
8258 f_ctrs_msc_expect(0, "mscpool:subscr:new", 4);
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008259 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008260}
8261
8262/* Three Layer 3 Complete by IMSI are round-robin'ed across two connected MSCs */
8263/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8264 * just as well using only RSL. */
8265testcase TC_mscpool_L3Complete_by_imsi_round_robin() runs on test_CT {
8266
8267 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8268 f_sleep(1.0);
8269
8270 /* Control which MSC gets chosen next by the round-robin, otherwise
8271 * would be randomly affected by which other tests ran before this. */
8272 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8273
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008274 f_ctrs_msc_init();
8275
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008276 var MSC_ConnHdlr vc_conn1;
8277 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8278 pars1.mscpool.rsl_idx := 0;
8279 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8280 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8281 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008282 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008283
8284 var MSC_ConnHdlr vc_conn2;
8285 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8286 pars2.mscpool.rsl_idx := 1;
8287 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8288 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8289 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008290 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008291
8292 /* Test round-robin wrap to the first MSC */
8293 var MSC_ConnHdlr vc_conn3;
8294 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8295 pars3.mscpool.rsl_idx := 2;
8296 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8297 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8298 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008299 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008300 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008301}
8302
8303/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 0
8304 * (configured in osmo-bsc.cfg). */
8305/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8306 * just as well using only RSL. */
8307testcase TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() runs on test_CT {
8308
8309 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8310 f_sleep(1.0);
8311
8312 /* Control which MSC gets chosen next by the round-robin, otherwise
8313 * would be randomly affected by which other tests ran before this. */
8314 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8315
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008316 f_ctrs_msc_init();
8317
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008318 var MSC_ConnHdlr vc_conn1;
8319 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8320 pars1.mscpool.rsl_idx := 0;
8321 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8322 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8323 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008324 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008325
8326 var MSC_ConnHdlr vc_conn2;
8327 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8328 pars2.mscpool.rsl_idx := 1;
8329 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8330 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8331 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008332 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008333
8334 /* Test round-robin wrap to the first MSC */
8335 var MSC_ConnHdlr vc_conn3;
8336 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8337 pars3.mscpool.rsl_idx := 2;
8338 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(0)), '00F110'O));
8339 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8340 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008341 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008342 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008343}
8344
8345/* Three LU by TMSI are round-robin'ed across two connected MSCs, because they contain the NULL-NRI 1
8346 * (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
8347 * NULL-NRI setting is stronger than that. */
8348/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8349 * just as well using only RSL. */
8350testcase TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() runs on test_CT {
8351
8352 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8353 f_sleep(1.0);
8354
8355 /* Control which MSC gets chosen next by the round-robin, otherwise
8356 * would be randomly affected by which other tests ran before this. */
8357 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8358
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008359 f_ctrs_msc_init();
8360
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008361 var MSC_ConnHdlr vc_conn1;
8362 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8363 pars1.mscpool.rsl_idx := 0;
8364 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8365 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8366 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008367 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008368
8369 var MSC_ConnHdlr vc_conn2;
8370 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8371 pars2.mscpool.rsl_idx := 1;
8372 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8373 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8374 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008375 f_ctrs_msc_expect(1, "mscpool:subscr:reattach");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008376
8377 /* Test round-robin wrap to the first MSC */
8378 var MSC_ConnHdlr vc_conn3;
8379 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8380 pars3.mscpool.rsl_idx := 2;
8381 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(1)), '00F110'O));
8382 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8383 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008384 f_ctrs_msc_expect(0, "mscpool:subscr:reattach");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008385 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008386}
8387
8388/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI not
8389 * assigned to any MSC (configured in osmo-bsc.cfg). */
8390/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8391 * just as well using only RSL. */
8392testcase TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() runs on test_CT {
8393
8394 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8395 f_sleep(1.0);
8396
8397 /* Control which MSC gets chosen next by the round-robin, otherwise
8398 * would be randomly affected by which other tests ran before this. */
8399 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8400
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008401 f_ctrs_msc_init();
8402
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008403 var MSC_ConnHdlr vc_conn1;
8404 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8405 pars1.mscpool.rsl_idx := 0;
8406 /* An NRI that is not assigned to any MSC */
8407 pars1.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(1023))));
8408 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8409 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008410 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008411
8412 var MSC_ConnHdlr vc_conn2;
8413 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8414 pars2.mscpool.rsl_idx := 1;
8415 /* An NRI that is not assigned to any MSC */
8416 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(768)), '00F110'O));
8417 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8418 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008419 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008420
8421 /* Test round-robin wrap to the first MSC */
8422 var MSC_ConnHdlr vc_conn3;
8423 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8424 pars3.mscpool.rsl_idx := 2;
8425 /* An NRI that is not assigned to any MSC */
8426 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_SS_ACT, valueof(ts_MI_TMSI_NRI_LV(819))));
8427 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8428 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008429 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008430 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008431}
8432
8433/* Three Layer 3 Complete by TMSI are round-robin'ed across two connected MSCs, because they contain an NRI
8434 * assigned to an MSC that is currently not connected (configured in osmo-bsc.cfg). */
8435/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8436 * just as well using only RSL. */
8437testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() runs on test_CT {
8438
8439 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8440 f_sleep(1.0);
8441
8442 /* Control which MSC gets chosen next by the round-robin, otherwise
8443 * would be randomly affected by which other tests ran before this. */
8444 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8445
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008446 f_ctrs_msc_init();
8447
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008448 var MSC_ConnHdlr vc_conn1;
8449 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8450 pars1.mscpool.rsl_idx := 0;
8451 /* An NRI that is assigned to an unconnected MSC */
8452 pars1.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(512))));
8453 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8454 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008455 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8456 f_ctrs_msc_add(0, "mscpool:subscr:new");
8457 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008458
8459 var MSC_ConnHdlr vc_conn2;
8460 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8461 pars2.mscpool.rsl_idx := 1;
8462 /* An NRI that is assigned to an unconnected MSC */
8463 pars2.mscpool.l3_info := valueof(ts_ML3_MO_MM_IMSI_DET_Ind(valueof(ts_MI_TMSI_NRI_LV(767))));
8464 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8465 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008466 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8467 f_ctrs_msc_add(1, "mscpool:subscr:new");
8468 f_ctrs_msc_verify();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008469
8470 /* Test round-robin wrap to the first MSC */
8471 var MSC_ConnHdlr vc_conn3;
8472 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8473 pars3.mscpool.rsl_idx := 2;
8474 /* An NRI that is assigned to an unconnected MSC */
8475 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(750)), '00F110'O));
8476 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8477 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008478 f_ctrs_msc_add(2, "mscpool:subscr:attach_lost");
8479 f_ctrs_msc_add(0, "mscpool:subscr:new");
8480 f_ctrs_msc_verify();
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008481 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008482}
8483
8484/* Three Layer 3 Complete by TMSI with valid NRI for the second MSC are all directed to the second MSC (configured in
8485 * osmo-bsc.cfg). */
8486/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8487 * just as well using only RSL. */
8488testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_1() runs on test_CT {
8489
8490 f_init(nr_bts := 3, handler_mode := true, nr_msc := 2);
8491 f_sleep(1.0);
8492
8493 /* All TMSIs in this test point at the second MSC, set the round robin to point at the first MSC to make sure
8494 * this is not using round-robin. */
8495 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8496
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008497 f_ctrs_msc_init();
8498
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008499 var MSC_ConnHdlr vc_conn1;
8500 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8501 pars1.mscpool.rsl_idx := 0;
8502 /* An NRI of the second MSC's range (256-511) */
8503 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(256))));
8504 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8505 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008506 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008507
8508 var MSC_ConnHdlr vc_conn2;
8509 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 1);
8510 pars2.mscpool.rsl_idx := 1;
8511 /* An NRI of the second MSC's range (256-511) */
8512 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(260))));
8513 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8514 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008515 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008516
8517 var MSC_ConnHdlr vc_conn3;
8518 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8519 pars3.mscpool.rsl_idx := 2;
8520 /* An NRI of the second MSC's range (256-511) */
8521 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(511)), '00F110'O));
8522 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8523 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008524 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008525 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008526}
8527
8528/* Layer 3 Complete by TMSI with valid NRI for the third MSC are directed to the third MSC (configured in osmo-bsc.cfg),
8529 * while a round-robin remains unaffected by that. */
8530/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8531 * just as well using only RSL. */
8532testcase TC_mscpool_L3Complete_by_tmsi_valid_nri_2() runs on test_CT {
8533
8534 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8535 f_sleep(1.0);
8536
8537 /* All TMSIs in this test point at the third MSC, set the round robin to point at the second MSC to make sure
8538 * this is not using round-robin. */
8539 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8540
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008541 f_ctrs_msc_init();
8542
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008543 var MSC_ConnHdlr vc_conn1;
8544 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 2);
8545 pars1.mscpool.rsl_idx := 0;
8546 /* An NRI of the third MSC's range (512-767) */
8547 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_SMS, valueof(ts_MI_TMSI_NRI_LV(512))));
8548 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8549 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008550 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008551
8552 var MSC_ConnHdlr vc_conn2;
8553 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8554 pars2.mscpool.rsl_idx := 1;
8555 /* An NRI of the third MSC's range (512-767) */
8556 pars2.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_TMSI_NRI_LV(678))));
8557 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8558 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008559 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008560
8561 /* The above forwardings to third MSC have not affected the round robin, which still points at the second MSC */
8562 var MSC_ConnHdlr vc_conn3;
8563 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 1);
8564 pars3.mscpool.rsl_idx := 2;
8565 pars3.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000013'H)), '00F110'O));
8566 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8567 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008568 f_ctrs_msc_expect(1, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008569 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008570}
8571
8572/* LU with a TMSI but indicating a different PLMN in its previous LAI: ignore the NRI. */
8573/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8574 * just as well using only RSL. */
8575testcase TC_mscpool_LU_by_tmsi_from_other_PLMN() runs on test_CT {
8576
8577 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8578 f_sleep(1.0);
8579
8580 /* The TMSIs in this test points at the second MSC, but since it is from a different PLMN, round-robin is used
8581 * instead, and hits msc 0. */
8582 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8583
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008584 f_ctrs_msc_init();
8585
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008586 /* An NRI of the second MSC's range (256-511), but a PLMN that doesn't match with osmo-bsc.cfg */
8587 var MSC_ConnHdlr vc_conn1;
8588 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8589 pars1.mscpool.rsl_idx := 0;
8590 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(260)), '99F999'O));
8591 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8592 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008593 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008594
8595 /* An NRI of the third MSC's range (512-767) and a matching PLMN gets directed by NRI. */
8596 var MSC_ConnHdlr vc_conn2;
8597 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8598 pars2.mscpool.rsl_idx := 1;
8599 pars2.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_TMSI_NRI_LV(555)), '00F110'O));
8600 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8601 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008602 f_ctrs_msc_expect(2, "mscpool:subscr:known");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008603 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008604}
8605
8606/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by IMSI, which would be
8607 * round-robined to another MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8608private function f_tc_mscpool_paging_imsi(charstring id) runs on MSC_ConnHdlr {
8609 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8610 //cid_list := { cIl_allInBSS := ''O };
8611 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8612 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8613 var BSSAP_N_UNITDATA_req paging;
8614 var hexstring imsi := '001010000000123'H;
8615
8616 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8617
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008618 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008619 valueof(ts_BSSMAP_Paging(imsi, cid_list, omit, bssmap_chneed))));
8620 BSSAP.send(paging);
8621
8622 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8623 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8624 * channel number is picked here. */
8625 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8626 f_rslem_register(0, new_chan_nr);
8627 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(imsi)));
8628 f_rslem_unregister(0, new_chan_nr);
8629
8630 /* Despite the round robin pointing at the second MSC ('roundrobin next 1'), the earlier Paging for the same IMSI
8631 * causes this Paging Response to go to the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008632 f_perform_compl_l3(RSL, RSL_PROC, ts_PAG_RESP(valueof(ts_MI_IMSI_LV(imsi))) );
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008633 f_sleep(1.0);
8634}
8635testcase TC_mscpool_paging_and_response_imsi() runs on test_CT {
8636 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8637 f_sleep(1.0);
8638
8639 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8640 * second MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8641 f_vty_transceive(BSCVTY, "mscpool roundrobin next 1");
8642
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008643 f_ctrs_msc_init();
8644
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008645 var MSC_ConnHdlr vc_conn1;
8646 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8647 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008648 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8649 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008650 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_imsi), pars1);
8651 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008652 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008653 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008654}
8655
8656/* Make sure that whichever MSC paged a subscriber will also get the Paging Response. Page by TMSI with an NRI value
8657 * that matches a different MSC, to make sure the Paging->Response relation is stronger than the NRI->MSC mapping. */
8658private function f_tc_mscpool_paging_tmsi(charstring id) runs on MSC_ConnHdlr {
8659 var template BSSMAP_FIELD_CellIdentificationList cid_list := { cIl_CI := { ts_BSSMAP_CI_CI(0) } };
8660 //cid_list := { cIl_allInBSS := ''O };
8661 var RSL_ChanNeeded rsl_chneed := RSL_CHANNEED_SDCCH;
8662 var template BSSMAP_IE_ChannelNeeded bssmap_chneed := ts_BSSMAP_IE_ChanNeeded(int2bit(enum2int(valueof(rsl_chneed)),2));
8663 var integer nri_v := 300; /* <-- second MSC's NRI */
Harald Weltebf397612021-01-14 20:39:46 +01008664 var octetstring tmsi := f_gen_tmsi(suffix := 0, nri_v := nri_v);
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008665 var BSSAP_N_UNITDATA_req paging;
8666
8667 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
8668
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008669 paging := valueof(ts_BSSAP_UNITDATA_req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008670 valueof(ts_BSSMAP_Paging('001010000000011'H, cid_list, tmsi, bssmap_chneed))));
8671 BSSAP.send(paging);
8672
8673 /* Register any RSL conn so that the Paging Command gets received here. With the current RSL_Emulation's main()
8674 * handling of '[bts_role] IPA_PT.receive(tr_ASP_RSL_UD(tr_RSL_PAGING_CMD()))' it doesn't matter at all which
8675 * channel number is picked here. */
8676 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(0, RSL_CHAN_NR_INVALID));
8677 f_rslem_register(0, new_chan_nr);
8678 RSL.receive(tr_RSL_PAGING_CMD(t_MI_TMSI(tmsi)));
8679 f_rslem_unregister(0, new_chan_nr);
8680
8681 /* Despite the NRI matching the second MSC (NRI from 'msc 1' in osmo-bsc.cfg) and round robin pointing at the
8682 * third MSC ('roundrobin next 2'), the earlier Paging for the same TMSI causes this Paging Response to go to
8683 * the first MSC (bssap_idx := 0). */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02008684 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 +02008685 f_sleep(1.0);
8686}
8687testcase TC_mscpool_paging_and_response_tmsi() runs on test_CT {
8688 f_init(nr_bts := 1, handler_mode := true, nr_msc := 3);
8689 f_sleep(1.0);
8690
8691 /* Testing a Paging on the first MSC to get a Paging Response back to the first MSC. Set round robin to the
8692 * third MSC to make sure we're getting the Paging logic, not a coincidental round robin match. */
8693 f_vty_transceive(BSCVTY, "mscpool roundrobin next 2");
8694
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008695 f_ctrs_msc_init();
8696
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008697 var MSC_ConnHdlr vc_conn1;
8698 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8699 pars1.mscpool.rsl_idx := 0;
Neels Hofmeyr90f80962020-06-12 16:16:55 +02008700 pars1.sccp_addr_bsc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_peer;
8701 pars1.sccp_addr_msc := g_bssap[pars1.mscpool.bssap_idx].sccp_addr_own;
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008702 vc_conn1 := f_start_handler(refers(f_tc_mscpool_paging_tmsi), pars1);
8703 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008704 f_ctrs_msc_expect(0, "mscpool:subscr:paged");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008705 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008706}
8707
8708/* For round-robin, skip an MSC that has 'no allow-attach' set. */
8709/* FIXME: each run is using a separate RSLem: RSL, RSL1, RSL2. It should work
8710 * just as well using only RSL. */
8711testcase TC_mscpool_no_allow_attach_round_robin() runs on test_CT {
8712
8713 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8714 f_sleep(1.0);
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008715 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8716 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008717
8718 /* Control which MSC gets chosen next by the round-robin, otherwise
8719 * would be randomly affected by which other tests ran before this. */
8720 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8721
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008722 f_ctrs_msc_init();
8723
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008724 var MSC_ConnHdlr vc_conn1;
8725 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 0);
8726 pars1.mscpool.rsl_idx := 0;
8727 pars1.mscpool.l3_info := valueof(ts_LU_REQ(LU_Type_IMSI_Attach, valueof(ts_MI_IMSI_LV('001010000000001'H)), '00F110'O));
8728 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8729 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008730 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008731
8732 var MSC_ConnHdlr vc_conn2;
8733 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 2);
8734 pars2.mscpool.rsl_idx := 1;
8735 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8736 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8737 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008738 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008739
8740 var MSC_ConnHdlr vc_conn3;
8741 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 0);
8742 pars3.mscpool.rsl_idx := 2;
8743 pars3.mscpool.l3_info := valueof(ts_PAG_RESP(valueof(ts_MI_IMSI_LV('001010000000003'H))));
8744 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8745 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008746 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008747 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008748}
8749
8750/* An MSC that has 'no allow-attach' set should still serve subscribers that are already attached according to their
8751 * TMSI NRI. */
8752testcase TC_mscpool_no_allow_attach_valid_nri() runs on test_CT {
8753
8754 f_init(nr_bts := 3, handler_mode := true, nr_msc := 3);
8755 f_sleep(1.0);
8756
Neels Hofmeyra460f1f2020-08-09 20:17:03 +00008757 /* Mark the second MSC as offloading, round-robin should skip this MSC now. */
8758 f_vty_msc_allow_attach(BSCVTY, {true, false, true});
8759
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008760 /* Control which MSC gets chosen next by the round-robin, otherwise
8761 * would be randomly affected by which other tests ran before this. */
8762 f_vty_transceive(BSCVTY, "mscpool roundrobin next 0");
8763
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008764 f_ctrs_msc_init();
8765
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008766 /* Round robin points at msc 0, but the valid NRI directs to msc 1, even though msc 1 has 'no allow-attach'. */
8767 var MSC_ConnHdlr vc_conn1;
8768 var TestHdlrParams pars1 := f_gen_test_hdlr_pars(bssap_idx := 1);
8769 pars1.mscpool.rsl_idx := 0;
8770 /* An NRI of the second MSC's range (256-511) */
8771 pars1.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_TMSI_NRI_LV(260))));
8772 vc_conn1 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars1);
8773 vc_conn1.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008774 f_ctrs_msc_expect(1, "mscpool:subscr:known");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008775
8776 var MSC_ConnHdlr vc_conn2;
8777 var TestHdlrParams pars2 := f_gen_test_hdlr_pars(bssap_idx := 0);
8778 pars2.mscpool.rsl_idx := 1;
8779 pars2.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000002'H))));
8780 vc_conn2 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars2);
8781 vc_conn2.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008782 f_ctrs_msc_expect(0, "mscpool:subscr:new");
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008783
8784 var MSC_ConnHdlr vc_conn3;
8785 var TestHdlrParams pars3 := f_gen_test_hdlr_pars(bssap_idx := 2);
8786 pars3.mscpool.rsl_idx := 2;
8787 pars3.mscpool.l3_info := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, valueof(ts_MI_IMSI_LV('001010000000003'H))));
8788 vc_conn3 := f_start_handler(refers(f_tc_mscpool_compl_l3), pars3);
8789 vc_conn3.done;
Neels Hofmeyr22c3f792020-06-17 02:49:28 +02008790 f_ctrs_msc_expect(2, "mscpool:subscr:new");
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008791 f_shutdown_helper();
Neels Hofmeyr4f118412020-06-04 15:25:10 +02008792}
8793
Philipp Maier783681c2020-07-16 16:47:06 +02008794/* Allow/Deny emergency calls globally via VTY */
8795private function f_vty_allow_emerg_msc(boolean allow) runs on test_CT {
8796 f_vty_enter_cfg_msc(BSCVTY, 0);
8797 if (allow) {
8798 f_vty_transceive(BSCVTY, "allow-emergency allow");
8799 } else {
8800 f_vty_transceive(BSCVTY, "allow-emergency deny");
8801 }
8802 f_vty_transceive(BSCVTY, "exit");
8803 f_vty_transceive(BSCVTY, "exit");
8804}
8805
8806/* Allow/Deny emergency calls per BTS via VTY */
8807private function f_vty_allow_emerg_bts(boolean allow, integer bts_nr) runs on test_CT {
8808 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8809 if (allow) {
8810 f_vty_transceive(BSCVTY, "rach emergency call allowed 1");
8811 } else {
8812 f_vty_transceive(BSCVTY, "rach emergency call allowed 0");
8813 }
8814 f_vty_transceive(BSCVTY, "exit");
8815 f_vty_transceive(BSCVTY, "exit");
Neels Hofmeyrb6ed80c2020-10-12 22:52:39 +00008816 f_vty_transceive(BSCVTY, "exit");
Philipp Maier783681c2020-07-16 16:47:06 +02008817}
8818
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +02008819/* Allow/Forbid Fast Return after SRVCC on a given BTS via VTY */
8820private function f_vty_allow_srvcc_fast_return(boolean allow, integer bts_nr) runs on test_CT {
8821 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8822 if (allow) {
8823 f_vty_transceive(BSCVTY, "srvcc fast-return allow");
8824 } else {
8825 f_vty_transceive(BSCVTY, "srvcc fast-return forbid");
8826 }
8827 f_vty_transceive(BSCVTY, "exit");
8828 f_vty_transceive(BSCVTY, "exit");
8829 f_vty_transceive(BSCVTY, "exit");
8830}
8831
Pau Espin Pedrol14475352021-07-22 15:48:16 +02008832/* Allow/Forbid TCH for signalling if SDCCH exhausted on a given BTS via VTY */
8833private function f_vty_allow_tch_for_signalling(boolean allow, integer bts_nr) runs on test_CT {
8834 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
8835 if (allow) {
8836 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 1");
8837 } else {
8838 f_vty_transceive(BSCVTY, "channel allocator allow-tch-for-signalling 0");
8839 }
8840 f_vty_transceive(BSCVTY, "exit");
8841 f_vty_transceive(BSCVTY, "exit");
8842 f_vty_transceive(BSCVTY, "exit");
8843}
8844
Philipp Maier783681c2020-07-16 16:47:06 +02008845/* Begin assignmet procedure and send an EMERGENCY SETUP (RR) */
8846private function f_assignment_emerg_setup() runs on MSC_ConnHdlr {
8847 var PDU_ML3_MS_NW emerg_setup;
8848 var octetstring emerg_setup_enc;
8849 var RSL_Message emerg_setup_data_ind;
8850
8851 f_establish_fully(omit, omit);
8852
8853 emerg_setup := valueof(ts_ML3_MO_CC_EMERG_SETUP(1, valueof(ts_Bcap_voice)));
8854 emerg_setup_enc := enc_PDU_ML3_MS_NW(emerg_setup);
8855 emerg_setup_data_ind := valueof(ts_RSL_DATA_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0)), emerg_setup_enc));
8856
8857 RSL.send(emerg_setup_data_ind);
8858}
8859
8860/* Test if the EMERGENCY SETUP gets passed on to the MSC via A when EMERGENCY
8861 * CALLS are permitted by the BSC config. */
8862private function f_TC_assignment_emerg_setup_allow(charstring id) runs on MSC_ConnHdlr {
8863 var PDU_BSSAP emerg_setup_data_ind_bssap;
8864 var PDU_ML3_MS_NW emerg_setup;
8865 timer T := 3.0;
8866
8867 f_assignment_emerg_setup()
8868
8869 T.start;
8870 alt {
8871 [] BSSAP.receive(tr_BSSAP_DTAP) -> value emerg_setup_data_ind_bssap {
8872 emerg_setup := dec_PDU_ML3_MS_NW(emerg_setup_data_ind_bssap.pdu.dtap);
8873 if (not isbound(emerg_setup.msgs.cc.emergencySetup)) {
8874 setverdict(fail, "no emergency setup");
8875 }
8876 }
8877 [] BSSAP.receive {
8878 setverdict(fail, "unexpected BSSAP message!");
8879 }
8880 [] T.timeout {
8881 setverdict(fail, "timout waiting for EMERGENCY SETUP!");
8882 }
8883 }
8884
8885 setverdict(pass);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008886 f_perform_clear();
Philipp Maier783681c2020-07-16 16:47:06 +02008887}
8888
8889/* Test if the EMERGENCY SETUP gets blocked by the BSC if EMERGENCY CALLS are
8890 * forbidden by the BSC config. */
8891private function f_TC_assignment_emerg_setup_deny(charstring id) runs on MSC_ConnHdlr {
8892 var PDU_BSSAP emerg_setup_data_ind_bssap;
8893 timer T := 3.0;
8894
8895 f_assignment_emerg_setup()
8896
8897 T.start;
8898 alt {
8899 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
8900 setverdict(pass);
8901 }
8902 [] RSL.receive {
8903 setverdict(fail, "unexpected RSL message!");
8904 }
8905 [] T.timeout {
8906 setverdict(fail, "timout waiting for RR CHANNEL RELEASE!");
8907 }
8908 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01008909 BSSAP.receive(tr_BSSMAP_ClearRequest);
Neels Hofmeyrc3c6ee62022-01-26 01:22:12 +01008910 f_perform_clear_no_rr_rel();
Philipp Maier783681c2020-07-16 16:47:06 +02008911}
8912
8913/* EMERGENCY CALL situation #1, allowed globally and by BTS */
8914testcase TC_assignment_emerg_setup_allow() runs on test_CT {
8915 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8916 var MSC_ConnHdlr vc_conn;
8917
8918 f_init(1, true);
8919 f_sleep(1.0);
8920
8921 f_vty_allow_emerg_msc(true);
8922 f_vty_allow_emerg_bts(true, 0);
8923 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_allow), pars);
8924 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008925 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008926}
8927
8928/* EMERGENCY CALL situation #2, forbidden globally but allowed by BTS */
8929testcase TC_assignment_emerg_setup_deny_msc() runs on test_CT {
8930 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8931 var MSC_ConnHdlr vc_conn;
8932
8933 f_init(1, true);
8934 f_sleep(1.0);
8935
8936 f_vty_allow_emerg_msc(false);
8937 f_vty_allow_emerg_bts(true, 0);
8938 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8939 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008940 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008941}
8942
8943/* EMERGENCY CALL situation #3, allowed globally but forbidden by BTS */
8944testcase TC_assignment_emerg_setup_deny_bts() runs on test_CT {
8945 var TestHdlrParams pars := f_gen_test_hdlr_pars();
8946 var MSC_ConnHdlr vc_conn;
8947
8948 /* Note: This simulates a spec violation by the MS, correct MS
8949 * implementations would not try to establish an emergency call because
8950 * the system information tells in advance that emergency calls are
8951 * not forbidden */
8952
8953 f_init(1, true);
8954 f_sleep(1.0);
8955
8956 f_vty_allow_emerg_msc(true);
8957 f_vty_allow_emerg_bts(false, 0);
8958 vc_conn := f_start_handler(refers(f_TC_assignment_emerg_setup_deny), pars);
8959 vc_conn.done;
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02008960 f_shutdown_helper();
Philipp Maier783681c2020-07-16 16:47:06 +02008961}
8962
Philipp Maier82812002020-08-13 18:48:27 +02008963/* Test what happens when an emergency call arrives while all TCH channels are
8964 * busy, the BSC is expected to terminate one call in favor of the incoming
8965 * emergency call */
8966testcase TC_emerg_premption() runs on test_CT {
8967 var ASP_RSL_Unitdata rsl_ud;
8968 var integer i;
8969 var integer chreq_total, chreq_nochan;
8970 var RSL_Message rx_rsl;
8971 var RslChannelNr chan_nr;
8972
8973 f_init(1);
8974 f_sleep(1.0);
8975
8976 f_vty_allow_emerg_msc(true);
8977 f_vty_allow_emerg_bts(true, 0);
8978
8979 /* Fill up all channels on the BTS */
8980 chreq_total := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total");
8981 chreq_nochan := f_ctrl_get_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:no_channel");
8982 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS; i := i+1) {
8983 chan_nr := f_chreq_act_ack('33'O, i);
8984 }
8985 IPA_RSL[0].clear;
8986 f_ctrl_get_exp_ratectr_abs(IPA_CTRL, "bts", 0, "chreq:total",
8987 chreq_total + NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS + NUM_SDCCH_PER_BTS);
8988
8989 /* Send Channel request for emegergency call */
8990 f_ipa_tx(0, ts_RSL_CHAN_RQD('A5'O, 23));
8991
8992 /* Expect the BSC to release one (the first) TCH/F on the BTS */
8993 chan_nr := valueof(t_RslChanNr_Bm(1));
8994 f_expect_chan_rel(0, chan_nr, expect_rr_chan_rel := false, expect_rll_rel_req := false);
8995
8996 /* Expect the BSC to send activate/assign the a channel for the emergency call */
8997 rx_rsl := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
8998 chan_nr := rx_rsl.ies[0].body.chan_nr;
8999 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 33));
9000 rx_rsl := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Philipp Maier104f4c02020-09-11 18:12:18 +02009001
Pau Espin Pedrol6ed083c2020-09-23 14:16:58 +02009002 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009003}
9004
9005/* Hopping parameters per a timeslot */
Vadim Yanitskiybc6654a2020-09-13 01:27:40 +07009006private type record length(0..64) of GsmArfcn ArfcnList;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009007private type record FHParamsTs {
9008 boolean enabled,
9009 uint6_t hsn,
9010 uint6_t maio,
9011 ArfcnList ma
9012};
9013
9014/* Hopping parameters per a transceiver */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009015private type record FHParamsTrx {
Philipp Maier798d8952021-10-19 14:43:19 +02009016 GsmBandArfcn arfcn,
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009017 FHParamsTs ts[8]
9018};
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009019
9020/* Randomly generate the hopping parameters for the given timeslot numbers */
9021private function f_TC_fh_params_gen(template integer tr_tn := (1, 3, 5))
9022runs on test_CT return FHParamsTrx {
9023 var FHParamsTrx fhp;
9024
Philipp Maier798d8952021-10-19 14:43:19 +02009025 /* Generate a random ARFCN in the range of 0 - 3. This ARFCN will
9026 * fall in the GSM900 band. */
9027 fhp.arfcn.arfcn := f_rnd_int(3);
9028 fhp.arfcn.pcs := false;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009029
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009030 for (var integer tn := 0; tn < 8; tn := tn + 1) {
9031 if (not match(tn, tr_tn)) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009032 fhp.ts[tn].enabled := false;
9033 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009034 continue;
9035 }
9036
9037 /* Random HSN / MAIO values: 0..63 */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009038 fhp.ts[tn].hsn := f_rnd_int(64);
9039 fhp.ts[tn].maio := f_rnd_int(64);
9040 fhp.ts[tn].ma := { };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009041
9042 /* Random Mobile Allocation (hopping channels) */
9043 var integer ma_len := 2 + f_rnd_int(9); /* 2..10 channels */
9044 var integer step := 3 + f_rnd_int(4); /* 3..6 stepping */
9045 for (var integer i := 1; i <= ma_len; i := i + 1) {
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009046 fhp.ts[tn].ma := fhp.ts[tn].ma & { i * step };
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009047 }
9048
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009049 fhp.ts[tn].enabled := true;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009050 }
9051
9052 log("f_TC_fh_params_gen(): ", fhp);
9053 return fhp;
9054}
9055
9056/* Make sure that the given Channel Description IE matches the hopping configuration */
9057private function f_TC_fh_params_match_chan_desc(in FHParamsTrx fhp, in ChannelDescription cd)
9058{
9059 var template (present) ChannelDescription tr_cd;
9060 var template (present) MaioHsn tr_maio_hsn;
9061 var uint3_t tn := cd.chan_nr.tn;
9062
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009063 if (fhp.ts[tn].enabled) {
9064 tr_maio_hsn := tr_HsnMaio(fhp.ts[tn].hsn, fhp.ts[tn].maio);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009065 tr_cd := tr_ChanDescH1(cd.chan_nr, tr_maio_hsn);
9066 } else {
Philipp Maier798d8952021-10-19 14:43:19 +02009067 tr_cd := tr_ChanDescH0(cd.chan_nr, fhp.arfcn.arfcn);
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009068 }
9069
9070 if (not match(cd, tr_cd)) {
9071 setverdict(fail, "Channel Description IE does not match: ",
9072 cd, " vs expected ", tr_cd);
9073 }
9074}
9075
9076/* Make sure that the given Mobile Allocation IE matches the hopping configuration */
9077private function f_TC_fh_params_match_ma(in FHParamsTrx fhp, uint3_t tn,
9078 in MobileAllocationLV ma)
9079{
9080 var template MobileAllocationLV tr_ma := f_TC_fh_params_gen_tr_ma(fhp, tn, ma);
9081
9082 if (not match(ma, tr_ma)) {
9083 setverdict(fail, "Mobile Allocation IE does not match (tn := ",
9084 tn, "): ", ma, " vs expected: ", tr_ma);
9085 } else {
9086 setverdict(pass);
9087 }
9088}
9089
9090private function f_TC_fh_params_gen_tr_ma(in FHParamsTrx fhp, uint3_t tn,
9091 in MobileAllocationLV ma)
9092return template MobileAllocationLV {
9093 /* Mobile Allocation IE is expected to be empty if hopping is not enabled */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009094 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009095 return { len := 0, ma := ''B };
9096 }
9097
9098 var bitstring full_mask := f_pad_bit(''B, 1024, '0'B);
9099 var bitstring slot_mask := f_pad_bit(''B, 1024, '0'B);
9100 var bitstring ma_mask := ''B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009101
9102 /* Compose the full bit-mask (all channels, up to 1024 entries) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009103 for (var integer i := 0; i < lengthof(fhp.ts); i := i + 1) {
9104 for (var integer j := 0; j < lengthof(fhp.ts[i].ma); j := j + 1) {
9105 if (full_mask[fhp.ts[i].ma[j]] == '1'B)
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009106 { continue; }
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009107 full_mask[fhp.ts[i].ma[j]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009108 }
9109 }
9110
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009111 /* Take ARFCN of the TRX itself into account */
Philipp Maier798d8952021-10-19 14:43:19 +02009112 full_mask[fhp.arfcn.arfcn] := '1'B;
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009113
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009114 /* Compose a bit-mask for the given timeslot number */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009115 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9116 slot_mask[fhp.ts[tn].ma[i]] := '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009117 }
9118
9119 /* Finally, compose the Mobile Allocation bit-mask */
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009120 for (var integer i := 1; i < lengthof(full_mask); i := i + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009121 if (full_mask[i] != '1'B)
9122 { continue; }
9123
9124 /* FIXME: ma_mask := ma_mask & slot_mask[i]; // triggers a bug in TITAN */
9125 if (slot_mask[i] == '1'B) {
9126 ma_mask := ma_mask & '1'B;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009127 } else {
9128 ma_mask := ma_mask & '0'B;
9129 }
9130 }
9131
Vadim Yanitskiy3e997362020-09-05 21:08:34 +07009132 /* ARFCN 0 (if present) goes to the last position of the bit-mask */
9133 if (full_mask[0] == '1'B) {
9134 /* FIXME: ma_mask := ma_mask & slot_mask[0]; // triggers a bug in TITAN */
9135 if (slot_mask[0] == '1'B) {
9136 ma_mask := ma_mask & '1'B;
9137 } else {
9138 ma_mask := ma_mask & '0'B;
9139 }
9140 }
9141
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009142 /* Ensure that ma_mask is octet-aligned */
Vadim Yanitskiy2aa02522020-09-06 14:05:23 +07009143 var integer ma_mask_len := (lengthof(ma_mask) + 8 - 1) / 8;
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009144 ma_mask := f_pad_bit(ma_mask, ma_mask_len * 8, '0'B);
9145
9146 return { len := ma_mask_len, ma := ma_mask };
9147}
9148
Philipp Maier798d8952021-10-19 14:43:19 +02009149/* Configure the appropriate band for a given arfcn, exc */
9150private function f_TC_set_band_by_arfcn(integer bts_nr, GsmBandArfcn arfcn) runs on test_CT
9151{
9152 var charstring band;
9153 var GsmBandArfcn arfcn_ := valueof(ts_GsmBandArfcn(arfcn.arfcn, arfcn.pcs, false));
9154
9155 select (arfcn_) {
9156 case (tr_GsmBandArfcn((259..293), false, ?)) { band := "GSM450"; }
9157 case (tr_GsmBandArfcn((306..340), false, ?)) { band := "GSM480"; }
9158 case (tr_GsmBandArfcn((438..511), false, ?)) { band := "GSM750"; }
9159 case (tr_GsmBandArfcn((128..251), false, ?)) { band := "GSM850"; }
9160 case (tr_GsmBandArfcn((0..124), false, ?)) { band := "GSM900"; }
9161 case (tr_GsmBandArfcn((955..1023), false, ?)) { band := "GSM900"; }
9162 case (tr_GsmBandArfcn((512..885), false, ?)) { band := "DCS1800"; }
9163 case (tr_GsmBandArfcn((512..810), true, ?)) { band := "PCS1900"; }
9164 case else { return; }
9165 }
9166
9167 f_vty_enter_cfg_bts(BSCVTY, bts_nr);
9168 f_vty_transceive(BSCVTY, "band " & band);
9169 f_vty_transceive(BSCVTY, "end");
9170}
9171
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009172/* Configure the hopping parameters in accordance with the given record */
9173private function f_TC_fh_params_set(in FHParamsTrx fhp,
9174 uint8_t bts_nr := 0,
9175 uint8_t trx_nr := 0)
9176runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009177
9178 f_TC_set_band_by_arfcn(bts_nr, fhp.arfcn);
9179
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009180 /* Enter the configuration node for the given BTS/TRX numbers */
9181 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9182
Philipp Maier798d8952021-10-19 14:43:19 +02009183 f_vty_transceive(BSCVTY, "arfcn " & int2str(fhp.arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009184
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009185 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009186 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9187
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009188 if (not fhp.ts[tn].enabled) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009189 f_vty_transceive(BSCVTY, "hopping enabled 0");
9190 f_vty_transceive(BSCVTY, "exit"); /* go back */
9191 continue;
9192 }
9193
9194 /* Configure HSN / MAIO values */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009195 f_vty_transceive(BSCVTY, "hopping sequence-number " & int2str(fhp.ts[tn].hsn));
9196 f_vty_transceive(BSCVTY, "hopping maio " & int2str(fhp.ts[tn].maio));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009197
9198 /* Configure the Mobile Allocation (hopping channels) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009199 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9200 f_vty_transceive(BSCVTY, "hopping arfcn add " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009201 }
9202
9203 f_vty_transceive(BSCVTY, "hopping enabled 1");
9204 f_vty_transceive(BSCVTY, "exit"); /* go back */
9205 }
9206
9207 f_vty_transceive(BSCVTY, "end");
9208}
9209
9210/* Disable frequency hopping on all timeslots */
9211private function f_TC_fh_params_unset(in FHParamsTrx fhp,
9212 uint8_t bts_nr := 0,
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009213 uint8_t trx_nr := 0,
Philipp Maier798d8952021-10-19 14:43:19 +02009214 GsmBandArfcn arfcn := {pcs := false, arfcn := 871})
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009215runs on test_CT {
Philipp Maier798d8952021-10-19 14:43:19 +02009216
9217 f_TC_set_band_by_arfcn(bts_nr, arfcn);
9218
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009219 /* Enter the configuration node for the given BTS/TRX numbers */
9220 f_vty_enter_cfg_trx(BSCVTY, bts_nr, trx_nr);
9221
Philipp Maier798d8952021-10-19 14:43:19 +02009222 f_vty_transceive(BSCVTY, "arfcn " & int2str(arfcn.arfcn));
Vadim Yanitskiye7c8c6e2020-09-13 14:33:03 +07009223
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009224 for (var integer tn := 0; tn < lengthof(fhp.ts); tn := tn + 1) {
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009225 f_vty_transceive(BSCVTY, "timeslot " & int2str(tn));
9226
9227 /* Delete all ARFCNs from the Mobile Allocation (if any) */
Vadim Yanitskiy1b996612020-09-13 13:22:34 +07009228 for (var integer i := 0; i < lengthof(fhp.ts[tn].ma); i := i + 1) {
9229 f_vty_transceive(BSCVTY, "hopping arfcn del " & int2str(fhp.ts[tn].ma[i]));
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009230 }
9231
9232 f_vty_transceive(BSCVTY, "hopping enabled 0");
9233 f_vty_transceive(BSCVTY, "exit"); /* go back */
9234 }
9235
9236 f_vty_transceive(BSCVTY, "end");
9237 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9238}
9239
9240/* Verify presence and correctness of the hopping parameters (HSN, MAIO)
9241 * in the Channel Identification IE of the RSL CHANnel ACTIVation message. */
9242testcase TC_fh_params_chan_activ() runs on test_CT {
9243 var FHParamsTrx fhp := f_TC_fh_params_gen();
9244 var RSL_Message rsl_msg;
9245 var RSL_IE_Body ie;
9246
9247 f_init_vty();
9248
9249 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9250 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9251
9252 f_init(1);
9253
9254 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9255 for (var integer i := 0; i < 9; i := i + 1) {
9256 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9257 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9258
9259 /* Make sure that Channel Identification IE is present */
9260 if (not f_rsl_find_ie(rsl_msg, RSL_IE_CHAN_IDENT, ie)) {
9261 setverdict(fail, "RSL Channel Identification IE is absent");
9262 continue;
9263 }
9264
9265 /* Make sure that hopping parameters (HSN/MAIO) match */
9266 f_TC_fh_params_match_chan_desc(fhp, ie.chan_ident.ch_desc.v);
9267
9268 /* "Mobile Allocation shall be included but empty" - let's check this */
9269 if (ie.chan_ident.ma.v.len != 0) {
9270 setverdict(fail, "Mobile Allocation IE is not empty: ",
9271 ie.chan_ident.ma, ", despite it shall be");
9272 continue;
9273 }
9274 }
9275
9276 /* Disable frequency hopping */
9277 f_TC_fh_params_unset(fhp);
9278
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009279 f_shutdown_helper();
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +07009280}
9281
9282/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Immediate Assignment */
9283testcase TC_fh_params_imm_ass() runs on test_CT {
9284 var FHParamsTrx fhp := f_TC_fh_params_gen();
9285 var RSL_Message rsl_msg;
9286 var RSL_IE_Body ie;
9287
9288 f_init_vty();
9289
9290 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9291 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9292
9293 f_init(1);
9294
9295 /* CS domain: 3 (SDCCH/4+CBCH) + 4 (TCH/F) + 2 (TCH/H) channels available */
9296 for (var integer i := 0; i < 9; i := i + 1) {
9297 f_ipa_tx(0, ts_RSL_CHAN_RQD(f_rnd_ra_cs(), 23));
9298 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9299
9300 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9301 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeC(RSL_MT_IMMEDIATE_ASSIGN_CMD));
9302
9303 /* Make sure that Full Immediate Assign Info IE is present */
9304 if (not f_rsl_find_ie(rsl_msg, RSL_IE_FULL_IMM_ASS_INFO, ie)) {
9305 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
9306 continue;
9307 }
9308
9309 /* Decode the actual Immediate Assignment message */
9310 var GsmRrMessage rr_msg := dec_GsmRrMessage(ie.full_imm_ass_info.payload);
9311 if (not match(rr_msg.header, t_RrHeader(IMMEDIATE_ASSIGNMENT, ?))) {
9312 setverdict(fail, "Failed to match Immediate Assignment: ", rr_msg);
9313 continue;
9314 }
9315
9316 /* Make sure that hopping parameters (HSN/MAIO) match */
9317 f_TC_fh_params_match_chan_desc(fhp, rr_msg.payload.imm_ass.chan_desc);
9318
9319 /* Make sure that the Mobile Allocation IE matches */
9320 f_TC_fh_params_match_ma(fhp, rr_msg.payload.imm_ass.chan_desc.chan_nr.tn,
9321 rr_msg.payload.imm_ass.mobile_allocation);
9322 }
9323
9324 /* Disable frequency hopping */
9325 f_TC_fh_params_unset(fhp);
Philipp Maier82812002020-08-13 18:48:27 +02009326
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009327 f_shutdown_helper();
Philipp Maier82812002020-08-13 18:48:27 +02009328}
9329
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009330/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Assignment Command */
9331testcase TC_fh_params_assignment_cmd() runs on test_CT {
9332 var FHParamsTrx fhp := f_TC_fh_params_gen();
9333 var RSL_Message rsl_msg;
9334 var RSL_IE_Body ie;
9335
9336 f_init_vty();
9337
9338 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9339 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9340
9341 f_init(1);
9342
9343 /* HACK: work around "Couldn't find Expect for CRCX" */
9344 vc_MGCP.stop;
9345
9346 var template PDU_BSSAP ass_cmd := f_gen_ass_req();
9347 ass_cmd.pdu.bssmap.assignmentRequest.codecList := ts_BSSMAP_IE_CodecList({ts_CodecFR});
9348
9349 /* CS domain (TCH): 4 (TCH/F) + 2 (TCH/H) channels available
9350 * NOTE: only 3 SDCCH/4 channels are available on CCCH+SDCCH4+CBCH */
9351 for (var integer i := 0; i < 3; i := i + 1) {
9352 /* Establish a dedicated channel, so we can trigger (late) TCH assignment */
9353 var DchanTuple dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
9354
9355 /* Send a BSSMAP Assignment Command, expect CHANnel ACTIVation */
9356 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ass_cmd));
9357 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9358
9359 /* ACKnowledge CHANnel ACTIVation, expect RSL DATA REQuest */
9360 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9361 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9362
9363 /* Make sure that L3 Information IE is present */
9364 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9365 setverdict(fail, "RSL L3 Information IE is absent");
9366 continue;
9367 }
9368
9369 /* Decode the L3 message and make sure it is (RR) Assignment Command */
9370 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9371 if (not match(l3_msg.header, t_RrL3Header(ASSIGNMENT_COMMAND))) {
9372 setverdict(fail, "Failed to match Assignment Command: ", l3_msg);
9373 continue;
9374 }
9375
9376 /* Make sure that hopping parameters (HSN/MAIO) match */
9377 var ChannelDescription chan_desc := l3_msg.payload.ass_cmd.chan_desc;
9378 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9379
9380 /* Make sure that Cell Channel Description IE is present if FH is enabled */
9381 if (chan_desc.h and not ispresent(l3_msg.payload.ass_cmd.cell_chan_desc)) {
Vadim Yanitskiy38d069d2020-09-02 17:18:57 +07009382 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009383 continue;
9384 }
9385
9386 /* Make sure that the Mobile Allocation IE matches (if present) */
9387 var boolean ma_present := ispresent(l3_msg.payload.ass_cmd.mobile_allocation);
9388 if (chan_desc.h and ma_present) {
9389 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9390 l3_msg.payload.ass_cmd.mobile_allocation.v);
9391 } else if (chan_desc.h and not ma_present) {
9392 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9393 continue;
9394 } else if (not chan_desc.h and ma_present) {
9395 setverdict(fail, "FH disabled, but Mobile Allocation IE is present");
9396 continue;
9397 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009398
9399 f_perform_clear_test_ct(dt);
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009400 }
9401
9402 /* Give the IUT some time to release all channels */
9403 f_sleep(3.0);
9404
9405 /* Disable frequency hopping */
9406 f_TC_fh_params_unset(fhp);
9407
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009408 f_shutdown_helper();
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +07009409}
9410
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009411/* Verify the hopping parameters (HSN, MAIO, MA) in (RR) Handover Command */
9412private function f_TC_fh_params_handover_cmd(in FHParamsTrx fhp)
9413runs on test_CT {
9414 var RSL_Message rsl_msg;
9415 var RSL_IE_Body ie;
9416 var DchanTuple dt;
9417
9418 /* Establish a dedicated channel, so we can trigger handover */
9419 dt := f_est_dchan(f_rnd_ra_cs(), 23, f_rnd_octstring(16));
Vadim Yanitskiyc18ff472021-11-18 20:15:37 +03009420 f_sleep(0.5);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009421
9422 /* Trigger handover from BTS0 to BTS1 */
9423 f_bts_0_cfg(BSCVTY, { "neighbor bts 1" });
9424 f_vty_handover(BSCVTY, 0, 0, dt.rsl_chan_nr, 1);
9425
9426 /* Expect RSL CHANnel ACTIVation on BTS1/TRX0/TS1 */
9427 rsl_msg := f_exp_ipa_rx(1, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
9428
9429 /* ACKnowledge channel activation and expect (RR) Handover Command */
9430 f_ipa_tx(1, ts_RSL_CHAN_ACT_ACK(rsl_msg.ies[0].body.chan_nr, 33));
9431 rsl_msg := f_exp_ipa_rx(0, tr_RSL_MsgTypeR(RSL_MT_DATA_REQ));
9432
9433 /* Make sure that L3 Information IE is present */
9434 if (not f_rsl_find_ie(rsl_msg, RSL_IE_L3_INFO, ie)) {
9435 setverdict(fail, "RSL L3 Information IE is absent");
9436 return;
9437 }
9438
9439 /* Decode the L3 message and make sure it is (RR) Handover Command */
9440 var GsmRrL3Message l3_msg := dec_GsmRrL3Message(ie.l3_info.payload);
9441 if (not match(l3_msg.header, t_RrL3Header(HANDOVER_COMMAND))) {
9442 setverdict(fail, "Failed to match Handover Command: ", l3_msg);
9443 return;
9444 }
9445
9446 /* Make sure that we've got SDCCH/8 on TS1 (expected to be hopping) */
9447 var ChannelDescription chan_desc := l3_msg.payload.ho_cmd.chan_desc;
9448 if (not match(chan_desc.chan_nr, t_RslChanNr_SDCCH8(1, ?))) {
9449 setverdict(fail, "Unexpected channel number: ", chan_desc.chan_nr);
9450 return;
9451 }
9452
9453 /* Make sure that hopping parameters (HSN/MAIO) match */
9454 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9455
9456 /* Make sure that Cell Channel Description IE is present */
9457 if (not ispresent(l3_msg.payload.ho_cmd.cell_chan_desc)) {
9458 setverdict(fail, "FH enabled, but Cell Channel Description IE is absent");
9459 return;
9460 }
9461
9462 /* Make sure that the Mobile Allocation (after time) IE is present and matches */
9463 var boolean ma_present := ispresent(l3_msg.payload.ho_cmd.mobile_allocation);
9464 if (ma_present) {
9465 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9466 l3_msg.payload.ho_cmd.mobile_allocation.v);
9467 } else {
9468 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9469 return;
9470 }
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +01009471
9472 f_perform_clear_test_ct(dt);
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +07009473}
9474testcase TC_fh_params_handover_cmd() runs on test_CT {
9475 var FHParamsTrx fhp := f_TC_fh_params_gen();
9476
9477 f_init_vty();
9478
9479 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8 on BTS1/TRX0 */
9480 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9481
9482 f_vty_transceive(BSCVTY, "timeslot 0");
9483 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9484 f_vty_transceive(BSCVTY, "exit"); /* go back */
9485
9486 f_vty_transceive(BSCVTY, "timeslot 1");
9487 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8");
9488 f_vty_transceive(BSCVTY, "end"); /* we're done */
9489
9490 f_TC_fh_params_set(fhp, 1); /* Enable frequency hopping on BTS1 */
9491 f_vty_transceive(BSCVTY, "drop bts connection 1 oml");
9492
9493 f_init(2);
9494
9495 f_TC_fh_params_handover_cmd(fhp);
9496
9497 /* Disable frequency hopping on BTS1 */
9498 f_TC_fh_params_unset(fhp, 1);
9499
9500 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
9501 f_vty_enter_cfg_trx(BSCVTY, bts := 1, trx := 0);
9502
9503 f_vty_transceive(BSCVTY, "timeslot 0");
9504 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
9505 f_vty_transceive(BSCVTY, "exit"); /* go back */
9506
9507 f_vty_transceive(BSCVTY, "timeslot 1");
9508 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9509 f_vty_transceive(BSCVTY, "end"); /* we're done */
9510
9511 f_shutdown_helper();
9512}
9513
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009514/* Verify the hopping parameters in System Information Type 4 */
9515testcase TC_fh_params_si4_cbch() runs on test_CT {
9516 var FHParamsTrx fhp := f_TC_fh_params_gen(tr_tn := 1);
9517 var ASP_RSL_Unitdata rx_rsl_ud;
9518 timer T := 5.0;
9519
9520 f_init_vty();
9521
9522 /* (Re)configure TS0 as BCCH and TS1 as SDCCH8+CBCH */
9523 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9524
9525 f_vty_transceive(BSCVTY, "timeslot 0");
9526 f_vty_transceive(BSCVTY, "phys_chan_config ccch");
9527 f_vty_transceive(BSCVTY, "exit"); /* go back */
9528
9529 f_vty_transceive(BSCVTY, "timeslot 1");
9530 f_vty_transceive(BSCVTY, "phys_chan_config sdcch8+cbch");
9531 f_vty_transceive(BSCVTY, "end"); /* we're done */
9532
9533 f_TC_fh_params_set(fhp); /* Enable frequency hopping */
9534 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
9535
9536 f_init(1);
9537
9538 T.start;
9539 alt {
9540 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(tr_RSL_BCCH_INFO(RSL_SYSTEM_INFO_4))) -> value rx_rsl_ud {
9541 var RSL_IE_Body ie := rx_rsl_ud.rsl.ies[2].body; /* FULL BCCH Information IE */
9542 var SystemInformation si := dec_SystemInformation(ie.other.payload);
9543
9544 /* Make sure that what we decoded is System Information Type 4 */
9545 if (si.header.message_type != SYSTEM_INFORMATION_TYPE_4) {
9546 setverdict(fail, "RSL FULL BCCH Information IE contains: ", si);
9547 repeat;
9548 }
9549
9550 /* Make sure that CBCH Channel Description IE is present */
9551 if (not ispresent(si.payload.si4.cbch_chan_desc)) {
9552 setverdict(fail, "CBCH Channel Description IE is absent");
9553 break;
9554 }
9555
9556 /* Finally, check the hopping parameters (HSN, MAIO) */
9557 var ChannelDescription chan_desc := si.payload.si4.cbch_chan_desc.v;
9558 f_TC_fh_params_match_chan_desc(fhp, chan_desc);
9559
9560 /* 3GPP TS 44.018, section 9.1.36.2 "CBCH Mobile Allocation":
9561 * The CBCH Mobile Allocation IE *shall* be present if FH is enabled. */
9562 if (chan_desc.h and not ispresent(si.payload.si4.cbch_mobile_alloc)) {
9563 setverdict(fail, "FH enabled, but Mobile Allocation IE is absent");
9564 break;
9565 } else if (chan_desc.h and ispresent(si.payload.si4.cbch_mobile_alloc)) {
9566 f_TC_fh_params_match_ma(fhp, chan_desc.chan_nr.tn,
9567 si.payload.si4.cbch_mobile_alloc.v);
9568 }
9569 }
9570 [] IPA_RSL[0].receive { repeat; }
9571 [] T.timeout {
9572 setverdict(fail, "Timeout waiting for RSL BCCH INFOrmation (SI4)");
9573 }
9574 }
9575
9576 /* Disable frequency hopping */
9577 f_TC_fh_params_unset(fhp);
9578
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009579 /* (Re)configure TS0 as CCCH+SDCCH4+CBCH and TS1 as TCH/F */
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009580 f_vty_enter_cfg_trx(BSCVTY, trx := 0);
9581
9582 f_vty_transceive(BSCVTY, "timeslot 0");
Vadim Yanitskiy8bc46012020-09-06 12:38:01 +07009583 f_vty_transceive(BSCVTY, "phys_chan_config ccch+sdcch4+cbch");
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009584 f_vty_transceive(BSCVTY, "exit"); /* go back */
9585
9586 f_vty_transceive(BSCVTY, "timeslot 1");
9587 f_vty_transceive(BSCVTY, "phys_chan_config tch/f");
9588 f_vty_transceive(BSCVTY, "end"); /* we're done */
9589
Vadim Yanitskiy21726312020-09-04 01:45:36 +07009590 f_shutdown_helper();
Vadim Yanitskiyca974032020-09-01 07:20:39 +07009591}
9592
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009593template (value) PDU_BSSAP_LE ts_BSSMAP_LE_BSSLAP(template (value) BSSLAP_PDU bsslap)
9594 := ts_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, data := enc_BSSLAP_PDU(valueof(bsslap)));
9595
9596private function f_match_bsslap(PDU_BSSAP_LE got_bsslap_msg,
9597 template (present) BSSLAP_PDU expect_bsslap)
9598{
9599 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(got_bsslap_msg.pdu.bssmap.co_info.bsslap_apdu.data);
9600 if (not match(bsslap, expect_bsslap)) {
9601 log("EXPECTING BSSLAP: ", expect_bsslap);
9602 log("GOT BSSLAP: ", bsslap);
9603 setverdict(fail, "BSSLAP is not as expected");
9604 mtc.stop;
9605 }
9606 setverdict(pass);
9607}
9608
9609/* GAD: this is an Ellipsoid point with uncertainty circle, encoded as in 3GPP TS 23.032 §7.3.2. */
9610const octetstring gad_ell_point_unc_circle := '10b0646d0d5f6627'O;
9611
9612private function f_expect_bsslap(template (present) BSSLAP_PDU expect_rx_bsslap) runs on MSC_ConnHdlr {
9613 var PDU_BSSAP_LE rx_bsslap;
9614 BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap);
9615 f_match_bsslap(rx_bsslap, expect_rx_bsslap);
9616}
9617
9618/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9619 * Request on Lb interface. Either with or without the SMLC doing a BSSLAP TA Request. */
9620private function f_lcs_loc_req_for_active_ms(boolean do_ta_request := false) runs on MSC_ConnHdlr {
9621 f_sleep(1.0);
9622
9623 f_establish_fully(omit, omit);
9624 f_bssap_le_register_imsi(g_pars.imsi, omit);
9625
9626 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9627 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9628
9629 var PDU_BSSAP_LE plr;
9630 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9631
9632 if (not do_ta_request) {
9633 /* verify TA Layer 3 in APDU. First the APDU type (BSSLAP), then the BSSLAP data contents. */
9634 var template BSSMAP_LE_IE_APDU expect_apdu := tr_BSSMAP_LE_APDU(BSSMAP_LE_PROT_BSSLAP, ?);
9635 if (not match(plr.pdu.bssmap.perf_loc_req.bsslap_apdu, expect_apdu)) {
9636 log("EXPECTING BSSMAP-LE APDU IE ", expect_apdu);
9637 log("GOT BSSMAP-LE APDU IE ", plr.pdu.bssmap.perf_loc_req.bsslap_apdu);
9638 setverdict(fail, "BSSMAP-LE APDU IE is not as expected");
9639 mtc.stop;
9640 }
9641 var template BSSLAP_PDU expect_ta_layer3 := tr_BSSLAP_TA_Layer3(tr_BSSLAP_IE_TA(0));
9642 var BSSLAP_PDU bsslap := dec_BSSLAP_PDU(plr.pdu.bssmap.perf_loc_req.bsslap_apdu.data);
9643 if (not match(bsslap, expect_ta_layer3)) {
9644 log("EXPECTING BSSLAP TA Layer 3: ", expect_ta_layer3);
9645 log("GOT BSSLAP: ", bsslap);
9646 setverdict(fail, "BSSLAP is not as expected");
9647 mtc.stop;
9648 }
9649 /* OsmoBSC directly sent the TA as BSSLAP APDU in the BSSMAP-LE Perform Location Request to the SMLC. The SMLC
9650 * has no need to request the TA from the BSC and directly responds. */
9651 } else {
9652 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9653 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9654 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9655 }
9656
9657 /* SMLC got the TA from the BSC, now responds with geo information data. */
9658 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9659 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9660 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9661
9662 /* The LCS was using an active A-interface conn. It should still remain active after this. */
9663 f_mo_l3_transceive();
9664
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009665 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009666
9667 f_sleep(2.0);
9668 setverdict(pass);
9669}
9670
9671/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9672 * Request on Lb interface. Without the SMLC doing a BSSLAP TA Request. */
9673private function f_tc_lcs_loc_req_for_active_ms(charstring id) runs on MSC_ConnHdlr {
9674 f_lcs_loc_req_for_active_ms(false);
9675}
9676testcase TC_lcs_loc_req_for_active_ms() runs on test_CT {
9677 var MSC_ConnHdlr vc_conn;
9678 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9679
9680 f_init(1, true);
9681 f_sleep(1.0);
9682 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms), pars);
9683 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009684 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009685}
9686
9687/* With an active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9688 * Request on Lb interface. With the SMLC doing a BSSLAP TA Request. */
9689private function f_tc_lcs_loc_req_for_active_ms_ta_req(charstring id) runs on MSC_ConnHdlr {
9690 f_lcs_loc_req_for_active_ms(true);
9691}
9692testcase TC_lcs_loc_req_for_active_ms_ta_req() runs on test_CT {
9693 var MSC_ConnHdlr vc_conn;
9694 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9695
9696 f_init(1, true);
9697 f_sleep(1.0);
9698 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_ta_req), pars);
9699 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009700 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009701}
9702
9703/* Clear the A-interface conn only, without doing anything on Abis. Useful for LCS, for cases where there is only an A
9704 * conn without an active lchan. */
9705private function f_clear_A_conn() runs on MSC_ConnHdlr
9706{
9707 var BssmapCause cause := 0;
9708 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
9709 BSSAP.receive(tr_BSSMAP_ClearComplete);
9710 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
9711
9712 timer no_more_bssap := 5.0;
9713 no_more_bssap.start;
9714 alt {
9715 [] no_more_bssap.timeout { break; }
9716 [] BSSAP.receive(tr_BSSAP_BSSMAP) {
9717 setverdict(fail, "Expected no more BSSAP after Clear Complete");
9718 mtc.stop;
9719 }
9720 }
9721 setverdict(pass);
9722}
9723
9724/* Verify that the A-interface connection is still working, and then clear it, without doing anything on Abis. Useful
9725 * for LCS, for cases where there is only an A conn without an active lchan. */
9726private function f_verify_active_A_conn_and_clear() runs on MSC_ConnHdlr
9727{
9728 f_logp(BSCVTY, "f_verify_active_A_conn_and_clear: test A link, then clear");
9729
9730 /* When an lchan is active, we can send some L3 data from the BTS side and verify that it shows up on the other
9731 * side towards the MSC. When there is no lchan, this is not possible. To probe whether the A-interface
9732 * connection is still up, we need something that echos back on the A-interface. Another LCS request! */
9733 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9734 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9735 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?));
9736
9737 /* Right, the Perform Location Request showed up on Lb, now we can clear the A conn. */
9738 f_clear_A_conn();
9739 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9740 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9741}
9742
9743/* With *no* active lchan, start BSSMAP Perform Location Request on A interface, starting BSSMAP-LE Perform Location
9744 * Request on Lb interface. BSC will Page for the subscriber as soon as we (virtual SMLC) request the TA via BSSLAP.
9745 */
9746private function f_tc_lcs_loc_req_for_idle_ms(charstring id) runs on MSC_ConnHdlr {
9747 f_sleep(1.0);
9748
9749 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9750 f_bssap_le_register_imsi(g_pars.imsi, omit);
9751
9752 /* Register to receive the Paging Command */
9753 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9754 g_chan_nr := new_chan_nr;
9755 f_rslem_register(0, g_chan_nr);
9756
9757 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9758 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9759 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9760 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9761
9762 var PDU_BSSAP_LE plr;
9763 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9764
9765 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9766 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9767
9768 /* OsmoBSC needs to Page */
9769 RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi)));
9770 f_logp(BSCVTY, "got Paging Command");
9771
9772 /* MS requests channel. Since the Paging was for LCS, the Paging Response does not trigger a Complete Layer 3 to
9773 * the MSC, and releases the lchan directly. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +02009774 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);
9775 f_expect_lchan_rel(RSL, RSL_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009776
9777 /* From the Paging Response, the TA is now known to the BSC, and it responds to the SMLC. */
9778
9779 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9780
9781 /* SMLC got the TA from the BSC, now responds with geo information data. */
9782 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
9783 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9784
9785 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
9786
9787 /* The lchan is gone, the A-interface conn was created for the LCS only.
9788 * Still it is clearly the MSC's job to decide whether to tear down the conn or not. */
9789 f_verify_active_A_conn_and_clear();
9790
9791 f_sleep(2.0);
9792 setverdict(pass);
9793}
9794testcase TC_lcs_loc_req_for_idle_ms() runs on test_CT {
9795 var MSC_ConnHdlr vc_conn;
9796 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9797
9798 f_init(1, true);
9799 f_sleep(1.0);
9800
9801 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9802 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9803
9804 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms), pars);
9805 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009806 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009807}
9808
9809/* With no active lchan, start BSSMAP Perform Location Request on A interface, but omit IMSI; expect failure response.
9810 */
9811private function f_tc_lcs_loc_req_no_subscriber(charstring id) runs on MSC_ConnHdlr {
9812 f_sleep(1.0);
9813
9814 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9815 f_bssap_le_register_imsi(g_pars.imsi, omit);
9816
9817 /* provoke an abort by omitting both IMSI and IMEI */
9818 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9819 valueof(ts_BSSMAP_Perform_Location_Request(omit,
9820 ts_CellId_CGI('262'H, '42'H, 23, 42)))));
9821 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9822
9823 /* BSC tells MSC about failure */
9824 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9825 locationEstimate := omit, positioningData := omit,
9826 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_DATA_MISSING_IN_REQ)));
9827
9828 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9829 f_verify_active_A_conn_and_clear();
9830
9831 f_sleep(2.0);
9832 setverdict(pass);
9833}
9834testcase TC_lcs_loc_req_no_subscriber() runs on test_CT {
9835 var MSC_ConnHdlr vc_conn;
9836 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9837
9838 f_init(1, true);
9839 f_sleep(1.0);
9840
9841 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9842 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9843
9844 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_no_subscriber), pars);
9845 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009846 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009847}
9848
9849/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9850 * BSSMAP-LE Perform Location Response (before or after sending a BSSLAP TA Request) */
9851private function f_lcs_loc_req_for_active_ms_le_timeout(boolean do_ta) runs on MSC_ConnHdlr {
9852 f_sleep(1.0);
9853
9854 f_establish_fully(omit, omit);
9855 f_bssap_le_register_imsi(g_pars.imsi, omit);
9856
9857 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9858 ts_CellId_CGI('262'H, '42'H, 23, 42))));
9859
9860 var PDU_BSSAP_LE plr;
9861 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9862
9863 if (do_ta) {
9864 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9865 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9866 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
9867 }
9868
9869 /* SMLC fails to respond, BSC runs into timeout */
9870 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocAbort(BSSMAP_LE_LCS_CAUSE_SYSTEM_FAILURE));
9871 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9872
9873 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9874 locationEstimate := omit, positioningData := omit,
9875 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_SYSTEM_FAILURE)));
9876
9877 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9878 f_verify_active_A_conn_and_clear();
9879
9880 f_sleep(2.0);
9881 setverdict(pass);
9882}
9883
9884/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9885 * BSSMAP-LE Perform Location Response, without sending a BSSLAP TA Request. */
9886private function f_tc_lcs_loc_req_for_active_ms_le_timeout(charstring id) runs on MSC_ConnHdlr {
9887 f_lcs_loc_req_for_active_ms_le_timeout(false);
9888}
9889
9890testcase TC_lcs_loc_req_for_active_ms_le_timeout() runs on test_CT {
9891 var MSC_ConnHdlr vc_conn;
9892 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9893
9894 f_init(1, true);
9895 f_sleep(1.0);
9896 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout), pars);
9897 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009898 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009899}
9900
9901/* With an active lchan, start a Perform Location Request on the A-interface, but virtual SMLC does not answer with
9902 * BSSMAP-LE Perform Location Response, after sending a BSSLAP TA Request. */
9903private function f_tc_lcs_loc_req_for_active_ms_le_timeout2(charstring id) runs on MSC_ConnHdlr {
9904 f_lcs_loc_req_for_active_ms_le_timeout(true);
9905}
9906
9907testcase TC_lcs_loc_req_for_active_ms_le_timeout2() runs on test_CT {
9908 var MSC_ConnHdlr vc_conn;
9909 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9910
9911 f_init(1, true);
9912 f_sleep(1.0);
9913 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_active_ms_le_timeout2), pars);
9914 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009915 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009916}
9917
9918/* With *no* active lchan, start a Perform Location Request, expecting that the MS will be Paged. */
9919private function f_tc_lcs_loc_req_for_idle_ms_no_pag_resp(charstring id) runs on MSC_ConnHdlr {
9920 f_sleep(1.0);
9921
9922 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9923 f_bssap_le_register_imsi(g_pars.imsi, omit);
9924
9925 /* Register to receive the Paging Command */
9926 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9927 g_chan_nr := new_chan_nr;
9928 f_rslem_register(0, g_chan_nr);
9929
9930 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9931 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9932 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
9933 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
9934
9935 var PDU_BSSAP_LE plr;
9936 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
9937
9938 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
9939 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
9940
9941 /* OsmoBSC needs to Page */
9942 var PDU_BSSAP_LE rx_bsslap;
9943 alt {
9944 [] RSL.receive(tr_RSL_PAGING_CMD(tr_MI_IMSI(g_pars.imsi))) {
9945 f_logp(BSCVTY, "got Paging Command");
9946 repeat;
9947 }
9948 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
9949 /* MS does not respond to Paging, TA Req runs into timeout. */
9950 f_match_bsslap(rx_bsslap, tr_BSSLAP_Abort(?));
9951 }
9952 }
9953
9954 /* SMLC responds with failure */
9955 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(omit, BSSMAP_LE_LCS_CAUSE_REQUEST_ABORTED));
9956 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
9957
9958 /* BSC tells MSC about failure */
9959 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(
9960 locationEstimate := omit, positioningData := omit,
9961 lCS_Cause := tr_BSSMAP_LcsCause(BSSMAP_LCS_CAUSE_REQUEST_ABORTED)));
9962
9963 /* There is no lchan. Still the MSC's job to decide whether to tear down the conn or not. */
9964 f_verify_active_A_conn_and_clear();
9965
9966 f_sleep(2.0);
9967 setverdict(pass);
9968}
9969testcase TC_lcs_loc_req_for_idle_ms_no_pag_resp() runs on test_CT {
9970 var MSC_ConnHdlr vc_conn;
9971 var TestHdlrParams pars := f_gen_test_hdlr_pars();
9972
9973 f_init(1, true);
9974 f_sleep(1.0);
9975
9976 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
9977 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
9978
9979 vc_conn := f_start_handler(refers(f_tc_lcs_loc_req_for_idle_ms_no_pag_resp), pars);
9980 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +01009981 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +02009982}
9983
9984/* During an ongoing Location Request, the MS sends a CM Service Request. Expect the same A-conn to be re-used / taken
9985 * over. */
9986private function f_tc_cm_service_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
9987 f_sleep(1.0);
9988
9989 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
9990 f_bssap_le_register_imsi(g_pars.imsi, omit);
9991
9992 /* Register to receive the Paging Command */
9993 var RslChannelNr new_chan_nr := valueof(t_RslChanNr0(1, RSL_CHAN_NR_Bm_ACCH));
9994 g_chan_nr := new_chan_nr;
9995 f_rslem_register(0, g_chan_nr);
9996
9997 BSSAP.send(ts_BSSAP_Conn_Req(g_pars.sccp_addr_bsc, g_pars.sccp_addr_msc,
9998 valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
9999 ts_CellId_CGI('001'H, '01'H, 1, 0)))));
10000 BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND);
10001
10002 var PDU_BSSAP_LE plr;
10003 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10004
10005 /* As the A-interface conn was established for LCS, the MS coincidentally decides to issue a CM Service Request
10006 * and establish Layer 3. It should use the existing A-interface conn. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010007 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 +020010008 do_clear := false, expect_bssmap_l3 := true);
10009
10010 /* SMLC wants to ask the TA from the BSC explicitly in a BSSLAP TA Request message */
10011 BSSAP_LE.send(ts_BSSMAP_LE_BSSLAP(ts_BSSLAP_TA_Req));
10012
10013 /* OsmoBSC already has an lchan, no need to Page, just returns the TA */
10014 f_expect_bsslap(tr_BSSLAP_TA_Resp(?, ?));
10015
10016 /* SMLC got the TA from the BSC, now responds with geo information data. */
10017 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10018 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10019 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10020
10021 /* The lchan should still exist, it was from a CM Service Request. */
10022 f_mo_l3_transceive();
10023
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010024 f_perform_clear();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010025
10026 f_sleep(2.0);
10027 setverdict(pass);
10028}
10029testcase TC_cm_service_during_lcs_loc_req() runs on test_CT {
10030 var MSC_ConnHdlr vc_conn;
10031 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10032
10033 f_init(1, true);
10034 f_sleep(1.0);
10035
10036 pars.sccp_addr_msc := g_bssap[0].sccp_addr_own;
10037 pars.sccp_addr_bsc := g_bssap[0].sccp_addr_peer;
10038
10039 vc_conn := f_start_handler(refers(f_tc_cm_service_during_lcs_loc_req), pars);
10040 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010041 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010042}
10043
10044/* During an ongoing Perform Location Request, do a Handover, an expect a BSSLAP Reset message from the BSC to indicate
10045 * the new lchan after handover. */
10046private function f_tc_ho_during_lcs_loc_req(charstring id) runs on MSC_ConnHdlr {
10047 f_sleep(1.0);
10048
10049 f_establish_fully(omit, omit);
10050 f_bssap_le_register_imsi(g_pars.imsi, omit);
10051
10052 BSSAP.send(valueof(ts_BSSMAP_Perform_Location_Request(ts_BSSMAP_Imsi(g_pars.imsi),
10053 ts_CellId_CGI('262'H, '42'H, 23, 42))));
10054
10055 var PDU_BSSAP_LE plr;
10056 BSSAP_LE.receive(tr_BSSMAP_LE_PerfLocReq(BSSMAP_LE_LOC_INFO_CURRENT_GEOGRAPHIC_LOC, ?, ?)) -> value(plr);
10057
10058 /* SMLC ponders the Location Request, in the meantime the BSC decides to handover */
10059 f_bts_0_cfg(BSCVTY, {"neighbor bts 1"});
10060
10061 var HandoverState hs := {
10062 rr_ho_cmpl_seen := false,
10063 handover_done := false,
Neels Hofmeyrc741fcb2021-10-02 14:52:28 +020010064 old_chan_nr := -,
10065 expect_target_tsc := BTS_TSC[1]
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010066 };
10067 /* issue hand-over command on VTY */
10068 f_vty_handover(BSCVTY, 0, 0, g_chan_nr, 1);
10069 /* temporarily suspend DChan processing on BTS1 to avoid race with RSLEM_register */
10070 f_rslem_suspend(RSL1_PROC);
10071
10072 /* From the MGW perspective, a handover is is characterized by
10073 * performing one MDCX operation with the MGW. So we expect to see
10074 * one more MDCX during handover. */
10075 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].crcx_seen_exp + 1;
10076
10077 alt {
10078 [] as_handover(hs);
10079 }
10080
10081 var PDU_BSSAP_LE rx_bsslap;
10082
10083 interleave {
10084 /* Expect the BSC to inform the MSC about the handover */
10085 [] BSSAP.receive(tr_BSSMAP_HandoverPerformed);
10086
10087 /* Expect the BSC to inform the SMLC about the handover */
10088 [] BSSAP_LE.receive(tr_BSSMAP_LE_ConnInfo(BSSMAP_LE_PROT_BSSLAP, ?)) -> value(rx_bsslap) {
10089 f_match_bsslap(rx_bsslap, tr_BSSLAP_Reset(BSSLAP_CAUSE_INTRA_BSS_HO));
10090 }
10091 }
10092
10093 /* SMLC now responds with geo information data. */
10094 BSSAP_LE.send(ts_BSSMAP_LE_PerfLocResp(gad_ell_point_unc_circle, omit));
10095 BSSAP_LE.receive(BSSAP_LE_Conn_Prim:CONN_PRIM_DISC_IND);
10096 BSSAP.receive(tr_BSSMAP_Perform_Location_Response(tr_BSSMAP_IE_LocationEstimate(gad_ell_point_unc_circle)));
10097
10098 /* lchan still active */
10099 f_mo_l3_transceive(RSL1);
10100
10101 /* MSC decides it is done now. */
Neels Hofmeyr85bcd272021-07-22 19:14:48 +020010102 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010103
10104 f_sleep(2.0);
10105 setverdict(pass);
10106}
10107testcase TC_ho_during_lcs_loc_req() runs on test_CT {
10108 var MSC_ConnHdlr vc_conn;
10109 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10110
10111 f_init(2, true);
10112 f_sleep(1.0);
10113 vc_conn := f_start_handler(refers(f_tc_ho_during_lcs_loc_req), pars);
10114 vc_conn.done;
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010115 f_shutdown_helper();
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020010116}
10117
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010118/* Attempt Complete Layer 3 without any MSC available (OS#4832) */
10119private function f_tc_no_msc(charstring id) runs on MSC_ConnHdlr {
10120 f_MscConnHdlr_init(g_pars.media_nr, "127.0.0.2", "127.0.0.3", FR_AMR);
10121
10122 /* Also disable attach for the single connected MSC */
10123 f_vty_msc_allow_attach(BSCVTY, { false });
10124
10125 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) ));
10126 f_chan_est(g_pars.ra, l3_enc, g_pars.link_id, g_pars.fn);
10127
10128 /* No MSC is found, expecting a proper release on RSL */
10129 interleave {
10130 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {
10131 f_logp(BSCVTY, "Got RSL RR Release");
10132 }
10133 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10134 f_logp(BSCVTY, "Got RSL Deact SACCH");
10135 }
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010136 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010137 f_logp(BSCVTY, "Got RSL RF Chan Rel, sending Rel Ack");
10138 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010139 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010140 }
10141 }
10142 setverdict(pass);
10143}
10144testcase TC_no_msc() runs on test_CT {
10145
10146 f_init(1, true);
10147 f_sleep(1.0);
10148 var MSC_ConnHdlr vc_conn;
10149 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10150
10151 f_ctrs_bsc_init(counternames_bsc_mscpool);
10152
10153 vc_conn := f_start_handler(refers(f_tc_no_msc), pars);
10154 vc_conn.done;
10155
10156 f_ctrs_bsc_add("mscpool:subscr:no_msc");
10157 f_ctrs_bsc_verify();
Vadim Yanitskiy8ca840e2021-01-03 14:16:35 +010010158 f_shutdown_helper();
Neels Hofmeyrbf037052020-10-28 22:52:02 +000010159}
10160
Harald Welte0ea2d5e2018-04-07 21:40:29 +020010161/* Dyn PDCH todo:
10162 * activate OSMO as TCH/F
10163 * activate OSMO as TCH/H
10164 * does the BSC-located PCU socket get the updated INFO?
10165 * what if no PCU is connected at the time?
10166 * is the info correct on delayed PCU (re)connect?
10167 */
Harald Welte94e0c342018-04-07 11:33:23 +020010168
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010169private function f_TC_refuse_mode_modif_to_vamos(charstring id) runs on MSC_ConnHdlr {
10170 var PDU_BSSAP ass_cmd := f_gen_ass_req(g_pars.use_osmux);
10171 var template PDU_BSSAP exp_compl := f_gen_exp_compl(g_pars.use_osmux);
10172
10173 /* puzzle together the ASSIGNMENT REQ for given codec[s] */
10174 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
10175 ass_cmd.pdu.bssmap.assignmentRequest.codecList := g_pars.ass_codec_list;
10176 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0] :=
10177 g_pars.ass_codec_list.codecElements[0];
10178 if (isvalue(g_pars.expect_mr_s0_s7)) {
10179 exp_compl.pdu.bssmap.assignmentComplete.speechCodec.codecElements[0].s0_7 :=
10180 g_pars.expect_mr_s0_s7;
10181 }
10182 }
10183 ass_cmd.pdu.bssmap.assignmentRequest.channelType :=
10184 f_BSSMAP_chtype_from_codec(g_pars.ass_codec_list.codecElements[0]);
10185 log("expecting ASS COMPL like this: ", exp_compl);
10186
10187 f_establish_fully(ass_cmd, exp_compl);
10188
Neels Hofmeyr8746b0d2021-06-01 17:25:39 +020010189 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 +000010190
10191 var RSL_Message rsl;
10192
10193 timer T := 5.0;
10194 T.start;
10195 alt {
10196 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
10197 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
10198 log("Rx L3 from net: ", l3);
10199 if (ischosen(l3.msgs.rrm.channelModeModify)) {
10200 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10201 mtc.stop;
10202 }
10203 }
10204 [] RSL.receive(tr_RSL_MODE_MODIFY_REQ(g_chan_nr, ?)) -> value rsl {
10205 setverdict(fail, "Mode Modify to VAMOS succeeded even though BTS does not support VAMOS");
10206 mtc.stop;
10207 }
10208 [] T.timeout {
10209 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related Mode Modify should happen. */
10210 setverdict(pass);
10211 }
10212 }
10213 T.stop;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010214
10215 f_perform_clear();
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010216}
10217
10218/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel Mode Modify to VAMOS mode is refused by
10219 * osmo-bsc. */
10220testcase TC_refuse_mode_modif_to_vamos() runs on test_CT {
10221 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10222 var MSC_ConnHdlr vc_conn;
10223
10224 f_init(1, true);
10225 f_sleep(1.0);
10226
10227 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10228 vc_conn := f_start_handler(refers(f_TC_refuse_mode_modif_to_vamos), pars);
10229 vc_conn.done;
10230 f_shutdown_helper();
10231}
10232
10233/* The BSC does *not* indicate BTS_FEAT_VAMOS; make sure that a channel activation to VAMOS mode is refused by osmo-bsc.
10234 */
10235testcase TC_refuse_chan_act_to_vamos() runs on test_CT {
10236 f_init_vty();
10237
10238 f_init(1, false);
10239 f_sleep(1.0);
10240
10241 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot 1 sub-slot 0 activate-vamos fr");
10242
10243 var ASP_RSL_Unitdata rx_rsl_ud;
10244 timer T := 5.0;
10245
10246 T.start;
10247 alt {
10248 [] IPA_RSL[0].receive(tr_ASP_RSL_UD(?, IPAC_PROTO_RSL_TRX0)) -> value rx_rsl_ud {
10249 if (rx_rsl_ud.rsl.msg_type == RSL_MT_CHAN_ACTIV) {
10250 T.stop;
10251 setverdict(fail, "CHANnel ACTivate in VAMOS mode succeeded even though BTS does not support VAMOS");
10252 mtc.stop;
10253 }
10254 repeat;
10255 }
10256 [] T.timeout {
10257 /* The BTS does not exhibit BTS_FEAT_VAMOS, so no VAMOS related CHANnel ACTivate should happen. */
10258 setverdict(pass);
10259 }
10260 }
10261}
10262
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010263private function f_TC_reassignment_codec(charstring id) runs on MSC_ConnHdlr {
10264 /* First fully set up a speech lchan */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010265 f_assignment_codec(id, do_perform_clear := false);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010266
10267 /* Trigger re-assignment to another lchan */
10268 var AssignmentState assignment_st := valueof(ts_AssignmentStateInit);
10269
10270 /* Re-Assignment should tell the MGW endpoint the new lchan's RTP address and port, so expecting to see exactly
10271 * one MDCX on MGCP. */
10272 g_media.mgcp_conn[0].mdcx_seen_exp := g_media.mgcp_conn[0].mdcx_seen_exp + 1;
10273
10274 /* The new lchan will see all-new IPAC_CRCX and IPAC_MDCX messages telling the BTS the same RTP address and port
10275 * as the old lchan used. */
10276 g_media.bts.ipa_crcx_seen := false;
10277 g_media.bts.ipa_mdcx_seen := false;
10278
10279 /* Send different BTS side RTP port number for the new lchan */
10280 g_media.bts.bts.port_nr := 4223;
10281
10282 f_rslem_register(0, valueof(ts_RslChanNr_Bm(2))); /* <-- FIXME: can we somehow infer the timeslot that will be used? */
10283
10284 /* Trigger re-assignment. */
10285 f_vty_transceive(BSCVTY, "bts 0 trx 0 timeslot " & int2str(g_chan_nr.tn) & " sub-slot 0 assignment");
10286
10287 timer T := 5.0;
10288 T.start;
10289 alt {
10290 [] as_assignment(assignment_st);
10291 [] as_Media();
10292 [] T.timeout {
10293 break;
10294 }
10295 }
10296
10297 if (not assignment_st.assignment_done) {
10298 setverdict(fail, "Assignment did not complete");
10299 mtc.stop;
10300 }
10301
10302 f_check_mgcp_expectations()
10303 setverdict(pass);
10304
10305 f_sleep(2.0);
10306 log("show lchan summary: ", f_vty_transceive_ret(BSCVTY, "show lchan summary"));
10307
10308 /* Instruct BSC to clear channel */
10309 var BssmapCause cause := 0;
10310 BSSAP.send(ts_BSSMAP_ClearCommand(cause));
10311 interleave {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010312 [] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_RRM_RR_RELEASE)) {}
10313 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {}
Neels Hofmeyr3c5127e2021-07-22 19:18:40 +020010314 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010315 RSL.send(ts_RSL_RF_CHAN_REL_ACK(g_chan_nr));
Neels Hofmeyre680b012021-07-22 19:19:09 +020010316 f_rslem_unregister(0, g_chan_nr);
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010317 }
10318 [] BSSAP.receive(tr_BSSMAP_ClearComplete) {
10319 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
10320 }
10321 }
Neels Hofmeyr40a45d12021-09-23 22:57:12 +020010322 f_expect_dlcx_conns();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010323
10324 f_sleep(0.5);
10325}
10326
10327testcase TC_reassignment_fr() runs on test_CT {
10328 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10329 var MSC_ConnHdlr vc_conn;
10330
10331 f_init(1, true);
10332 f_sleep(1.0);
10333
Neels Hofmeyrac432fa2021-11-02 16:45:56 +010010334 f_ctrs_bsc_and_bts_handover_init();
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000010335
10336 pars.ass_codec_list := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10337 vc_conn := f_start_handler(refers(f_TC_reassignment_codec), pars);
10338 vc_conn.done;
10339
10340 /* from f_establish_fully() */
10341 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10342 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10343 /* from re-assignment */
10344 f_ctrs_bsc_and_bts_add(0, "assignment:attempted");
10345 f_ctrs_bsc_and_bts_add(0, "assignment:completed");
10346 f_ctrs_bsc_and_bts_verify();
10347 f_shutdown_helper();
10348}
10349
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010350const charstring REEST_LOST_CONNECTION := "REEST_LOST_CONNECTION";
10351const charstring REEST_CLEAR := "REEST_CLEAR";
10352const charstring REEST_CLEAR_DONE := "REEST_CLEAR_DONE";
10353
10354/* CM Re-Establishment, 3GPP TS 24.008 4.5.1.6.
10355 * The MS <-> BTS loses radio connection, MS shows up on second BTS and asks for CM Re-Establishment.
10356 * BSC should establish a separate A conn for the same MS, the original A conn is then cleared by
10357 * the MSC as the CM Re-Establishment is handled.
10358 *
10359 * MS bts0 bts1 bsc msc test-component
10360 * |<----->|<----------------->|<-0-->| _1 Establish channel on bts 0
10361 * | | _1 wait a bit, to settle down
10362 * |<-x x--| | _1 "lose connection"
10363 * | | REEST_LOST_CONNECTION
10364 * |----------------->|------->|--1-->| _2 new A-conn: Chan Rqd, Imm Ass, Compl L3 with CM Re-Establishment Req
10365 * | | REEST_CLEAR
10366 * | |<-0---| _1 Clear Command on first A-conn
10367 * | |--0-->| _1 Clear Complete
10368 * | |<----------------->| | _1 Release first channel
10369 * | | REEST_CLEAR_DONE
10370 * |<-----------------|<-------|<-1---| _2 Chan Activ, Assignment Command
10371 * |<-----------------|<-------|<-1---| _2 Clear Command, Release
10372 *
10373 */
10374private function f_tc_cm_reestablishment_1(charstring id) runs on MSC_ConnHdlr {
10375 var template PDU_BSSAP exp_compl := f_gen_exp_compl();
10376 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10377
10378 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10379 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10380
10381 f_establish_fully(ass_cmd, exp_compl);
10382
10383 /* The original channel loses connection, MS attemts CM Re-Establishment on another cell, see
10384 * f_tc_cm_reestablishment_2(). This established channel stays active until MSC sends a Clear Command. The time
10385 * when exactly that happens is determined by f_tc_cm_reestablishment_2(). */
10386 f_sleep(2.0);
10387 COORD.send(REEST_LOST_CONNECTION);
10388
10389 alt {
10390 [] COORD.receive(REEST_CLEAR);
10391 [] RSL.receive(tr_RSL_DEACT_SACCH(g_chan_nr)) {
10392 setverdict(fail, "Unexpected channel release");
10393 mtc.stop;
10394 }
10395 [] RSL.receive(tr_RSL_RF_CHAN_REL(g_chan_nr)) {
10396 setverdict(fail, "Unexpected channel release");
10397 mtc.stop;
10398 }
10399 }
10400 f_perform_clear()
Neels Hofmeyr969abd02021-09-23 22:24:08 +020010401 f_create_mgcp_delete_ep(g_media.mgcp_ep);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010402 COORD.send(REEST_CLEAR_DONE);
10403}
10404
10405private function f_tc_cm_reestablishment_2(charstring id) runs on MSC_ConnHdlr {
10406 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, FR_AMR);
10407
10408 /* The MS lost the connection on the first channel, now establishes another one */
10409 COORD.receive(REEST_LOST_CONNECTION);
10410
10411 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(g_pars.imsi));
10412 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_REESTABL_REQ(mi));
10413 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
10414
10415 f_create_bssmap_exp(l3_enc);
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010416 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 +020010417 BSSAP.receive(tr_BSSMAP_ComplL3(l3_enc));
10418
10419 /* MSC got the CM Re-Establishment request and first off clears the previous conn. */
10420 COORD.send(REEST_CLEAR);
10421 COORD.receive(REEST_CLEAR_DONE);
10422
10423 f_sleep(2.0);
10424
10425 /* Answer the CM Re-Establishment with an Assignment Command. */
10426 var template PDU_BSSAP expect_assignment_compl := f_gen_exp_compl();
10427 var PDU_BSSAP ass_cmd := f_gen_ass_req();
10428 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10429 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
10430
10431 var AssignmentState st := valueof(ts_AssignmentStateInit);
10432 st.voice_call := true;
10433 st.is_assignment := true;
10434
10435 var ExpectCriteria mgcpcrit := {
10436 connid := omit,
10437 endpoint := omit,
10438 transid := omit
10439 };
10440 f_create_mgcp_expect(mgcpcrit);
10441
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010442 f_rslem_dchan_queue_enable(RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010443
10444 BSSAP.send(ass_cmd);
10445
10446 var PDU_BSSAP bssap;
10447
10448 alt {
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010449 [] as_assignment(st, rsl_pt := RSL1, rsl_proc_pt := RSL1_PROC);
10450 [] as_Media_ipacc(RSL1, RSL2);
10451 [] as_Media_mgw();
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010452 [st.assignment_done] BSSAP.receive(expect_assignment_compl) {
10453 break;
10454 }
10455 }
10456
10457 f_sleep(3.0);
10458
10459 f_logp(BSCVTY, "f_tc_cm_reestablishment_2 clearing");
Neels Hofmeyrc7b1f6d2021-07-20 23:21:36 +020010460 f_perform_clear(RSL1, RSL1_PROC);
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010461}
10462
10463testcase TC_cm_reestablishment() runs on test_CT {
10464 var TestHdlrParams pars1 := f_gen_test_hdlr_pars();
10465 var MSC_ConnHdlr vc_conn1;
10466
10467 var TestHdlrParams pars2 := f_gen_test_hdlr_pars();
10468 var MSC_ConnHdlr vc_conn2;
10469 pars2.imsi := pars1.imsi;
10470 pars2.media_nr := 2;
Neels Hofmeyrbf720202021-10-02 12:58:24 +020010471 pars2.expect_tsc := BTS_TSC[1];
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020010472
10473 f_init(2, true, guard_timeout := 40.0);
10474 f_sleep(1.0);
10475
10476 vc_conn1 := f_start_handler_create(pars1);
10477 vc_conn2 := f_start_handler_create(pars2);
10478 connect(vc_conn1:COORD, vc_conn2:COORD);
10479 f_start_handler_run(vc_conn1, refers(f_tc_cm_reestablishment_1), pars1);
10480 f_start_handler_run(vc_conn2, refers(f_tc_cm_reestablishment_2), pars2);
10481 vc_conn1.done;
10482 vc_conn2.done;
10483
10484 f_shutdown_helper();
10485}
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000010486
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010487function f_exp_ipa_rx_nonfatal(integer bts_nr, template (present) RSL_Message t_rx, float t_secs := 2.0,
10488 IpaStreamId sid := IPAC_PROTO_RSL_TRX0, boolean ignore_other_rx := true)
10489runs on test_CT return template (omit) RSL_Message {
10490 var ASP_RSL_Unitdata rx_rsl_ud;
10491 timer T := t_secs;
10492
10493 T.start;
10494 alt {
10495 [] IPA_RSL[bts_nr].receive(tr_ASP_RSL_UD(t_rx, sid)) -> value rx_rsl_ud {
10496 T.stop;
10497 }
10498 [ignore_other_rx] IPA_RSL[bts_nr].receive { repeat; }
10499 [not ignore_other_rx] IPA_RSL[bts_nr].receive {
10500 log("f_exp_ipa_rx_nonfatal(): Got different message than ", t_rx);
10501 T.stop;
10502 return omit;
10503 }
10504 [] T.timeout {
10505 return omit;
10506 }
10507 }
10508 return rx_rsl_ud.rsl;
10509}
10510
10511private function f_vty_set_imm_ass(TELNETasp_PT pt, BtsNr bts_nr := 0, charstring imm_ass_setting := "post-chan-ack") {
10512 f_vty_enter_cfg_bts(pt, bts_nr);
10513 f_vty_transceive(pt, "immediate-assignment " & imm_ass_setting);
10514 f_vty_transceive(pt, "exit");
10515 f_vty_transceive(pt, "exit");
10516 f_vty_transceive(pt, "exit");
10517}
10518
10519private function f_verify_imm_ass(RSL_Message imm_ass, template uint8_t ra := ?, template GsmFrameNumber fn := ?,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010520 template RslChannelNr chan_nr := ?,
10521 template (present) uint12_t arfcn := ?,
10522 template (present) uint3_t tsc := ?)
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010523{
10524 var RSL_IE_Body full_imm_ass_info;
10525 if (not f_rsl_find_ie(imm_ass, RSL_IE_FULL_IMM_ASS_INFO, full_imm_ass_info)) {
10526 setverdict(fail, "RSL Full Immediate Assign Info IE is absent");
10527 mtc.stop;
10528 }
10529
10530 var GsmRrMessage rr_imm_ass := dec_GsmRrMessage(full_imm_ass_info.full_imm_ass_info.payload);
10531 var template GsmRrMessage expect_imm_ass := tr_IMM_ASS(ra := ra,
10532 fn := fn,
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010533 ch_desc := tr_ChanDescH0(chan_nr, arfcn, tsc),
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010534 page_mode := ?);
10535 if (not match(rr_imm_ass, expect_imm_ass)) {
10536 log("Error: expected ", expect_imm_ass, " got ", rr_imm_ass);
10537 setverdict(fail, "Failed to match Immediate Assignment");
10538 mtc.stop;
10539 }
10540}
10541
10542testcase TC_imm_ass_post_chan_ack() runs on test_CT {
10543 var RSL_Message chan_act;
10544 var RSL_Message imm_ass;
10545
10546 f_init(1, false);
10547 f_sleep(1.0);
10548
10549 /* (should be the default anyway, just to make things clear) */
10550 f_vty_set_imm_ass(BSCVTY, 0, "post-chan-ack");
10551
10552 /* RA containing reason=LU */
10553 var GsmFrameNumber fn := 2342;
10554 var uint8_t ra := 2;
10555 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10556
10557 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10558
10559 /* First send the Chan Act ACK */
10560 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010561 var DchanTuple dt;
10562 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010563 var RSL_IE_Body chan_ident_ie;
10564 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10565 setverdict(fail, "RSL Channel Identification IE is absent");
10566 mtc.stop;
10567 }
10568
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010569 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn + 10));
10570
10571 /* Then expect the Immediate Assignment, after we ACKed the chan act */
10572 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10573
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010574 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10575 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010576
10577 /* Check that the lchan is working */
10578 var octetstring l3 := '00010203040506'O;
10579 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10580
10581 var BSSAP_N_CONNECT_ind rx_c_ind;
10582 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010583 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010584 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10585
10586 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010587 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010588 f_shutdown_helper();
10589}
10590
10591testcase TC_imm_ass_pre_chan_ack() runs on test_CT {
10592 var RSL_Message chan_act;
10593 var RSL_Message imm_ass;
10594
10595 f_init(1, false);
10596 f_sleep(1.0);
10597
10598 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10599
10600 /* RA containing reason=LU */
10601 var GsmFrameNumber fn := 2342;
10602 var uint8_t ra := 2;
10603 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10604
10605 /* (set bts 0 cfg back to default) */
10606 f_vty_set_imm_ass(BSCVTY);
10607
10608 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10609 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010610 var DchanTuple dt;
10611 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010612 var RSL_IE_Body chan_ident_ie;
10613 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10614 setverdict(fail, "RSL Channel Identification IE is absent");
10615 mtc.stop;
10616 }
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010617
10618 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10619 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010620 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10621 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010622
10623 /* Only now send the Chan Act ACK */
10624 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10625
10626 /* Check that the lchan is working */
10627 var octetstring l3 := '00010203040506'O;
10628 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10629
10630 var BSSAP_N_CONNECT_ind rx_c_ind;
10631 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010632 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010633 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10634
10635 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010636 f_perform_clear_test_ct(dt);
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020010637 f_shutdown_helper();
10638}
10639
Neels Hofmeyr23158742021-09-07 19:08:07 +020010640testcase TC_imm_ass_pre_ts_ack() runs on test_CT {
10641 var RSL_Message chan_act;
10642 var RSL_Message imm_ass;
10643
10644 f_init(1, false);
10645 f_sleep(1.0);
10646
10647 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10648
10649 /* RA containing reason=LU */
10650 var GsmFrameNumber fn := 2342;
10651 var uint8_t ra := 2;
10652 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10653
10654 /* (set bts 0 cfg back to default) */
10655 f_vty_set_imm_ass(BSCVTY);
10656
10657 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
10658 var RslChannelNr chan_nr := chan_act.ies[0].body.chan_nr;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010659 var DchanTuple dt;
10660 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010661 var RSL_IE_Body chan_ident_ie;
10662 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10663 setverdict(fail, "RSL Channel Identification IE is absent");
10664 mtc.stop;
10665 }
10666
10667 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10668 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10669 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10670 chan_ident_ie.chan_ident.ch_desc.v.tsc);
10671
10672 /* Only now send the Chan Act ACK */
10673 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10674
10675 /* Check that the lchan is working */
10676 var octetstring l3 := '00010203040506'O;
10677 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10678
10679 var BSSAP_N_CONNECT_ind rx_c_ind;
10680 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010681 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr23158742021-09-07 19:08:07 +020010682 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10683
10684 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010685 f_perform_clear_test_ct(dt);
Neels Hofmeyr23158742021-09-07 19:08:07 +020010686 f_shutdown_helper();
10687}
10688
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010689testcase TC_imm_ass_pre_chan_ack_dyn_ts() runs on test_CT {
10690 /* change Timeslot 6 before f_init() starts RSL */
10691 f_init_vty();
10692 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10693 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10694
10695 f_init(1, false);
10696 f_sleep(1.0);
10697
10698 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10699 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010700 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010701 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10702
10703 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10704 f_ts_set_chcomb(0, 0, 6, "PDCH");
10705
10706 /* block all static timeslots so that the dyn TS will be used */
10707 f_disable_all_tch_f();
10708 f_disable_all_tch_h();
10709 f_disable_all_sdcch();
10710
10711 var RSL_Message chan_act;
10712 var RSL_Message imm_ass;
10713
10714 f_init(1, false);
10715 f_sleep(1.0);
10716
10717 f_vty_set_imm_ass(BSCVTY, 0, "pre-chan-ack");
10718
10719 /* RA containing reason=LU */
10720 var GsmFrameNumber fn := 2342;
10721 var uint8_t ra := 2;
10722 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10723
10724 /* (set bts 0 cfg back to default) */
10725 f_vty_set_imm_ass(BSCVTY);
10726
10727 /* Expect the dyn TS to deactivate PDCH first */
10728 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10729 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10730
10731 /* Now activation as SDCCH8 */
10732 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010733 var DchanTuple dt;
10734 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010735
10736 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010737 var RSL_IE_Body chan_ident_ie;
10738 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10739 setverdict(fail, "RSL Channel Identification IE is absent");
10740 mtc.stop;
10741 }
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010742
10743 /* *FIRST* expect the Immediate Assignment, before we ACK the chan act */
10744 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010745 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10746 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010747
10748 /* Only now send the Chan Act ACK */
10749 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10750
10751 /* Check that the lchan is working */
10752 var octetstring l3 := '00010203040506'O;
10753 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10754
10755 var BSSAP_N_CONNECT_ind rx_c_ind;
10756 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010757 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010758 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10759
10760 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010761 f_perform_clear_test_ct(dt);
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020010762 f_shutdown_helper();
10763}
10764
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010765testcase TC_imm_ass_pre_ts_ack_dyn_ts() runs on test_CT {
10766 /* change Timeslot 6 before f_init() starts RSL */
10767 f_init_vty();
10768 f_ts_set_chcomb(0, 0, 6, "TCH/F_TCH/H_PDCH");
10769 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
10770
10771 f_init(1, false);
10772 f_sleep(1.0);
10773
10774 var RslChannelNr chan_nr := valueof(t_RslChanNr_PDCH(6));
10775 /* The BSC will activate the dynamic PDCH by default, so confirm that */
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060010776 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010777 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2323));
10778
10779 /* clean up timeslot 6 config, will only take effect when the OML drops the next time */
10780 f_ts_set_chcomb(0, 0, 6, "PDCH");
10781
10782 /* block all static timeslots so that the dyn TS will be used */
10783 f_disable_all_tch_f();
10784 f_disable_all_tch_h();
10785 f_disable_all_sdcch();
10786
10787 var RSL_Message chan_act;
10788 var RSL_Message imm_ass;
10789
10790 f_init(1, false);
10791 f_sleep(1.0);
10792
10793 f_vty_set_imm_ass(BSCVTY, 0, "pre-ts-ack");
10794
10795 /* RA containing reason=LU */
10796 var GsmFrameNumber fn := 2342;
10797 var uint8_t ra := 2;
10798 f_ipa_tx(0, ts_RSL_CHAN_RQD(int2oct(ra, 1), fn));
10799
10800 /* (set bts 0 cfg back to default) */
10801 f_vty_set_imm_ass(BSCVTY);
10802
10803 /* Expect the dyn TS to deactivate PDCH first */
10804 f_exp_ipa_rx(0, tr_RSL_RF_CHAN_REL(chan_nr));
10805
10806 /* And already the Immediate Assignment even before the PDCH Deact ACK */
10807 imm_ass := f_exp_ipa_rx(0, tr_RSL_IMM_ASSIGN(0));
10808
10809 /* continue the Osmo style PDCH Deact (usual chan rel) */
10810 f_ipa_tx(0, ts_RSL_RF_CHAN_REL_ACK(chan_nr));
10811
10812 /* Now activation as SDCCH8 */
10813 chan_nr := valueof(t_RslChanNr_SDCCH8(tn := 6, sub_slot := 0));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010814 var DchanTuple dt;
10815 dt.rsl_chan_nr := chan_nr;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010816
10817 chan_act := f_exp_ipa_rx(0, tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV));
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010818 var RSL_IE_Body chan_ident_ie;
10819 if (not f_rsl_find_ie(chan_act, RSL_IE_CHAN_IDENT, chan_ident_ie)) {
10820 setverdict(fail, "RSL Channel Identification IE is absent");
10821 mtc.stop;
10822 }
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010823 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, fn+10));
10824
Neels Hofmeyr07603cf2021-09-07 19:05:52 +020010825 f_verify_imm_ass(imm_ass, ra, fn, chan_nr, chan_ident_ie.chan_ident.ch_desc.v.arfcn,
10826 chan_ident_ie.chan_ident.ch_desc.v.tsc);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010827
10828 /* Check that the lchan is working */
10829 var octetstring l3 := '00010203040506'O;
10830 f_ipa_tx(0, ts_RSL_EST_IND(chan_nr, valueof(ts_RslLinkID_DCCH(0)), l3));
10831
10832 var BSSAP_N_CONNECT_ind rx_c_ind;
10833 BSSAP.receive(tr_BSSAP_CONNECT_ind(?, ?, tr_BSSMAP_ComplL3(l3))) -> value rx_c_ind;
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010834 dt.sccp_conn_id := rx_c_ind.connectionId;
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010835 BSSAP.send(ts_BSSAP_CONNECT_res(rx_c_ind.connectionId));
10836
10837 f_sleep(1.0);
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010838 f_perform_clear_test_ct(dt);
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020010839 f_shutdown_helper();
10840}
10841
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020010842/* GET and SET the bts.N.trx.M.rf_locked CTRL variable */
10843testcase TC_ctrl_trx_rf_locked() runs on test_CT {
10844 var MSC_ConnHdlr vc_conn;
10845
10846 f_init(nr_bts := 2, handler_mode := true, nr_msc := 1);
10847 f_sleep(1.0);
10848
10849 /* BTS 0, 1, 2 are OML unlocked, only BTS 0, 1 are actually connected to RSL. */
10850 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10851 "0,0,operational,unlocked,on,rsl-up;" &
10852 "1,0,operational,unlocked,on,rsl-up;" &
10853 "2,0,operational,unlocked,on,rsl-down;" &
10854 "3,0,inoperational,locked,on,rsl-down;");
10855
10856 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock BTS 1 TRX 0");
10857 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10858 /* give it a moment to settle the FSM status */
10859 f_sleep(1.0);
10860
10861 /* Now BTS 1 TRX 0 should reflect "locked". Note the RF policy stays "on", because this is still handled
10862 * globally in osmo-bsc. Probably after sending "rf_locked 1" for a TRX, that TRX should reflect an RF policy
10863 * of "off"? But that's for a future patch if at all. */
10864 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10865 "0,0,operational,unlocked,on,rsl-up;" &
10866 "1,0,operational,locked,on,rsl-up;" &
10867 "2,0,operational,unlocked,on,rsl-down;" &
10868 "3,0,inoperational,locked,on,rsl-down;");
10869
10870 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: lock the already locked TRX, nothing should change");
10871 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "1");
10872 f_sleep(1.0);
10873 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10874 "0,0,operational,unlocked,on,rsl-up;" &
10875 "1,0,operational,locked,on,rsl-up;" &
10876 "2,0,operational,unlocked,on,rsl-down;" &
10877 "3,0,inoperational,locked,on,rsl-down;");
10878
10879 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock BTS 1 TRX 0");
10880 f_ctrl_set(IPA_CTRL, "bts.1.trx.0.rf_locked", "0");
10881 f_sleep(1.0);
10882 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10883 "0,0,operational,unlocked,on,rsl-up;" &
10884 "1,0,operational,unlocked,on,rsl-up;" &
10885 "2,0,operational,unlocked,on,rsl-down;" &
10886 "3,0,inoperational,locked,on,rsl-down;");
10887
10888 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an already unlocked TRX, nothing should change");
10889 f_ctrl_set(IPA_CTRL, "bts.0.trx.0.rf_locked", "0");
10890 f_sleep(1.0);
10891 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10892 "0,0,operational,unlocked,on,rsl-up;" &
10893 "1,0,operational,unlocked,on,rsl-up;" &
10894 "2,0,operational,unlocked,on,rsl-down;" &
10895 "3,0,inoperational,locked,on,rsl-down;");
10896
10897 f_logp(BSCVTY, "TC_ctrl_trx_rf_locked: unlock an inoperational TRX");
10898 f_ctrl_set(IPA_CTRL, "bts.3.trx.0.rf_locked", "0");
10899 f_sleep(1.0);
10900 f_ctrl_get_exp(IPA_CTRL, "rf_states",
10901 "0,0,operational,unlocked,on,rsl-up;" &
10902 "1,0,operational,unlocked,on,rsl-up;" &
10903 "2,0,operational,unlocked,on,rsl-down;" &
10904 "3,0,inoperational,locked,on,rsl-down;");
10905
10906 f_shutdown_helper();
10907}
10908
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010909const CounterNameVals counternames_cm_serv_rej := {
10910 { "cm_serv_rej", 0 },
10911 { "cm_serv_rej:imsi_unknown_in_hlr", 0 },
10912 { "cm_serv_rej:illegal_ms", 0 },
10913 { "cm_serv_rej:imsi_unknown_in_vlr", 0 },
10914 { "cm_serv_rej:imei_not_accepted", 0 },
10915 { "cm_serv_rej:illegal_me", 0 },
10916 { "cm_serv_rej:plmn_not_allowed", 0 },
10917 { "cm_serv_rej:loc_not_allowed", 0 },
10918 { "cm_serv_rej:roaming_not_allowed", 0 },
10919 { "cm_serv_rej:network_failure", 0 },
10920 { "cm_serv_rej:synch_failure", 0 },
10921 { "cm_serv_rej:congestion", 0 },
10922 { "cm_serv_rej:srv_opt_not_supported", 0 },
10923 { "cm_serv_rej:rqd_srv_opt_not_supported", 0 },
10924 { "cm_serv_rej:srv_opt_tmp_out_of_order", 0 },
10925 { "cm_serv_rej:call_can_not_be_identified", 0 },
10926 { "cm_serv_rej:incorrect_message", 0 },
10927 { "cm_serv_rej:invalid_mandantory_inf", 0 },
10928 { "cm_serv_rej:msg_type_not_implemented", 0 },
10929 { "cm_serv_rej:msg_type_not_compatible", 0 },
10930 { "cm_serv_rej:inf_eleme_not_implemented", 0 },
10931 { "cm_serv_rej:condtional_ie_error", 0 },
10932 { "cm_serv_rej:msg_not_compatible", 0 },
10933 { "cm_serv_rej:protocol_error", 0 },
10934 { "cm_serv_rej:retry_in_new_cell", 0 }
10935};
10936
10937private function f_TC_cm_serv_rej(charstring id) runs on MSC_ConnHdlr
10938{
10939 f_create_chan_and_exp();
Vadim Yanitskiya7fc5a62021-12-04 20:10:08 +030010940 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010941 BSSAP.send(ts_PDU_DTAP_MT(ts_CM_SERV_REJ('02'O), '00'O));
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010010942 RSL.receive(tr_RSL_DATA_REQ(g_chan_nr, ?, decmatch tr_CM_SERV_REJ));
10943 f_perform_clear();
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010944 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010945}
10946testcase TC_cm_serv_rej() runs on test_CT {
10947 var TestHdlrParams pars := f_gen_test_hdlr_pars();
10948 var MSC_ConnHdlr vc_conn;
10949
10950 f_init(1, true);
10951 f_sleep(1.0);
10952
10953 f_ctrs_bts_init(1, counternames_cm_serv_rej);
10954
10955 vc_conn := f_start_handler(refers(f_TC_cm_serv_rej), pars);
10956 vc_conn.done;
10957
10958 f_ctrs_bts_add(0, "cm_serv_rej", 1);
10959 f_ctrs_bts_add(0, "cm_serv_rej:imsi_unknown_in_hlr", 1);
10960 f_ctrs_bts_verify();
10961
Neels Hofmeyr87a65612021-11-16 15:56:45 +010010962 f_sleep(1.0);
Neels Hofmeyrb7581872021-11-07 14:02:49 +010010963 f_shutdown_helper();
10964}
10965
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010966/* Reproduce a segfault happening when the SDCCH (primary) lchan is lost in-between a TCH Channel Activ and its Channel
10967 * Activ Ack (SYS#5627). */
10968private function f_TC_lost_sdcch_during_assignment(charstring id) runs on MSC_ConnHdlr {
10969 var PDU_BSSAP ass_cmd := f_gen_ass_req();
Vadim Yanitskiyf0310e32021-10-26 00:30:59 +030010970
10971 ass_cmd.pdu.bssmap.assignmentRequest.channelType := valueof(ts_BSSMAP_IE_ChannelType);
10972 ass_cmd.pdu.bssmap.assignmentRequest.codecList := valueof(ts_BSSMAP_IE_CodecList({ts_CodecFR}));
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010973
10974 var BSSMAP_FIELD_CodecType codecType;
10975 codecType := valueof(ass_cmd.pdu.bssmap.assignmentRequest.codecList.codecElements[0].codecType);
10976
10977 f_MscConnHdlr_init(g_pars.media_nr, host_bts, host_mgw_mgcp, codecType);
10978
10979 /* First establish a signalling lchan */
10980 f_create_chan_and_exp();
10981 f_rslem_dchan_queue_enable();
10982
10983 /* we should now have a COMPL_L3 at the MSC */
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020010984
10985 f_create_mgcp_expect(ExpectCriteria:{omit,omit,omit});
10986 activate(as_Media_mgw());
10987
10988 var RslChannelNr chan_nr := { u := { ch0 := RSL_CHAN_NR_Bm_ACCH }, tn := 1 };
10989 f_rslem_register(0, chan_nr);
10990
10991 f_rslem_set_auto_chan_act_ack(RSL_PROC, false);
10992 BSSAP.send(ass_cmd);
10993
10994
10995 /* Wait for the Channel Activ for the TCH channel */
10996 var ASP_RSL_Unitdata rx_rsl_ud;
10997 RSL.receive(tr_ASP_RSL_UD(tr_RSL_MsgTypeD(RSL_MT_CHAN_ACTIV), sid := ?)) -> value rx_rsl_ud;
10998
10999 /* make the original SDCCH disappear */
11000 RSL.send(ts_RSL_REL_IND(g_chan_nr, valueof(ts_RslLinkID_DCCH(0))));
11001
11002 /* and ACK the TCH channel activation. This caused a segfault up to OsmoBSC 1.7.0 (SYS#5627) */
11003 RSL.send(ts_ASP_RSL_UD(ts_RSL_CHAN_ACT_ACK(chan_nr, 23), rx_rsl_ud.streamId));
11004
11005 interleave {
11006 [] BSSAP.receive(tr_BSSMAP_AssignmentFail);
11007 [] BSSAP.receive(tr_BSSMAP_ClearRequest);
11008 }
11009
11010 BSSAP.send(ts_BSSMAP_ClearCommand(0));
11011 BSSAP.receive(tr_BSSMAP_ClearComplete);
11012 BSSAP.send(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_REQ);
11013
11014 var MgcpCommand mgcp;
11015 MGCP.receive(tr_DLCX()) -> value mgcp {
11016 MGCP.send(ts_DLCX_ACK2(mgcp.line.trans_id));
11017 };
11018
11019 f_sleep(0.5);
11020}
11021testcase TC_lost_sdcch_during_assignment() runs on test_CT {
11022 var TestHdlrParams pars := f_gen_test_hdlr_pars();
11023 var MSC_ConnHdlr vc_conn;
11024
11025 f_init(1, true);
11026 f_sleep(1.0);
11027
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011028 vc_conn := f_start_handler(refers(f_TC_lost_sdcch_during_assignment), pars);
11029 vc_conn.done;
11030
11031 f_shutdown_helper();
11032}
11033
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011034const CounterNameVals counternames_bsc_bts_all_available_allocated := {
11035 { "all_allocated:sdcch", 0 },
11036 { "all_allocated:static_sdcch", 0 },
11037 { "all_allocated:tch", 0 },
11038 { "all_allocated:static_tch", 0 }
11039}
11040
11041private function f_all_allocated_expect_counter_change(charstring_list expect_changed) runs on test_CT
11042{
11043 /* Make sure counters settle first */
11044 f_sleep(1.0);
11045
11046 /* Take a baseline of counters */
11047 f_ctrs_bsc_and_bts_init(1, counternames_bsc_bts_all_available_allocated);
11048
11049 /* Elapse some time so that we see changes in counters, hopefully where expected */
11050 f_sleep(2.0);
11051
11052 /* Get new counters */
11053 var charstring_list all_changed := {};
11054 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bsc", g_ctr_bsc);
11055 all_changed := all_changed & f_counter_name_vals_get_changed_n(IPA_CTRL, "bts", g_ctr_bts);
11056
11057 /* Compare with expectations */
11058 var charstring_list all_expect_changed := {};
11059 for (var integer i := 0; i < lengthof(expect_changed); i := i + 1) {
11060 all_expect_changed := all_expect_changed & { "bsc.0." & expect_changed[i], "bts.0." & expect_changed[i] };
11061 }
11062 f_counter_name_vals_expect_changed_list(all_changed, all_expect_changed);
11063}
11064
11065testcase TC_ratectr_all_available_allocated() runs on test_CT {
11066 var ASP_RSL_Unitdata rsl_ud;
11067 var integer i;
11068 var integer chreq_total, chreq_nochan;
11069
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011070 f_init(1, guard_timeout := 60.0);
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011071 f_sleep(1.0);
11072
11073 /* Exhaust all dedicated SDCCH lchans.
11074 /* GSM 44.018 Table 9.1.8.2:
11075 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11076 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011077 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011078 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011079 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011080 }
11081
11082 /* Since only bts 0 is connected, expecting all_allocated to become true for both bts 0 and the "global" bsc
11083 * level.
11084 * All SDCCH are now occupied. */
11085 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11086
11087 /* Also fill up all remaining (TCH) channels */
11088 for (i := 0; i < NUM_TCHF_PER_BTS + NUM_TCHH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011089 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011090 }
11091
11092 /* All TCH are now also occupied */
11093 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11094 "all_allocated:tch", "all_allocated:static_tch"});
11095
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011096 /* Clean up SDCCH lchans */
11097 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11098 f_perform_clear_test_ct(chan_cleanup[i]);
11099 }
11100
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011101 f_shutdown_helper();
11102}
11103
11104testcase TC_ratectr_all_available_allocated_dyn() runs on test_CT {
11105 var ASP_RSL_Unitdata rsl_ud;
11106 var integer i;
11107 var integer chreq_total, chreq_nochan;
11108
11109 f_init_vty();
11110 f_ts_set_chcomb(0, 0, 2, "TCH/F_TCH/H_PDCH");
11111 f_vty_transceive(BSCVTY, "drop bts connection 0 oml");
11112 /* Now we have 3 TCH/F, 1 OSMO_DYN, 1 TCH/H */
11113
11114 f_init(1, guard_timeout := 60.0);
11115 f_sleep(1.0);
11116
11117 /* The dyn TS wants to activate PDCH mode, ACK that. */
11118 var RslChannelNr chan_nr;
11119 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011120 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011121 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11122
11123 /* Exhaust all dedicated SDCCH lchans.
11124 /* GSM 44.018 Table 9.1.8.2:
11125 * RA = '13'O -> Establishment cause = 0001xxxx (MS dual rate capable and asks for "SDCCH").
11126 */
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011127 var DchanTuples chan_cleanup := {};
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011128 for (i := 0; i < NUM_SDCCH_PER_BTS; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011129 chan_cleanup := chan_cleanup & { f_est_dchan('13'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011130 }
11131
11132 /* The static SDCCH should now be occupied, while still 3x8 dynamic SDCCH potentially remain. So only
11133 * all_allocated:static_sdcch is counted, all_allocated:sdcch remains zero. */
11134 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch"});
11135
11136 /* Request more SDCCH, hence convert the first dyn TS to SDCCH8.
11137 * Will release them later, so remember all the DchanTuples. */
11138 var DchanTuples dyn_sddch := {};
11139 dyn_sddch := dyn_sddch & { f_est_dchan_dyn('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11140
11141 /* Also occupy the seven other SDCCH of the dyn TS */
11142 for (i := 0; i < 7; i := i+1) {
11143 dyn_sddch := dyn_sddch & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
11144 }
11145
11146 /* Now all dynamic SDCCH are also occupied, so for the first time all_allocated:sdcch will trigger... */
11147 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch"});
11148
11149 /* occupy the remaining TCH, three TCH/F and two TCH/H lchans */
11150 for (i := 0; i < 5; i := i+1) {
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011151 chan_cleanup := chan_cleanup & { f_est_dchan('33'O, NUM_SDCCH_PER_BTS + i, '00010203040506'O) };
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011152 }
11153
11154 /* All TCH lchans are now also occupied, both static and dynamic */
11155 f_all_allocated_expect_counter_change({"all_allocated:sdcch", "all_allocated:static_sdcch",
11156 "all_allocated:tch", "all_allocated:static_tch"});
11157
11158 /* Starting to release the dyn TS: as soon as the first SDCCH gets released, all_allocated:sdcch stops
11159 * incrementing. */
11160 var BssmapCause cause := 0;
11161 var DchanTuple dt := dyn_sddch[0];
11162 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11163 f_exp_chan_rel_and_clear(dt, 0);
11164
11165 /* one dyn TS SDCCH is free again, so only the static_sdcch should increment. For tch, both static and dynamic
11166 * count as occupied, so those still both increment. */
11167 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch",
11168 "all_allocated:tch", "all_allocated:static_tch"});
11169
11170 /* Release the remaining SDCCH of the dyn TS, so it becomes available as TCH again */
11171 for (i := 1; i < lengthof(dyn_sddch); i := i+1) {
11172 dt := dyn_sddch[i];
11173 BSSAP.send(ts_BSSAP_DATA_req(dt.sccp_conn_id, ts_BSSMAP_ClearCommand(cause)));
11174 f_exp_chan_rel_and_clear(dt, 0);
11175 }
11176
11177 /* All SDCCH on the dyn TS are released, the dyn TS wants to activate PDCH again */
11178 chan_nr := valueof(t_RslChanNr_PDCH(2));
Vadim Yanitskiy58b16532021-10-09 20:27:39 +060011179 f_exp_ipa_rx(0, tr_RSL_CHAN_ACT_PDCH(chan_nr));
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011180 f_ipa_tx(0, ts_RSL_CHAN_ACT_ACK(chan_nr, 2342));
11181
11182 /* Now all channels are occupied except the dyn TS, so expecting only the static counters to increment */
11183 f_all_allocated_expect_counter_change({"all_allocated:static_sdcch", "all_allocated:static_tch"});
11184
Neels Hofmeyr4d4cd7e2021-12-14 17:25:36 +010011185 /* Clean up SDCCH lchans */
11186 for (i := 0; i < lengthof(chan_cleanup); i := i + 1) {
11187 f_perform_clear_test_ct(chan_cleanup[i]);
11188 }
11189
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011190 /* clean up config */
11191 f_ts_reset_chcomb(0);
11192
11193 f_shutdown_helper();
11194}
11195
Harald Welte28d943e2017-11-25 15:00:50 +010011196control {
Harald Welte898113b2018-01-31 18:32:21 +010011197 /* CTRL interface testing */
Harald Welte4003d112017-12-09 22:35:39 +010011198 execute( TC_ctrl_msc_connection_status() );
Stefan Sperlingb041b3d2018-01-03 17:14:55 +010011199 execute( TC_ctrl_msc0_connection_status() );
Neels Hofmeyrf65ce872021-09-23 18:40:10 +020011200 /* In SCCPlite tests, only one MSC is configured. These tests assume that three MSCs are configured, so only run
11201 * these in the AoIP test suite. */
11202 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11203 execute( TC_stat_num_msc_connected_1() );
11204 execute( TC_stat_num_msc_connected_2() );
11205 execute( TC_stat_num_msc_connected_3() );
11206 }
Neels Hofmeyr5ce3ae42021-08-29 15:32:00 +020011207 execute( TC_stat_num_bts_connected_1() );
11208 execute( TC_stat_num_bts_connected_2() );
11209 execute( TC_stat_num_bts_connected_3() );
Harald Welte96c94412017-12-09 03:12:45 +010011210 execute( TC_ctrl() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011211 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_SCCPlite_SERVER) {
Pau Espin Pedrol5a2d7432019-06-07 19:43:45 +020011212 execute( TC_ctrl_location() );
11213 }
Harald Welte898113b2018-01-31 18:32:21 +010011214
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011215 execute( TC_si_default() );
Neels Hofmeyr66aeba42020-07-06 02:21:21 +020011216 execute( TC_si2quater_2_earfcns() );
11217 execute( TC_si2quater_3_earfcns() );
11218 execute( TC_si2quater_4_earfcns() );
11219 execute( TC_si2quater_5_earfcns() );
11220 execute( TC_si2quater_6_earfcns() );
Neels Hofmeyrad132f22020-07-08 02:20:16 +020011221 execute( TC_si2quater_12_earfcns() );
11222 execute( TC_si2quater_23_earfcns() );
11223 execute( TC_si2quater_32_earfcns() );
11224 execute( TC_si2quater_33_earfcns() );
11225 execute( TC_si2quater_42_earfcns() );
11226 execute( TC_si2quater_48_earfcns() );
11227 execute( TC_si2quater_49_earfcns() );
Pau Espin Pedrol85a84432020-07-20 18:45:03 +020011228 execute( TC_si_acc_rotate() );
Alexander Couzens4ad3a352020-09-10 22:29:12 +020011229 execute( TC_si_acc_ramp_rotate() );
Neels Hofmeyr5e686dc2020-06-30 01:26:53 +020011230
Harald Welte898113b2018-01-31 18:32:21 +010011231 /* RSL DCHAN Channel ACtivation / Deactivation */
Harald Welteae026692017-12-09 01:03:01 +010011232 execute( TC_chan_act_noreply() );
Harald Welte4003d112017-12-09 22:35:39 +010011233 execute( TC_chan_act_counter() );
Harald Welteae026692017-12-09 01:03:01 +010011234 execute( TC_chan_act_ack_noest() );
Philipp Maier9c60a622020-07-09 15:08:46 +020011235 execute( TC_chan_act_ack_noest_emerg() );
Philipp Maier606f07d2020-08-12 17:21:58 +020011236 execute( TC_chan_rqd_emerg_deny() );
Harald Welteae026692017-12-09 01:03:01 +010011237 execute( TC_chan_act_ack_est_ind_noreply() );
11238 execute( TC_chan_act_ack_est_ind_refused() );
Harald Welte618ef642017-12-14 14:58:20 +010011239 execute( TC_chan_act_nack() );
Harald Welte799c97b2017-12-14 17:50:30 +010011240 execute( TC_chan_exhaustion() );
Vadim Yanitskiy1ff1fdf2018-11-27 01:32:57 +070011241 execute( TC_chan_deact_silence() );
Harald Welte4003d112017-12-09 22:35:39 +010011242 execute( TC_chan_rel_rll_rel_ind() );
11243 execute( TC_chan_rel_conn_fail() );
11244 execute( TC_chan_rel_hard_clear() );
Pau Espin Pedrol841b90d2021-04-15 16:42:52 +020011245 execute( TC_chan_rel_last_eutran_plmn_hard_clear_no_csfb() );
11246 execute( TC_chan_rel_last_eutran_plmn_hard_clear_csfb() );
Harald Welte99787102019-02-04 10:41:36 +010011247 execute( TC_chan_rel_hard_clear_csfb() );
Harald Welted8c36cd2017-12-09 23:05:31 +010011248 execute( TC_chan_rel_hard_rlsd() );
Harald Welte550daf92018-06-11 19:22:13 +020011249 execute( TC_chan_rel_hard_rlsd_ms_dead() );
Harald Welte85804d42017-12-10 14:11:58 +010011250 execute( TC_chan_rel_a_reset() );
Pau Espin Pedrolc675b612020-01-09 19:55:40 +010011251 execute( TC_chan_rel_sccp_tiar_timeout() );
Neels Hofmeyr95a5edc2020-07-11 02:57:04 +020011252 execute( TC_chan_rel_rr_cause() );
Harald Welte6f521d82017-12-11 19:52:02 +010011253
Harald Weltecfe2c962017-12-15 12:09:32 +010011254 execute( TC_outbound_connect() );
Harald Welte898113b2018-01-31 18:32:21 +010011255
11256 /* Assignment related */
Harald Welte16a4adf2017-12-14 18:54:01 +010011257 execute( TC_assignment_cic_only() );
Harald Welte235ebf12017-12-15 14:18:16 +010011258 execute( TC_assignment_csd() );
11259 execute( TC_assignment_ctm() );
11260 execute( TC_assignment_sign() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011261 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11262 execute( TC_assignment_aoip_tla_v6() );
11263 }
Harald Welte235ebf12017-12-15 14:18:16 +010011264 execute( TC_assignment_fr_a5_0() );
11265 execute( TC_assignment_fr_a5_1() );
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011266 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Harald Welte8f67d1d2018-05-25 20:38:42 +020011267 execute( TC_assignment_fr_a5_1_codec_missing() );
11268 }
Harald Welte235ebf12017-12-15 14:18:16 +010011269 execute( TC_assignment_fr_a5_3() );
Neels Hofmeyr0d8ec532021-06-11 00:09:48 +020011270 execute( TC_assignment_fr_a5_4() );
Neels Hofmeyr0faeb7a2021-06-10 23:59:35 +020011271 execute( TC_assignment_fr_a5_4_fail() );
Neels Hofmeyr04d6e6a2021-06-11 00:10:02 +020011272 execute( TC_assignment_fr_a5_not_sup() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011273 execute( TC_ciph_mode_a5_0() );
11274 execute( TC_ciph_mode_a5_1() );
Oliver Smith50b98122021-07-09 15:00:28 +020011275 execute( TC_ciph_mode_a5_2_0() );
Oliver Smith1dff88d2021-07-09 08:45:51 +020011276 execute( TC_ciph_mode_a5_2_1() );
Harald Welte3c86ea02018-05-10 22:28:05 +020011277 execute( TC_ciph_mode_a5_3() );
Neels Hofmeyr81ad27f2021-06-11 00:09:40 +020011278 execute( TC_ciph_mode_a5_4() );
Harald Welte16a4adf2017-12-14 18:54:01 +010011279
Harald Welte60aa5762018-03-21 19:33:13 +010011280 execute( TC_assignment_codec_fr() );
Neels Hofmeyr559d5d02021-04-16 16:50:49 +020011281 execute( TC_assignment_codec_fr_by_mode_modify() );
Harald Welte60aa5762018-03-21 19:33:13 +010011282 execute( TC_assignment_codec_hr() );
11283 execute( TC_assignment_codec_efr() );
11284 execute( TC_assignment_codec_amr_f() );
11285 execute( TC_assignment_codec_amr_h() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011286
Neels Hofmeyrf246a922020-05-13 02:27:10 +020011287 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
Philipp Maier8a581d22019-03-26 18:32:48 +010011288 execute( TC_assignment_codec_amr_f_S1() );
11289 execute( TC_assignment_codec_amr_h_S1() );
11290 execute( TC_assignment_codec_amr_f_S124() );
11291 execute( TC_assignment_codec_amr_h_S124() );
11292 execute( TC_assignment_codec_amr_f_S0() );
11293 execute( TC_assignment_codec_amr_f_S02() );
11294 execute( TC_assignment_codec_amr_f_S024() );
11295 execute( TC_assignment_codec_amr_f_S0247() );
11296 execute( TC_assignment_codec_amr_h_S0() );
11297 execute( TC_assignment_codec_amr_h_S02() );
11298 execute( TC_assignment_codec_amr_h_S024() );
11299 execute( TC_assignment_codec_amr_h_S0247() );
11300 execute( TC_assignment_codec_amr_f_S01234567() );
11301 execute( TC_assignment_codec_amr_f_S0234567() );
11302 execute( TC_assignment_codec_amr_f_zero() );
11303 execute( TC_assignment_codec_amr_f_unsupp() );
11304 execute( TC_assignment_codec_amr_h_S7() );
Neels Hofmeyr21863562020-11-26 00:34:33 +000011305 execute( TC_assignment_codec_amr_f_start_mode_auto() );
11306 execute( TC_assignment_codec_amr_h_start_mode_auto() );
Neels Hofmeyr3eb94562020-11-26 02:40:26 +000011307 execute( TC_assignment_codec_amr_f_start_mode_4() );
11308 execute( TC_assignment_codec_amr_h_start_mode_4() );
Neels Hofmeyr454d7922020-11-26 02:24:57 +000011309 execute( TC_assignment_codec_amr_startmode_cruft() );
Philipp Maier8a581d22019-03-26 18:32:48 +010011310 }
Harald Welte60aa5762018-03-21 19:33:13 +010011311
Philipp Maierac09bfc2019-01-08 13:41:39 +010011312 execute( TC_assignment_codec_fr_exhausted_req_hr() );
11313 execute( TC_assignment_codec_fr_exhausted_req_fr() );
11314 execute( TC_assignment_codec_fr_exhausted_req_fr_hr() );
11315 execute( TC_assignment_codec_fr_exhausted_req_hr_fr() );
11316 execute( TC_assignment_codec_hr_exhausted_req_fr() );
11317 execute( TC_assignment_codec_hr_exhausted_req_hr() );
11318 execute( TC_assignment_codec_hr_exhausted_req_hr_fr() );
11319 execute( TC_assignment_codec_hr_exhausted_req_fr_hr() );
11320 execute( TC_assignment_codec_req_hr_fr() );
11321 execute( TC_assignment_codec_req_fr_hr() );
Pau Espin Pedrol14475352021-07-22 15:48:16 +020011322 execute( TC_assignment_sdcch_exhausted_req_signalling() );
11323 execute( TC_assignment_sdcch_exhausted_req_signalling_tch_forbidden() );
11324 execute( TC_assignment_sdcch_exhausted_req_voice_tch_forbidden() );
Philipp Maierac09bfc2019-01-08 13:41:39 +010011325
Pau Espin Pedrol23510fb2021-07-20 17:00:38 +020011326 execute( TC_assignment_osmux() );
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020011327
Harald Welte898113b2018-01-31 18:32:21 +010011328 /* RLL Establish Indication on inactive DCHAN / SAPI */
Harald Welte5cd20ed2017-12-13 21:03:20 +010011329 execute( TC_rll_est_ind_inact_lchan() );
11330 execute( TC_rll_est_ind_inval_sapi1() );
11331 execute( TC_rll_est_ind_inval_sapi3() );
11332 execute( TC_rll_est_ind_inval_sacch() );
11333
Vadim Yanitskiy61f784a2020-10-01 21:12:19 +070011334 /* DLCI / RSL Link ID conversion for MO/MT messages on SAPI0/SAPI3 */
11335 execute( TC_tch_dlci_link_id_sapi() );
11336
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011337 /* SAPI N Reject triggered by RLL establishment failures */
11338 execute( TC_rll_rel_ind_sapi_n_reject() );
11339 execute( TC_rll_err_ind_sapi_n_reject() );
11340 execute( TC_rll_timeout_sapi_n_reject() );
Vadim Yanitskiy999ceb62020-10-04 00:04:49 +070011341 execute( TC_rll_sapi_n_reject_dlci_cc() );
Vadim Yanitskiy6ef5dfa2020-08-28 18:04:41 +070011342
Harald Welte898113b2018-01-31 18:32:21 +010011343 /* Paging related tests */
Harald Welte6f521d82017-12-11 19:52:02 +010011344 execute( TC_paging_imsi_nochan() );
11345 execute( TC_paging_tmsi_nochan() );
11346 execute( TC_paging_tmsi_any() );
11347 execute( TC_paging_tmsi_sdcch() );
11348 execute( TC_paging_tmsi_tch_f() );
11349 execute( TC_paging_tmsi_tch_hf() );
11350 execute( TC_paging_imsi_nochan_cgi() );
11351 execute( TC_paging_imsi_nochan_lac_ci() );
11352 execute( TC_paging_imsi_nochan_ci() );
11353 execute( TC_paging_imsi_nochan_lai() );
11354 execute( TC_paging_imsi_nochan_lac() );
11355 execute( TC_paging_imsi_nochan_all() );
Harald Welte751d3eb2018-01-31 15:51:06 +010011356 execute( TC_paging_imsi_nochan_plmn_lac_rnc() );
11357 execute( TC_paging_imsi_nochan_rnc() );
11358 execute( TC_paging_imsi_nochan_lac_rnc() );
11359 execute( TC_paging_imsi_nochan_lacs() );
11360 execute( TC_paging_imsi_nochan_lacs_empty() );
Stefan Sperling049a86e2018-03-20 15:51:00 +010011361 execute( TC_paging_imsi_nochan_cgi_unknown_cid() );
Harald Welte10985002017-12-12 09:29:15 +010011362 execute( TC_paging_imsi_a_reset() );
Harald Weltee65d40e2017-12-13 00:09:06 +010011363 execute( TC_paging_imsi_load() );
Philipp Maier779a7922018-02-16 11:00:37 +010011364 execute( TC_paging_counter() );
Pau Espin Pedrol3466cc52018-11-05 12:41:05 +010011365 execute( TC_paging_resp_unsol() );
Harald Welte4e9b9cc2017-12-14 18:31:02 +010011366
11367 execute( TC_rsl_drop_counter() );
Stefan Sperling830dc9d2018-02-12 21:08:28 +010011368 execute( TC_rsl_unknown_unit_id() );
11369
11370 execute( TC_oml_unknown_unit_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011371
11372 execute( TC_classmark() );
Harald Welteeddf0e92020-06-21 19:42:15 +020011373 execute( TC_common_id() );
Harald Welte898113b2018-01-31 18:32:21 +010011374 execute( TC_unsol_ass_fail() );
Harald Welteea99a002018-01-31 20:46:43 +010011375 execute( TC_unsol_ass_compl() );
Harald Weltefbf9b5e2018-01-31 20:41:23 +010011376 execute( TC_unsol_ho_fail() );
Harald Weltee3bd6582018-01-31 22:51:25 +010011377 execute( TC_err_82_short_msg() );
Harald Weltee9e02e42018-01-31 23:36:25 +010011378 execute( TC_err_84_unknown_msg() );
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011379
Harald Welte261af4b2018-02-12 21:20:39 +010011380 execute( TC_ho_int() );
Neels Hofmeyraf88d9d2021-06-21 02:14:27 +020011381 execute( TC_ho_int_a5_0() );
11382 execute( TC_ho_int_a5_1() );
11383 execute( TC_ho_int_a5_3() );
11384 execute( TC_ho_int_a5_4() );
Neels Hofmeyr5f144212020-11-03 15:41:58 +000011385 execute( TC_ho_int_radio_link_failure() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011386
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011387 /* TC_ho_out_of_this_bsc is run last, see comment below */
Neels Hofmeyr61ebb8b2018-10-09 18:28:06 +020011388 execute( TC_ho_out_fail_no_msc_response() );
11389 execute( TC_ho_out_fail_rr_ho_failure() );
Neels Hofmeyrd8a602c2019-07-09 19:46:01 +020011390 execute( TC_ho_out_fail_no_result_after_ho_cmd() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011391
Neels Hofmeyrbd0ef932018-03-19 14:58:46 +010011392 execute( TC_ho_into_this_bsc() );
Neels Hofmeyr8ebf19c2021-06-21 05:24:01 +020011393 execute( TC_ho_into_this_bsc_a5_0() );
11394 execute( TC_ho_into_this_bsc_a5_1() );
11395 execute( TC_ho_into_this_bsc_a5_3() );
11396 execute( TC_ho_into_this_bsc_a5_4() );
Neels Hofmeyr93182e02022-02-17 21:59:07 +010011397 execute( TC_ho_into_this_bsc_a5_1_3_no_chosen_enc_alg() );
11398 execute( TC_ho_into_this_bsc_a5_1_3() );
Neels Hofmeyr907b23b2022-02-17 21:58:47 +010011399 execute( TC_ho_into_this_bsc_a5_mismatch() );
Pau Espin Pedrol07866632020-09-03 19:10:55 +020011400 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11401 execute( TC_ho_into_this_bsc_tla_v6() );
11402 }
Pau Espin Pedrolc08d5522021-04-16 15:40:38 +020011403 execute( TC_srvcc_eutran_to_geran() );
Vadim Yanitskiy634f75d2022-03-14 17:04:45 +030011404 execute( TC_srvcc_eutran_to_geran_a5_3() );
Pau Espin Pedrola8ef3be2022-02-16 16:21:17 +010011405 execute( TC_srvcc_eutran_to_geran_src_sai() );
Pau Espin Pedrol35801c32021-04-19 13:03:20 +020011406 execute( TC_srvcc_eutran_to_geran_ho_out() );
Pau Espin Pedrol9ae36d52021-06-15 17:29:43 +020011407 execute( TC_srvcc_eutran_to_geran_forbid_fast_return() );
11408 execute( TC_srvcc_eutran_to_geran_ho_out_forbid_fast_return() );
Neels Hofmeyr20bc3e22018-11-09 01:40:16 +010011409 execute( TC_ho_in_fail_msc_clears() );
11410 execute( TC_ho_in_fail_msc_clears_after_ho_detect() );
11411 execute( TC_ho_in_fail_no_detect() );
11412 execute( TC_ho_in_fail_no_detect2() );
Neels Hofmeyra23f3b12022-03-02 19:57:12 +010011413 execute( TC_ho_into_this_bsc_sccp_cr_without_bssap() );
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011414
Neels Hofmeyr91401012019-07-11 00:42:35 +020011415 execute( TC_ho_neighbor_config_1() );
11416 execute( TC_ho_neighbor_config_2() );
11417 execute( TC_ho_neighbor_config_3() );
11418 execute( TC_ho_neighbor_config_4() );
11419 execute( TC_ho_neighbor_config_5() );
11420 execute( TC_ho_neighbor_config_6() );
11421 execute( TC_ho_neighbor_config_7() );
11422
Neels Hofmeyrcdc2d762018-03-12 01:48:11 +010011423 execute( TC_bssap_rlsd_does_not_cause_bssmap_reset() );
Neels Hofmeyr4ff93282018-03-12 04:25:35 +010011424 execute( TC_bssmap_clear_does_not_cause_bssmap_reset() );
Neels Hofmeyrfd445c32018-03-09 15:39:31 +010011425 execute( TC_ms_rel_ind_does_not_cause_bssmap_reset() );
Harald Welte94e0c342018-04-07 11:33:23 +020011426
11427 execute( TC_dyn_pdch_ipa_act_deact() );
11428 execute( TC_dyn_pdch_ipa_act_nack() );
11429 execute( TC_dyn_pdch_osmo_act_deact() );
11430 execute( TC_dyn_pdch_osmo_act_nack() );
Pau Espin Pedrol37a4c152021-11-16 19:02:23 +010011431 execute( TC_dyn_ts_sdcch8_act_deact() );
11432 execute( TC_dyn_ts_sdcch8_all_subslots_used() );
11433 execute( TC_dyn_ts_sdcch8_tch_call_act_deact() );
11434 execute( TC_dyn_ts_sdcch8_act_nack() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011435
Stefan Sperling0796a822018-10-05 13:01:39 +020011436 execute( TC_chopped_ipa_ping() );
Stefan Sperlingaa1e60f2018-10-15 16:34:07 +020011437 execute( TC_chopped_ipa_payload() );
Stefan Sperling0796a822018-10-05 13:01:39 +020011438
Pau Espin Pedrol8f773632019-11-05 11:46:53 +010011439 /* Power control related */
11440 execute( TC_assignment_verify_ms_power_params_ie() );
Vadim Yanitskiy4b233042021-06-30 00:58:43 +020011441 execute( TC_c0_power_red_mode() );
Neels Hofmeyr4f118412020-06-04 15:25:10 +020011442
11443 /* MSC pooling */
11444 /* FIXME: in SCCPlite, indicating how many MSCs should be connected does currently not work. Since
11445 * RESET->RESET-ACK is unconditionally negotiated for all configured MSCs, they always all appear as connected
11446 * to osmo-bsc. The MSC pooling tests however require disconnecting selected MSCs, and hence don't work out as
11447 * intended on SCCPlite. So for now, run these only for SCCP/M3UA. */
11448 if (mp_bssap_cfg[0].transport == BSSAP_TRANSPORT_AoIP) {
11449 execute( TC_mscpool_L3Compl_on_1_msc() );
11450 execute( TC_mscpool_L3Complete_by_imsi_round_robin() );
11451 execute( TC_mscpool_LU_by_tmsi_null_nri_0_round_robin() );
11452 execute( TC_mscpool_LU_by_tmsi_null_nri_1_round_robin() );
11453 execute( TC_mscpool_L3Complete_by_tmsi_unassigned_nri_round_robin() );
11454 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_msc_not_connected_round_robin() );
11455 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_1() );
11456 execute( TC_mscpool_L3Complete_by_tmsi_valid_nri_2() );
11457 execute( TC_mscpool_LU_by_tmsi_from_other_PLMN() );
11458 execute( TC_mscpool_paging_and_response_imsi() );
11459 execute( TC_mscpool_paging_and_response_tmsi() );
11460 execute( TC_mscpool_no_allow_attach_round_robin() );
11461 execute( TC_mscpool_no_allow_attach_valid_nri() );
11462 }
11463
Harald Welte99f3ca02018-06-14 13:40:29 +020011464 execute( TC_early_conn_fail() );
11465 execute( TC_late_conn_fail() );
Oliver Smithaf03bef2021-08-24 15:34:51 +020011466 execute( TC_stats_conn_fail() );
Harald Welte99f3ca02018-06-14 13:40:29 +020011467
Philipp Maier783681c2020-07-16 16:47:06 +020011468 /* Emergency call handling (deny / allow) */
11469 execute( TC_assignment_emerg_setup_allow() );
11470 execute( TC_assignment_emerg_setup_deny_msc() );
11471 execute( TC_assignment_emerg_setup_deny_bts() );
Philipp Maier82812002020-08-13 18:48:27 +020011472 execute( TC_emerg_premption() );
11473
Vadim Yanitskiy16bbde92020-08-28 05:30:45 +070011474 /* Frequency hopping parameters handling */
11475 execute( TC_fh_params_chan_activ() );
11476 execute( TC_fh_params_imm_ass() );
Vadim Yanitskiyaeb54a22020-09-01 06:25:25 +070011477 execute( TC_fh_params_assignment_cmd() );
Vadim Yanitskiy8f5430d2020-09-02 18:51:38 +070011478 execute( TC_fh_params_handover_cmd() );
Vadim Yanitskiyca974032020-09-01 07:20:39 +070011479 execute( TC_fh_params_si4_cbch() );
Neels Hofmeyr2b910dc2020-10-01 06:36:04 +020011480
11481 if (mp_enable_lcs_tests) {
11482 execute( TC_lcs_loc_req_for_active_ms() );
11483 execute( TC_lcs_loc_req_for_active_ms_ta_req() );
11484 execute( TC_lcs_loc_req_for_idle_ms() );
11485 execute( TC_lcs_loc_req_no_subscriber() );
11486 execute( TC_lcs_loc_req_for_active_ms_le_timeout() );
11487 execute( TC_lcs_loc_req_for_active_ms_le_timeout2() );
11488 execute( TC_lcs_loc_req_for_idle_ms_no_pag_resp() );
11489 execute( TC_cm_service_during_lcs_loc_req() );
11490 execute( TC_ho_during_lcs_loc_req() );
11491 }
Neels Hofmeyrbf037052020-10-28 22:52:02 +000011492
11493 execute( TC_no_msc() );
Neels Hofmeyr87857ec2021-04-25 16:17:47 +000011494
11495 execute( TC_refuse_chan_act_to_vamos() );
11496 execute( TC_refuse_mode_modif_to_vamos() );
Neels Hofmeyrd2d9f332021-04-28 22:23:36 +000011497
11498 execute( TC_reassignment_fr() );
Neels Hofmeyrfeda88e2021-07-19 13:51:29 +020011499
11500 execute( TC_cm_reestablishment() );
Neels Hofmeyrb07b2952021-08-07 04:23:14 +020011501
11502 execute( TC_imm_ass_post_chan_ack() );
11503 execute( TC_imm_ass_pre_chan_ack() );
Neels Hofmeyr23158742021-09-07 19:08:07 +020011504 execute( TC_imm_ass_pre_ts_ack() );
Neels Hofmeyr7a6d0602021-08-07 04:23:50 +020011505 execute( TC_imm_ass_pre_chan_ack_dyn_ts() );
Neels Hofmeyrc8b95c12021-08-07 04:24:02 +020011506 execute( TC_imm_ass_pre_ts_ack_dyn_ts() );
Neels Hofmeyr5d7d13f2021-09-07 14:44:36 +020011507
11508 execute( TC_ctrl_trx_rf_locked() );
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011509
Neels Hofmeyrbd94fe72021-10-26 22:04:53 +020011510 execute( TC_ratectr_all_available_allocated() );
11511 execute( TC_ratectr_all_available_allocated_dyn() );
11512
Neels Hofmeyrb7581872021-11-07 14:02:49 +010011513 execute( TC_cm_serv_rej() );
11514
Neels Hofmeyr92cfa1c2021-09-28 18:29:44 +020011515 execute( TC_lost_sdcch_during_assignment() );
Neels Hofmeyrafe2ea52021-11-24 15:16:12 +010011516
11517 /* Run TC_ho_out_of_this_bsc last, because it may trigger a segfault before osmo-bsc's patch
11518 * with change-id I5a3345ab0005a73597f5c27207480912a2f5aae6 */
11519 execute( TC_ho_out_of_this_bsc() );
Harald Welte28d943e2017-11-25 15:00:50 +010011520}
11521
11522}